• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package android.telephony.mbms;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.ServiceConnection;
23 import android.content.pm.*;
24 import android.content.pm.ServiceInfo;
25 import android.telephony.MbmsDownloadSession;
26 import android.telephony.MbmsStreamingSession;
27 import android.util.Log;
28 
29 import java.io.File;
30 import java.io.IOException;
31 import java.util.List;
32 
33 /**
34  * @hide
35  */
36 public class MbmsUtils {
37     private static final String LOG_TAG = "MbmsUtils";
38 
isContainedIn(File parent, File child)39     public static boolean isContainedIn(File parent, File child) {
40         try {
41             String parentPath = parent.getCanonicalPath();
42             String childPath = child.getCanonicalPath();
43             return childPath.startsWith(parentPath);
44         } catch (IOException e) {
45             throw new RuntimeException("Failed to resolve canonical paths: " + e);
46         }
47     }
48 
toComponentName(ComponentInfo ci)49     public static ComponentName toComponentName(ComponentInfo ci) {
50         return new ComponentName(ci.packageName, ci.name);
51     }
52 
getOverrideServiceName(Context context, String serviceAction)53     public static ComponentName getOverrideServiceName(Context context, String serviceAction) {
54         String metaDataKey = null;
55         switch (serviceAction) {
56             case MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_ACTION:
57                 metaDataKey = MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA;
58                 break;
59             case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION:
60                 metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA;
61                 break;
62         }
63         if (metaDataKey == null) {
64             return null;
65         }
66 
67         ApplicationInfo appInfo;
68         try {
69             appInfo = context.getPackageManager()
70                     .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
71         } catch (PackageManager.NameNotFoundException e) {
72             return null;
73         }
74         if (appInfo.metaData == null) {
75             return null;
76         }
77         String serviceComponent = appInfo.metaData.getString(metaDataKey);
78         if (serviceComponent == null) {
79             return null;
80         }
81         return ComponentName.unflattenFromString(serviceComponent);
82     }
83 
getMiddlewareServiceInfo(Context context, String serviceAction)84     public static ServiceInfo getMiddlewareServiceInfo(Context context, String serviceAction) {
85         // Query for the proper service
86         PackageManager packageManager = context.getPackageManager();
87         Intent queryIntent = new Intent();
88         queryIntent.setAction(serviceAction);
89 
90         ComponentName overrideService = getOverrideServiceName(context, serviceAction);
91         List<ResolveInfo> services;
92         if (overrideService == null) {
93             services = packageManager.queryIntentServices(queryIntent,
94                     PackageManager.MATCH_SYSTEM_ONLY);
95         } else {
96             queryIntent.setComponent(overrideService);
97             services = packageManager.queryIntentServices(queryIntent,
98                     PackageManager.MATCH_ALL);
99         }
100 
101         if (services == null || services.size() == 0) {
102             Log.w(LOG_TAG, "No MBMS services found, cannot get service info");
103             return null;
104         }
105 
106         if (services.size() > 1) {
107             Log.w(LOG_TAG, "More than one MBMS service found, cannot get unique service");
108             return null;
109         }
110         return services.get(0).serviceInfo;
111     }
112 
startBinding(Context context, String serviceAction, ServiceConnection serviceConnection)113     public static int startBinding(Context context, String serviceAction,
114             ServiceConnection serviceConnection) {
115         Intent bindIntent = new Intent();
116         ServiceInfo mbmsServiceInfo =
117                 MbmsUtils.getMiddlewareServiceInfo(context, serviceAction);
118 
119         if (mbmsServiceInfo == null) {
120             return MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE;
121         }
122 
123         bindIntent.setComponent(MbmsUtils.toComponentName(mbmsServiceInfo));
124 
125         context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
126         return MbmsErrors.SUCCESS;
127     }
128 
129     /**
130      * Returns a File linked to the directory used to store temp files for this file service
131      */
getEmbmsTempFileDirForService(Context context, String serviceId)132     public static File getEmbmsTempFileDirForService(Context context, String serviceId) {
133         // Replace all non-alphanumerics/underscores with an underscore. Some filesystems don't
134         // like special characters.
135         String sanitizedServiceId = serviceId.replaceAll("[^a-zA-Z0-9_]", "_");
136 
137         File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context);
138 
139         return new File(embmsTempFileDir, sanitizedServiceId);
140     }
141 }
142