Loading telephony/java/android/telephony/MbmsDownloadManager.java +70 −51 Original line number Diff line number Diff line Loading @@ -194,27 +194,23 @@ public class MbmsDownloadManager { private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null); private final IMbmsDownloadManagerCallback mCallback; private final String mDownloadAppName; private MbmsDownloadManager(Context context, IMbmsDownloadManagerCallback callback, String downloadAppName, int subId) { private MbmsDownloadManager(Context context, IMbmsDownloadManagerCallback callback, int subId) { mContext = context; mCallback = callback; mDownloadAppName = downloadAppName; mSubscriptionId = subId; } /** * Create a new MbmsDownloadManager using the system default data subscription ID. * See {@link #create(Context, IMbmsDownloadManagerCallback, String, int)} * See {@link #create(Context, IMbmsDownloadManagerCallback, int)} * * @hide */ public static MbmsDownloadManager create(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName) IMbmsDownloadManagerCallback listener) throws MbmsException { return create(context, listener, downloadAppName, SubscriptionManager.getDefaultSubscriptionId()); return create(context, listener, SubscriptionManager.getDefaultSubscriptionId()); } /** Loading @@ -229,15 +225,13 @@ public class MbmsDownloadManager { * * @param context The instance of {@link Context} to use * @param listener A callback to get asynchronous error messages and file service updates. * @param downloadAppName The app name, as negotiated with the eMBMS provider * @param subscriptionId The data subscription ID to use * @hide */ public static MbmsDownloadManager create(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName, int subscriptionId) IMbmsDownloadManagerCallback listener, int subscriptionId) throws MbmsException { MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName, subscriptionId); MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, subscriptionId); mdm.bindAndInitialize(); return mdm; } Loading @@ -250,8 +244,7 @@ public class MbmsDownloadManager { IMbmsDownloadService downloadService = IMbmsDownloadService.Stub.asInterface(service); try { downloadService.initialize( mDownloadAppName, mSubscriptionId, mCallback); downloadService.initialize(mSubscriptionId, mCallback); } catch (RemoteException e) { Log.e(LOG_TAG, "Service died before initialization"); return; Loading Loading @@ -293,8 +286,7 @@ public class MbmsDownloadManager { throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND); } try { int returnCode = downloadService.getFileServices( mDownloadAppName, mSubscriptionId, classList); int returnCode = downloadService.getFileServices(mSubscriptionId, classList); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } Loading Loading @@ -345,8 +337,7 @@ public class MbmsDownloadManager { } try { int result = downloadService.setTempFileRootDirectory( mDownloadAppName, mSubscriptionId, filePath); int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath); if (result != MbmsException.SUCCESS) { throw new MbmsException(result); } Loading Loading @@ -396,7 +387,6 @@ public class MbmsDownloadManager { tempRootDirectory.mkdirs(); setTempFileRootDirectory(tempRootDirectory); } request.setAppName(mDownloadAppName); checkValidDownloadDestination(request); writeDownloadRequestToken(request); Loading @@ -404,6 +394,7 @@ public class MbmsDownloadManager { downloadService.download(request, callback); } catch (RemoteException e) { mService.set(null); throw new MbmsException(MbmsException.ERROR_SERVICE_LOST); } } Loading @@ -422,18 +413,31 @@ public class MbmsDownloadManager { } /** * Attempts to cancel the specified DownloadRequest. * Attempts to cancel the specified {@link DownloadRequest}. * * May throw a RemoteException. * If the middleware is not aware of the specified download request, an MbmsException will be * thrown with error code {@link MbmsException#ERROR_UNKNOWN_DOWNLOAD_REQUEST}. * * Synchronous responses may include * <li>SUCCESS</li> * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li> * <li>ERROR_MSDC_UNKNOWN_REQUEST</li> * If this method returns without throwing an exception, you may assume that cancellation * was successful. * @param downloadRequest The download request that you wish to cancel. */ public int cancelDownload(DownloadRequest downloadRequest) { // TODO: don't forget to delete the token return 0; public void cancelDownload(DownloadRequest downloadRequest) throws MbmsException { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND); } try { int result = downloadService.cancelDownload(downloadRequest); if (result != MbmsException.SUCCESS) { throw new MbmsException(result); } } catch (RemoteException e) { mService.set(null); throw new MbmsException(MbmsException.ERROR_SERVICE_LOST); } deleteDownloadRequestToken(downloadRequest); } /** Loading Loading @@ -472,6 +476,21 @@ public class MbmsDownloadManager { return 0; } public void dispose() { try { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { Log.i(LOG_TAG, "Service already dead"); return; } downloadService.dispose(mSubscriptionId); mService.set(null); } catch (RemoteException e) { // Ignore Log.i(LOG_TAG, "Remote exception while disposing of service"); } } /** * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that * the various intents from the middleware should be targeted towards. Loading Loading @@ -502,32 +521,13 @@ public class MbmsDownloadManager { return null; } public void dispose() { try { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { Log.i(LOG_TAG, "Service already dead"); return; } downloadService.dispose(mDownloadAppName, mSubscriptionId); mService.set(null); } catch (RemoteException e) { // Ignore Log.i(LOG_TAG, "Remote exception while disposing of service"); } } private void writeDownloadRequestToken(DownloadRequest request) { File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext, request.getFileServiceInfo()); if (!tempFileLocation.exists()) { tempFileLocation.mkdirs(); File token = getDownloadRequestTokenPath(request); if (!token.getParentFile().exists()) { token.getParentFile().mkdirs(); } String downloadTokenFileName = request.getHash() + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX; File token = new File(tempFileLocation, downloadTokenFileName); if (token.exists()) { Log.w(LOG_TAG, "Download token " + downloadTokenFileName + " already exists"); Log.w(LOG_TAG, "Download token " + token.getName() + " already exists"); return; } try { Loading @@ -541,6 +541,25 @@ public class MbmsDownloadManager { } } private void deleteDownloadRequestToken(DownloadRequest request) { File token = getDownloadRequestTokenPath(request); if (!token.isFile()) { Log.w(LOG_TAG, "Attempting to delete non-existent download token at " + token); return; } if (!token.delete()) { Log.w(LOG_TAG, "Couldn't delete download token at " + token); } } private File getDownloadRequestTokenPath(DownloadRequest request) { File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext, request.getFileServiceInfo()); String downloadTokenFileName = request.getHash() + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX; return new File(tempFileLocation, downloadTokenFileName); } /** * Verifies the following: * If a request is multi-part, Loading telephony/java/android/telephony/MbmsStreamingManager.java +12 −19 Original line number Diff line number Diff line Loading @@ -43,16 +43,14 @@ public class MbmsStreamingManager { private AtomicReference<IMbmsStreamingService> mService = new AtomicReference<>(null); private MbmsStreamingManagerCallback mCallbackToApp; private final String mAppName; private final Context mContext; private int mSubscriptionId = INVALID_SUBSCRIPTION_ID; /** @hide */ private MbmsStreamingManager(Context context, MbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId) { int subscriptionId) { mContext = context; mAppName = streamingAppName; mCallbackToApp = listener; mSubscriptionId = subscriptionId; } Loading @@ -67,27 +65,24 @@ public class MbmsStreamingManager { * @param context The {@link Context} to use. * @param listener A callback object on which you wish to receive results of asynchronous * operations. * @param streamingAppName The name of the streaming app, as specified by the carrier. * @param subscriptionId The subscription ID to use. */ public static MbmsStreamingManager create(Context context, MbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId) MbmsStreamingManagerCallback listener, int subscriptionId) throws MbmsException { MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, streamingAppName, subscriptionId); MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, subscriptionId); manager.bindAndInitialize(); return manager; } /** * Create a new MbmsStreamingManager using the system default data subscription ID. * See {@link #create(Context, MbmsStreamingManagerCallback, String, int)}. * See {@link #create(Context, MbmsStreamingManagerCallback, int)}. */ public static MbmsStreamingManager create(Context context, MbmsStreamingManagerCallback listener, String streamingAppName) MbmsStreamingManagerCallback listener) throws MbmsException { return create(context, listener, streamingAppName, SubscriptionManager.getDefaultSubscriptionId()); return create(context, listener, SubscriptionManager.getDefaultSubscriptionId()); } /** Loading @@ -101,7 +96,7 @@ public class MbmsStreamingManager { return; } try { streamingService.dispose(mAppName, mSubscriptionId); streamingService.dispose(mSubscriptionId); } catch (RemoteException e) { // Ignore for now } Loading Loading @@ -132,8 +127,7 @@ public class MbmsStreamingManager { throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND); } try { int returnCode = streamingService.getStreamingServices( mAppName, mSubscriptionId, classList); int returnCode = streamingService.getStreamingServices(mSubscriptionId, classList); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } Loading Loading @@ -168,7 +162,7 @@ public class MbmsStreamingManager { try { int returnCode = streamingService.startStreaming( mAppName, mSubscriptionId, serviceInfo.getServiceId(), listener); mSubscriptionId, serviceInfo.getServiceId(), listener); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } Loading @@ -178,8 +172,7 @@ public class MbmsStreamingManager { throw new MbmsException(MbmsException.ERROR_SERVICE_LOST); } return new StreamingService( mAppName, mSubscriptionId, streamingService, serviceInfo, listener); return new StreamingService(mSubscriptionId, streamingService, serviceInfo, listener); } private void bindAndInitialize() throws MbmsException { Loading @@ -190,12 +183,12 @@ public class MbmsStreamingManager { IMbmsStreamingService streamingService = IMbmsStreamingService.Stub.asInterface(service); try { streamingService.initialize(mCallbackToApp, mAppName, mSubscriptionId); streamingService.initialize(mCallbackToApp, mSubscriptionId); } catch (RemoteException e) { Log.e(LOG_TAG, "Service died before initialization"); return; } mService.set(null); mService.set(streamingService); } @Override Loading telephony/java/android/telephony/mbms/DownloadRequest.java +28 −20 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.Base64; import java.lang.IllegalStateException; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Objects; /** * A Parcelable class describing a pending Cell-Broadcast download request Loading Loading @@ -83,7 +83,7 @@ public class DownloadRequest implements Parcelable { public DownloadRequest build() { return new DownloadRequest(id, serviceInfo, source, dest, subscriptionId, appIntent, null, version); subscriptionId, appIntent, version); } } Loading @@ -94,18 +94,16 @@ public class DownloadRequest implements Parcelable { private final int subscriptionId; private final String serializedResultIntentForApp; private final int version; private String appName; // not the Android app Name, the embms app name private DownloadRequest(int id, FileServiceInfo serviceInfo, Uri source, Uri dest, int sub, String appIntent, String name, int version) { int sub, String appIntent, int version) { downloadId = id; fileServiceInfo = serviceInfo; sourceUri = source; destinationUri = dest; subscriptionId = sub; serializedResultIntentForApp = appIntent; appName = name; this.version = version; } Loading @@ -120,7 +118,6 @@ public class DownloadRequest implements Parcelable { destinationUri = dr.destinationUri; subscriptionId = dr.subscriptionId; serializedResultIntentForApp = dr.serializedResultIntentForApp; appName = dr.appName; version = dr.version; } Loading @@ -131,7 +128,6 @@ public class DownloadRequest implements Parcelable { destinationUri = in.readParcelable(getClass().getClassLoader()); subscriptionId = in.readInt(); serializedResultIntentForApp = in.readString(); appName = in.readString(); version = in.readInt(); } Loading @@ -146,7 +142,6 @@ public class DownloadRequest implements Parcelable { out.writeParcelable(destinationUri, flags); out.writeInt(subscriptionId); out.writeString(serializedResultIntentForApp); out.writeString(appName); out.writeInt(version); } Loading Loading @@ -178,18 +173,6 @@ public class DownloadRequest implements Parcelable { } } /** @hide */ public synchronized void setAppName(String newAppName) { if (appName != null) { throw new IllegalStateException("Attempting to reset appName"); } appName = newAppName; } public String getAppName() { return appName; } public int getVersion() { return version; } Loading Loading @@ -234,4 +217,29 @@ public class DownloadRequest implements Parcelable { // Add updates for future versions here return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) { return false; } if (!(o instanceof DownloadRequest)) { return false; } DownloadRequest request = (DownloadRequest) o; return downloadId == request.downloadId && subscriptionId == request.subscriptionId && version == request.version && Objects.equals(fileServiceInfo, request.fileServiceInfo) && Objects.equals(sourceUri, request.sourceUri) && Objects.equals(destinationUri, request.destinationUri) && Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp); } @Override public int hashCode() { return Objects.hash(downloadId, fileServiceInfo, sourceUri, destinationUri, subscriptionId, serializedResultIntentForApp, version); } } telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +42 −7 Original line number Diff line number Diff line Loading @@ -29,16 +29,16 @@ import android.util.Log; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.function.Predicate; /** * @hide Loading Loading @@ -431,17 +431,16 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } toFile.getParentFile().mkdirs(); // TODO: This will not work if the two files are on different filesystems. Add manual // copy later. if (fromFile.renameTo(toFile)) { return Uri.fromFile(toFile); } else if (manualMove(fromFile, toFile)) { return Uri.fromFile(toFile); } return null; } private static boolean verifyTempFilePath(Context context, FileServiceInfo serviceInfo, Uri filePath) { // TODO: modify pursuant to final decision on temp file path scheme if (!ContentResolver.SCHEME_FILE.equals(filePath.getScheme())) { Log.w(LOG_TAG, "Uri " + filePath + " does not have a file scheme"); return false; Loading Loading @@ -493,4 +492,40 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } return mMiddlewarePackageNameCache; } private static boolean manualMove(File src, File dst) { InputStream in = null; OutputStream out = null; try { if (!dst.exists()) { dst.createNewFile(); } in = new FileInputStream(src); out = new FileOutputStream(dst); byte[] buffer = new byte[2048]; int len; do { len = in.read(buffer); out.write(buffer, 0, len); } while (len > 0); } catch (IOException e) { Log.w(LOG_TAG, "Manual file move failed due to exception " + e); if (dst.exists()) { dst.delete(); } return false; } finally { try { if (in != null) { in.close(); } if (out != null) { out.close(); } } catch (IOException e) { Log.w(LOG_TAG, "Error closing streams: " + e); } } return true; } } telephony/java/android/telephony/mbms/MbmsException.java +2 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ public class MbmsException extends Exception { public static final int ERROR_UNABLE_TO_READ_SIM = 16; public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 17; public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 18; public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 19; public static final int ERROR_UNABLE_TO_INITIALIZE = 20; private final int mErrorCode; Loading Loading
telephony/java/android/telephony/MbmsDownloadManager.java +70 −51 Original line number Diff line number Diff line Loading @@ -194,27 +194,23 @@ public class MbmsDownloadManager { private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null); private final IMbmsDownloadManagerCallback mCallback; private final String mDownloadAppName; private MbmsDownloadManager(Context context, IMbmsDownloadManagerCallback callback, String downloadAppName, int subId) { private MbmsDownloadManager(Context context, IMbmsDownloadManagerCallback callback, int subId) { mContext = context; mCallback = callback; mDownloadAppName = downloadAppName; mSubscriptionId = subId; } /** * Create a new MbmsDownloadManager using the system default data subscription ID. * See {@link #create(Context, IMbmsDownloadManagerCallback, String, int)} * See {@link #create(Context, IMbmsDownloadManagerCallback, int)} * * @hide */ public static MbmsDownloadManager create(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName) IMbmsDownloadManagerCallback listener) throws MbmsException { return create(context, listener, downloadAppName, SubscriptionManager.getDefaultSubscriptionId()); return create(context, listener, SubscriptionManager.getDefaultSubscriptionId()); } /** Loading @@ -229,15 +225,13 @@ public class MbmsDownloadManager { * * @param context The instance of {@link Context} to use * @param listener A callback to get asynchronous error messages and file service updates. * @param downloadAppName The app name, as negotiated with the eMBMS provider * @param subscriptionId The data subscription ID to use * @hide */ public static MbmsDownloadManager create(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName, int subscriptionId) IMbmsDownloadManagerCallback listener, int subscriptionId) throws MbmsException { MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName, subscriptionId); MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, subscriptionId); mdm.bindAndInitialize(); return mdm; } Loading @@ -250,8 +244,7 @@ public class MbmsDownloadManager { IMbmsDownloadService downloadService = IMbmsDownloadService.Stub.asInterface(service); try { downloadService.initialize( mDownloadAppName, mSubscriptionId, mCallback); downloadService.initialize(mSubscriptionId, mCallback); } catch (RemoteException e) { Log.e(LOG_TAG, "Service died before initialization"); return; Loading Loading @@ -293,8 +286,7 @@ public class MbmsDownloadManager { throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND); } try { int returnCode = downloadService.getFileServices( mDownloadAppName, mSubscriptionId, classList); int returnCode = downloadService.getFileServices(mSubscriptionId, classList); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } Loading Loading @@ -345,8 +337,7 @@ public class MbmsDownloadManager { } try { int result = downloadService.setTempFileRootDirectory( mDownloadAppName, mSubscriptionId, filePath); int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath); if (result != MbmsException.SUCCESS) { throw new MbmsException(result); } Loading Loading @@ -396,7 +387,6 @@ public class MbmsDownloadManager { tempRootDirectory.mkdirs(); setTempFileRootDirectory(tempRootDirectory); } request.setAppName(mDownloadAppName); checkValidDownloadDestination(request); writeDownloadRequestToken(request); Loading @@ -404,6 +394,7 @@ public class MbmsDownloadManager { downloadService.download(request, callback); } catch (RemoteException e) { mService.set(null); throw new MbmsException(MbmsException.ERROR_SERVICE_LOST); } } Loading @@ -422,18 +413,31 @@ public class MbmsDownloadManager { } /** * Attempts to cancel the specified DownloadRequest. * Attempts to cancel the specified {@link DownloadRequest}. * * May throw a RemoteException. * If the middleware is not aware of the specified download request, an MbmsException will be * thrown with error code {@link MbmsException#ERROR_UNKNOWN_DOWNLOAD_REQUEST}. * * Synchronous responses may include * <li>SUCCESS</li> * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li> * <li>ERROR_MSDC_UNKNOWN_REQUEST</li> * If this method returns without throwing an exception, you may assume that cancellation * was successful. * @param downloadRequest The download request that you wish to cancel. */ public int cancelDownload(DownloadRequest downloadRequest) { // TODO: don't forget to delete the token return 0; public void cancelDownload(DownloadRequest downloadRequest) throws MbmsException { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND); } try { int result = downloadService.cancelDownload(downloadRequest); if (result != MbmsException.SUCCESS) { throw new MbmsException(result); } } catch (RemoteException e) { mService.set(null); throw new MbmsException(MbmsException.ERROR_SERVICE_LOST); } deleteDownloadRequestToken(downloadRequest); } /** Loading Loading @@ -472,6 +476,21 @@ public class MbmsDownloadManager { return 0; } public void dispose() { try { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { Log.i(LOG_TAG, "Service already dead"); return; } downloadService.dispose(mSubscriptionId); mService.set(null); } catch (RemoteException e) { // Ignore Log.i(LOG_TAG, "Remote exception while disposing of service"); } } /** * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that * the various intents from the middleware should be targeted towards. Loading Loading @@ -502,32 +521,13 @@ public class MbmsDownloadManager { return null; } public void dispose() { try { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { Log.i(LOG_TAG, "Service already dead"); return; } downloadService.dispose(mDownloadAppName, mSubscriptionId); mService.set(null); } catch (RemoteException e) { // Ignore Log.i(LOG_TAG, "Remote exception while disposing of service"); } } private void writeDownloadRequestToken(DownloadRequest request) { File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext, request.getFileServiceInfo()); if (!tempFileLocation.exists()) { tempFileLocation.mkdirs(); File token = getDownloadRequestTokenPath(request); if (!token.getParentFile().exists()) { token.getParentFile().mkdirs(); } String downloadTokenFileName = request.getHash() + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX; File token = new File(tempFileLocation, downloadTokenFileName); if (token.exists()) { Log.w(LOG_TAG, "Download token " + downloadTokenFileName + " already exists"); Log.w(LOG_TAG, "Download token " + token.getName() + " already exists"); return; } try { Loading @@ -541,6 +541,25 @@ public class MbmsDownloadManager { } } private void deleteDownloadRequestToken(DownloadRequest request) { File token = getDownloadRequestTokenPath(request); if (!token.isFile()) { Log.w(LOG_TAG, "Attempting to delete non-existent download token at " + token); return; } if (!token.delete()) { Log.w(LOG_TAG, "Couldn't delete download token at " + token); } } private File getDownloadRequestTokenPath(DownloadRequest request) { File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext, request.getFileServiceInfo()); String downloadTokenFileName = request.getHash() + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX; return new File(tempFileLocation, downloadTokenFileName); } /** * Verifies the following: * If a request is multi-part, Loading
telephony/java/android/telephony/MbmsStreamingManager.java +12 −19 Original line number Diff line number Diff line Loading @@ -43,16 +43,14 @@ public class MbmsStreamingManager { private AtomicReference<IMbmsStreamingService> mService = new AtomicReference<>(null); private MbmsStreamingManagerCallback mCallbackToApp; private final String mAppName; private final Context mContext; private int mSubscriptionId = INVALID_SUBSCRIPTION_ID; /** @hide */ private MbmsStreamingManager(Context context, MbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId) { int subscriptionId) { mContext = context; mAppName = streamingAppName; mCallbackToApp = listener; mSubscriptionId = subscriptionId; } Loading @@ -67,27 +65,24 @@ public class MbmsStreamingManager { * @param context The {@link Context} to use. * @param listener A callback object on which you wish to receive results of asynchronous * operations. * @param streamingAppName The name of the streaming app, as specified by the carrier. * @param subscriptionId The subscription ID to use. */ public static MbmsStreamingManager create(Context context, MbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId) MbmsStreamingManagerCallback listener, int subscriptionId) throws MbmsException { MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, streamingAppName, subscriptionId); MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, subscriptionId); manager.bindAndInitialize(); return manager; } /** * Create a new MbmsStreamingManager using the system default data subscription ID. * See {@link #create(Context, MbmsStreamingManagerCallback, String, int)}. * See {@link #create(Context, MbmsStreamingManagerCallback, int)}. */ public static MbmsStreamingManager create(Context context, MbmsStreamingManagerCallback listener, String streamingAppName) MbmsStreamingManagerCallback listener) throws MbmsException { return create(context, listener, streamingAppName, SubscriptionManager.getDefaultSubscriptionId()); return create(context, listener, SubscriptionManager.getDefaultSubscriptionId()); } /** Loading @@ -101,7 +96,7 @@ public class MbmsStreamingManager { return; } try { streamingService.dispose(mAppName, mSubscriptionId); streamingService.dispose(mSubscriptionId); } catch (RemoteException e) { // Ignore for now } Loading Loading @@ -132,8 +127,7 @@ public class MbmsStreamingManager { throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND); } try { int returnCode = streamingService.getStreamingServices( mAppName, mSubscriptionId, classList); int returnCode = streamingService.getStreamingServices(mSubscriptionId, classList); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } Loading Loading @@ -168,7 +162,7 @@ public class MbmsStreamingManager { try { int returnCode = streamingService.startStreaming( mAppName, mSubscriptionId, serviceInfo.getServiceId(), listener); mSubscriptionId, serviceInfo.getServiceId(), listener); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } Loading @@ -178,8 +172,7 @@ public class MbmsStreamingManager { throw new MbmsException(MbmsException.ERROR_SERVICE_LOST); } return new StreamingService( mAppName, mSubscriptionId, streamingService, serviceInfo, listener); return new StreamingService(mSubscriptionId, streamingService, serviceInfo, listener); } private void bindAndInitialize() throws MbmsException { Loading @@ -190,12 +183,12 @@ public class MbmsStreamingManager { IMbmsStreamingService streamingService = IMbmsStreamingService.Stub.asInterface(service); try { streamingService.initialize(mCallbackToApp, mAppName, mSubscriptionId); streamingService.initialize(mCallbackToApp, mSubscriptionId); } catch (RemoteException e) { Log.e(LOG_TAG, "Service died before initialization"); return; } mService.set(null); mService.set(streamingService); } @Override Loading
telephony/java/android/telephony/mbms/DownloadRequest.java +28 −20 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.Base64; import java.lang.IllegalStateException; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Objects; /** * A Parcelable class describing a pending Cell-Broadcast download request Loading Loading @@ -83,7 +83,7 @@ public class DownloadRequest implements Parcelable { public DownloadRequest build() { return new DownloadRequest(id, serviceInfo, source, dest, subscriptionId, appIntent, null, version); subscriptionId, appIntent, version); } } Loading @@ -94,18 +94,16 @@ public class DownloadRequest implements Parcelable { private final int subscriptionId; private final String serializedResultIntentForApp; private final int version; private String appName; // not the Android app Name, the embms app name private DownloadRequest(int id, FileServiceInfo serviceInfo, Uri source, Uri dest, int sub, String appIntent, String name, int version) { int sub, String appIntent, int version) { downloadId = id; fileServiceInfo = serviceInfo; sourceUri = source; destinationUri = dest; subscriptionId = sub; serializedResultIntentForApp = appIntent; appName = name; this.version = version; } Loading @@ -120,7 +118,6 @@ public class DownloadRequest implements Parcelable { destinationUri = dr.destinationUri; subscriptionId = dr.subscriptionId; serializedResultIntentForApp = dr.serializedResultIntentForApp; appName = dr.appName; version = dr.version; } Loading @@ -131,7 +128,6 @@ public class DownloadRequest implements Parcelable { destinationUri = in.readParcelable(getClass().getClassLoader()); subscriptionId = in.readInt(); serializedResultIntentForApp = in.readString(); appName = in.readString(); version = in.readInt(); } Loading @@ -146,7 +142,6 @@ public class DownloadRequest implements Parcelable { out.writeParcelable(destinationUri, flags); out.writeInt(subscriptionId); out.writeString(serializedResultIntentForApp); out.writeString(appName); out.writeInt(version); } Loading Loading @@ -178,18 +173,6 @@ public class DownloadRequest implements Parcelable { } } /** @hide */ public synchronized void setAppName(String newAppName) { if (appName != null) { throw new IllegalStateException("Attempting to reset appName"); } appName = newAppName; } public String getAppName() { return appName; } public int getVersion() { return version; } Loading Loading @@ -234,4 +217,29 @@ public class DownloadRequest implements Parcelable { // Add updates for future versions here return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) { return false; } if (!(o instanceof DownloadRequest)) { return false; } DownloadRequest request = (DownloadRequest) o; return downloadId == request.downloadId && subscriptionId == request.subscriptionId && version == request.version && Objects.equals(fileServiceInfo, request.fileServiceInfo) && Objects.equals(sourceUri, request.sourceUri) && Objects.equals(destinationUri, request.destinationUri) && Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp); } @Override public int hashCode() { return Objects.hash(downloadId, fileServiceInfo, sourceUri, destinationUri, subscriptionId, serializedResultIntentForApp, version); } }
telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +42 −7 Original line number Diff line number Diff line Loading @@ -29,16 +29,16 @@ import android.util.Log; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.function.Predicate; /** * @hide Loading Loading @@ -431,17 +431,16 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } toFile.getParentFile().mkdirs(); // TODO: This will not work if the two files are on different filesystems. Add manual // copy later. if (fromFile.renameTo(toFile)) { return Uri.fromFile(toFile); } else if (manualMove(fromFile, toFile)) { return Uri.fromFile(toFile); } return null; } private static boolean verifyTempFilePath(Context context, FileServiceInfo serviceInfo, Uri filePath) { // TODO: modify pursuant to final decision on temp file path scheme if (!ContentResolver.SCHEME_FILE.equals(filePath.getScheme())) { Log.w(LOG_TAG, "Uri " + filePath + " does not have a file scheme"); return false; Loading Loading @@ -493,4 +492,40 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } return mMiddlewarePackageNameCache; } private static boolean manualMove(File src, File dst) { InputStream in = null; OutputStream out = null; try { if (!dst.exists()) { dst.createNewFile(); } in = new FileInputStream(src); out = new FileOutputStream(dst); byte[] buffer = new byte[2048]; int len; do { len = in.read(buffer); out.write(buffer, 0, len); } while (len > 0); } catch (IOException e) { Log.w(LOG_TAG, "Manual file move failed due to exception " + e); if (dst.exists()) { dst.delete(); } return false; } finally { try { if (in != null) { in.close(); } if (out != null) { out.close(); } } catch (IOException e) { Log.w(LOG_TAG, "Error closing streams: " + e); } } return true; } }
telephony/java/android/telephony/mbms/MbmsException.java +2 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ public class MbmsException extends Exception { public static final int ERROR_UNABLE_TO_READ_SIM = 16; public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 17; public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 18; public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 19; public static final int ERROR_UNABLE_TO_INITIALIZE = 20; private final int mErrorCode; Loading