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.MbmsGroupCallSession; 27 import android.telephony.MbmsStreamingSession; 28 import android.util.Log; 29 30 import java.io.File; 31 import java.io.IOException; 32 import java.util.List; 33 34 /** 35 * @hide 36 */ 37 public class MbmsUtils { 38 private static final String LOG_TAG = "MbmsUtils"; 39 isContainedIn(File parent, File child)40 public static boolean isContainedIn(File parent, File child) { 41 try { 42 String parentPath = parent.getCanonicalPath(); 43 String childPath = child.getCanonicalPath(); 44 return childPath.startsWith(parentPath); 45 } catch (IOException e) { 46 throw new RuntimeException("Failed to resolve canonical paths: " + e); 47 } 48 } 49 toComponentName(ComponentInfo ci)50 public static ComponentName toComponentName(ComponentInfo ci) { 51 return new ComponentName(ci.packageName, ci.name); 52 } 53 getOverrideServiceName(Context context, String serviceAction)54 public static ComponentName getOverrideServiceName(Context context, String serviceAction) { 55 String metaDataKey = null; 56 switch (serviceAction) { 57 case MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_ACTION: 58 metaDataKey = MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA; 59 break; 60 case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION: 61 metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA; 62 break; 63 case MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_ACTION: 64 metaDataKey = MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA; 65 break; 66 } 67 if (metaDataKey == null) { 68 return null; 69 } 70 71 ApplicationInfo appInfo; 72 try { 73 appInfo = context.getPackageManager() 74 .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); 75 } catch (PackageManager.NameNotFoundException e) { 76 return null; 77 } 78 if (appInfo.metaData == null) { 79 return null; 80 } 81 String serviceComponent = appInfo.metaData.getString(metaDataKey); 82 if (serviceComponent == null) { 83 return null; 84 } 85 return ComponentName.unflattenFromString(serviceComponent); 86 } 87 getMiddlewareServiceInfo(Context context, String serviceAction)88 public static ServiceInfo getMiddlewareServiceInfo(Context context, String serviceAction) { 89 // Query for the proper service 90 PackageManager packageManager = context.getPackageManager(); 91 Intent queryIntent = new Intent(); 92 queryIntent.setAction(serviceAction); 93 94 ComponentName overrideService = getOverrideServiceName(context, serviceAction); 95 List<ResolveInfo> services; 96 if (overrideService == null) { 97 services = packageManager.queryIntentServices(queryIntent, 98 PackageManager.MATCH_SYSTEM_ONLY); 99 } else { 100 queryIntent.setComponent(overrideService); 101 services = packageManager.queryIntentServices(queryIntent, 102 PackageManager.MATCH_ALL); 103 } 104 105 if (services == null || services.size() == 0) { 106 Log.w(LOG_TAG, "No MBMS services found, cannot get service info"); 107 return null; 108 } 109 110 if (services.size() > 1) { 111 Log.w(LOG_TAG, "More than one MBMS service found, cannot get unique service"); 112 return null; 113 } 114 return services.get(0).serviceInfo; 115 } 116 startBinding(Context context, String serviceAction, ServiceConnection serviceConnection)117 public static int startBinding(Context context, String serviceAction, 118 ServiceConnection serviceConnection) { 119 Intent bindIntent = new Intent(); 120 ServiceInfo mbmsServiceInfo = 121 MbmsUtils.getMiddlewareServiceInfo(context, serviceAction); 122 123 if (mbmsServiceInfo == null) { 124 return MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE; 125 } 126 127 bindIntent.setComponent(MbmsUtils.toComponentName(mbmsServiceInfo)); 128 129 context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE); 130 return MbmsErrors.SUCCESS; 131 } 132 133 /** 134 * Returns a File linked to the directory used to store temp files for this file service 135 */ getEmbmsTempFileDirForService(Context context, String serviceId)136 public static File getEmbmsTempFileDirForService(Context context, String serviceId) { 137 // Replace all non-alphanumerics/underscores with an underscore. Some filesystems don't 138 // like special characters. 139 String sanitizedServiceId = serviceId.replaceAll("[^a-zA-Z0-9_]", "_"); 140 141 File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context); 142 143 return new File(embmsTempFileDir, sanitizedServiceId); 144 } 145 } 146