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 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 49 public static ComponentName toComponentName(ComponentInfo ci) { 50 return new ComponentName(ci.packageName, ci.name); 51 } 52 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 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 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 */ 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