diff options
7 files changed, 277 insertions, 233 deletions
diff --git a/telephony/java/android/telephony/MbmsDownloadManager.java b/telephony/java/android/telephony/MbmsDownloadManager.java index be193c65ed12..1e8cf185d4e4 100644 --- a/telephony/java/android/telephony/MbmsDownloadManager.java +++ b/telephony/java/android/telephony/MbmsDownloadManager.java @@ -18,18 +18,19 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SdkConstant; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; -import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; +import android.telephony.mbms.DownloadProgressListener; import android.telephony.mbms.FileInfo; import android.telephony.mbms.DownloadRequest; -import android.telephony.mbms.IDownloadProgressListener; import android.telephony.mbms.MbmsDownloadManagerCallback; import android.telephony.mbms.MbmsDownloadReceiver; import android.telephony.mbms.MbmsException; @@ -52,147 +53,38 @@ import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; public class MbmsDownloadManager { private static final String LOG_TAG = MbmsDownloadManager.class.getSimpleName(); + /** @hide */ + // TODO: systemapi + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; - /** - * The MBMS middleware should send this when a download of single file has completed or - * failed. Mandatory extras are - * {@link #EXTRA_RESULT} - * {@link #EXTRA_FILE_INFO} - * {@link #EXTRA_REQUEST} - * {@link #EXTRA_TEMP_LIST} - * {@link #EXTRA_FINAL_URI} - * - * TODO: future systemapi - */ - public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = - "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL"; - - /** - * The MBMS middleware should send this when it wishes to request {@code content://} URIs to - * serve as temp files for downloads or when it wishes to resume paused downloads. Mandatory - * extras are - * {@link #EXTRA_REQUEST} - * - * Optional extras are - * {@link #EXTRA_FD_COUNT} (0 if not present) - * {@link #EXTRA_PAUSED_LIST} (empty if not present) - * - * TODO: future systemapi - */ - public static final String ACTION_FILE_DESCRIPTOR_REQUEST = - "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST"; - - /** - * The MBMS middleware should send this when it wishes to clean up temp files in the app's - * filesystem. Mandatory extras are: - * {@link #EXTRA_TEMP_FILES_IN_USE} - * - * TODO: future systemapi - */ - public static final String ACTION_CLEANUP = - "android.telephony.mbms.action.CLEANUP"; /** * Integer extra indicating the result code of the download. One of * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, or {@link #RESULT_CANCELLED}. - * TODO: Not systemapi. */ public static final String EXTRA_RESULT = "android.telephony.mbms.extra.RESULT"; /** * Extra containing the {@link android.telephony.mbms.FileInfo} for which the download result * is for. Must not be null. - * TODO: Not systemapi. */ public static final String EXTRA_FILE_INFO = "android.telephony.mbms.extra.FILE_INFO"; /** - * Extra containing the {@link DownloadRequest} for which the download result or file - * descriptor request is for. Must not be null. - * TODO: future systemapi (here and and all extras) except the three for the app intent - */ - public static final String EXTRA_REQUEST = "android.telephony.mbms.extra.REQUEST"; - - /** - * Extra containing a {@link List} of {@link Uri}s that were used as temp files for this - * completed file. These {@link Uri}s should have scheme {@code file://}, and the temp - * files will be deleted upon receipt of the intent. - * May be null. - */ - public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST"; - - /** - * Extra containing a single {@link Uri} indicating the path to the temp file in which the - * decoded downloaded file resides. Must not be null. - */ - public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI"; - - /** - * Extra containing an integer indicating the number of temp files requested. - */ - public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT"; - - /** - * Extra containing a list of {@link Uri}s that the middleware is requesting access to via - * {@link #ACTION_FILE_DESCRIPTOR_REQUEST} in order to resume downloading. These {@link Uri}s - * should have scheme {@code file://}. - */ - public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST"; - - /** - * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the - * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These are temp files that are meant - * to be used for new file downloads. - */ - public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST"; - - /** - * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the - * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These - * {@link android.telephony.mbms.UriPathPair}s contain {@code content://} URIs that provide - * access to previously paused downloads. - */ - public static final String EXTRA_PAUSED_URI_LIST = - "android.telephony.mbms.extra.PAUSED_URI_LIST"; - - /** - * Extra containing a string that points to the middleware's knowledge of where the temp file - * root for the app is. The path should be a canonical path as returned by - * {@link File#getCanonicalPath()} - */ - public static final String EXTRA_TEMP_FILE_ROOT = - "android.telephony.mbms.extra.TEMP_FILE_ROOT"; - - /** - * Extra containing a list of {@link Uri}s indicating temp files which the middleware is - * still using. - */ - public static final String EXTRA_TEMP_FILES_IN_USE = - "android.telephony.mbms.extra.TEMP_FILES_IN_USE"; - - /** - * Extra containing an instance of {@link android.telephony.mbms.ServiceInfo}, used by - * file-descriptor requests and cleanup requests to specify which service they want to - * request temp files or clean up temp files for, respectively. - */ - public static final String EXTRA_SERVICE_INFO = - "android.telephony.mbms.extra.SERVICE_INFO"; - - /** * Extra containing a single {@link Uri} indicating the location of the successfully * downloaded file. Set on the intent provided via * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}. * Will always be set to a non-null value if {@link #EXTRA_RESULT} is set to * {@link #RESULT_SUCCESSFUL}. - * TODO: Not systemapi. */ public static final String EXTRA_COMPLETED_FILE_URI = "android.telephony.mbms.extra.COMPLETED_FILE_URI"; public static final int RESULT_SUCCESSFUL = 1; - public static final int RESULT_CANCELLED = 2; - public static final int RESULT_EXPIRED = 3; + public static final int RESULT_CANCELLED = 2; + public static final int RESULT_EXPIRED = 3; + public static final int RESULT_IO_ERROR = 4; // TODO - more results! /** @hide */ @@ -375,14 +267,15 @@ public class MbmsDownloadManager { * local instance of {@link android.content.SharedPreferences} and by the middleware. * * If this method is not called at least once before calling - * {@link #download(DownloadRequest, IDownloadProgressListener)}, the framework + * {@link #download(DownloadRequest, DownloadProgressListener)}, the framework * will default to a directory formed by the concatenation of the app's files directory and * {@link android.telephony.mbms.MbmsTempFileProvider#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY}. * * Before calling this method, the app must cancel all of its pending * {@link DownloadRequest}s via {@link #cancelDownload(DownloadRequest)}. If this is not done, * an {@link MbmsException} will be thrown with code - * {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} + * {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} unless the + * provided directory is the same as what has been previously configured. * * The {@link File} supplied as a root temp file directory must already exist. If not, an * {@link IllegalArgumentException} will be thrown. @@ -423,6 +316,26 @@ public class MbmsDownloadManager { } /** + * Retrieves the currently configured temp file root directory. Returns the file that was + * configured via {@link #setTempFileRootDirectory(File)} or the default directory + * {@link #download(DownloadRequest, DownloadProgressListener)} was called without ever setting + * the temp file root. If neither method has been called since the last time the app's shared + * preferences were reset, returns null. + * + * @return A {@link File} pointing to the configured temp file directory, or null if not yet + * configured. + */ + public @Nullable File getTempFileRootDirectory() { + SharedPreferences prefs = mContext.getSharedPreferences( + MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_FILE_NAME, 0); + String path = prefs.getString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, null); + if (path != null) { + return new File(path); + } + return null; + } + + /** * Requests a download of a file that is available via multicast. * * downloadListener is an optional callback object which can be used to get progress reports @@ -443,7 +356,7 @@ public class MbmsDownloadManager { * @param progressListener Optional listener that will be provided progress updates * if the app is running. */ - public void download(DownloadRequest request, IDownloadProgressListener progressListener) + public void download(DownloadRequest request, DownloadProgressListener progressListener) throws MbmsException { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { @@ -473,7 +386,7 @@ public class MbmsDownloadManager { /** * Returns a list of pending {@link DownloadRequest}s that originated from this application. * A pending request is one that was issued via - * {@link #download(DownloadRequest, IDownloadProgressListener)} but not cancelled through + * {@link #download(DownloadRequest, DownloadProgressListener)} but not cancelled through * {@link #cancelDownload(DownloadRequest)}. * @return A list, possibly empty, of {@link DownloadRequest}s */ @@ -598,36 +511,6 @@ public class MbmsDownloadManager { } } - /** - * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that - * the various intents from the middleware should be targeted towards. - * @param uid The uid of the frontend app. - * @return The component name of the receiver that the middleware should send its intents to, - * or null if the app didn't declare it in the manifest. - * - * @hide - * future systemapi - */ - public static ComponentName getAppReceiverFromUid(Context context, int uid) { - String[] packageNames = context.getPackageManager().getPackagesForUid(uid); - if (packageNames == null) { - return null; - } - - for (String packageName : packageNames) { - ComponentName candidate = new ComponentName(packageName, - MbmsDownloadReceiver.class.getCanonicalName()); - Intent queryIntent = new Intent(); - queryIntent.setComponent(candidate); - List<ResolveInfo> receivers = - context.getPackageManager().queryBroadcastReceivers(queryIntent, 0); - if (receivers != null && receivers.size() > 0) { - return candidate; - } - } - return null; - } - private void writeDownloadRequestToken(DownloadRequest request) { File token = getDownloadRequestTokenPath(request); if (!token.getParentFile().exists()) { diff --git a/telephony/java/android/telephony/mbms/DownloadProgressListener.java b/telephony/java/android/telephony/mbms/DownloadProgressListener.java index d6bd5dca8781..d91e9ad24a9a 100644 --- a/telephony/java/android/telephony/mbms/DownloadProgressListener.java +++ b/telephony/java/android/telephony/mbms/DownloadProgressListener.java @@ -16,6 +16,8 @@ package android.telephony.mbms; +import android.os.RemoteException; + /** * A optional listener class used by download clients to track progress. * @hide @@ -38,8 +40,9 @@ public class DownloadProgressListener extends IDownloadProgressListener.Stub { * @param currentDecodedSize is the number of bytes that have been decoded. * @param fullDecodedSize is the total number of bytes that make up the final decoded content. */ + @Override public void progress(DownloadRequest request, FileInfo fileInfo, int currentDownloadSize, int fullDownloadSize, - int currentDecodedSize, int fullDecodedSize) { + int currentDecodedSize, int fullDecodedSize) throws RemoteException { } } diff --git a/telephony/java/android/telephony/mbms/FileInfo.java b/telephony/java/android/telephony/mbms/FileInfo.java index b8e1c49f6b4a..f97131dda427 100644 --- a/telephony/java/android/telephony/mbms/FileInfo.java +++ b/telephony/java/android/telephony/mbms/FileInfo.java @@ -38,16 +38,6 @@ public class FileInfo implements Parcelable { */ private final String mimeType; - /** - * The size of the file in bytes. - */ - private final long size; - - /** - * The MD5 hash of the file. - */ - private final byte md5Hash[]; - public static final Parcelable.Creator<FileInfo> CREATOR = new Parcelable.Creator<FileInfo>() { @Override @@ -65,29 +55,20 @@ public class FileInfo implements Parcelable { * @hide * TODO: systemapi */ - public FileInfo(Uri uri, String mimeType, long size, byte[] md5Hash) { + public FileInfo(Uri uri, String mimeType) { this.uri = uri; this.mimeType = mimeType; - this.size = size; - this.md5Hash = md5Hash; } private FileInfo(Parcel in) { uri = in.readParcelable(null); mimeType = in.readString(); - size = in.readLong(); - int arraySize = in.readInt(); - md5Hash = new byte[arraySize]; - in.readByteArray(md5Hash); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(uri, flags); dest.writeString(mimeType); - dest.writeLong(size); - dest.writeInt(md5Hash.length); - dest.writeByteArray(md5Hash); } @Override @@ -102,12 +83,4 @@ public class FileInfo implements Parcelable { public String getMimeType() { return mimeType; } - - public long getSize() { - return size; - } - - public byte[] getMd5Hash() { - return md5Hash; - } } diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java index 339ff3985bff..ba7d120a3b7c 100644 --- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java @@ -25,6 +25,7 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.telephony.MbmsDownloadManager; +import android.telephony.mbms.vendor.VendorIntents; import android.util.Log; import java.io.File; @@ -56,9 +57,9 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { /** * Indicates that the intent sent had an invalid action. This will be the result if * {@link Intent#getAction()} returns anything other than - * {@link MbmsDownloadManager#ACTION_DOWNLOAD_RESULT_INTERNAL}, - * {@link MbmsDownloadManager#ACTION_FILE_DESCRIPTOR_REQUEST}, or - * {@link MbmsDownloadManager#ACTION_CLEANUP}. + * {@link VendorIntents#ACTION_DOWNLOAD_RESULT_INTERNAL}, + * {@link VendorIntents#ACTION_FILE_DESCRIPTOR_REQUEST}, or + * {@link VendorIntents#ACTION_CLEANUP}. * This is a fatal result code and no result extras should be expected. */ public static final int RESULT_INVALID_ACTION = 1; @@ -70,7 +71,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { public static final int RESULT_MALFORMED_INTENT = 2; /** - * Indicates that the supplied value for {@link MbmsDownloadManager#EXTRA_TEMP_FILE_ROOT} + * Indicates that the supplied value for {@link VendorIntents#EXTRA_TEMP_FILE_ROOT} * does not match what the app has stored. * This is a fatal result code and no result extras should be expected. */ @@ -104,18 +105,18 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { setResultCode(RESULT_MALFORMED_INTENT); return; } - if (!Objects.equals(intent.getStringExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT), + if (!Objects.equals(intent.getStringExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT), MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath())) { setResultCode(RESULT_BAD_TEMP_FILE_ROOT); return; } - if (MbmsDownloadManager.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { + if (VendorIntents.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { moveDownloadedFile(context, intent); cleanupPostMove(context, intent); - } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { + } else if (VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { generateTempFiles(context, intent); - } else if (MbmsDownloadManager.ACTION_CLEANUP.equals(intent.getAction())) { + } else if (VendorIntents.ACTION_CLEANUP.equals(intent.getAction())) { cleanupTempFiles(context, intent); } else { setResultCode(RESULT_INVALID_ACTION); @@ -123,16 +124,16 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } private boolean verifyIntentContents(Context context, Intent intent) { - if (MbmsDownloadManager.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { + if (VendorIntents.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { if (!intent.hasExtra(MbmsDownloadManager.EXTRA_RESULT)) { Log.w(LOG_TAG, "Download result did not include a result code. Ignoring."); return false; } - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_REQUEST)) { + if (!intent.hasExtra(VendorIntents.EXTRA_REQUEST)) { Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring."); return false; } - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT)) { + if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT)) { Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring."); return false; } @@ -141,12 +142,12 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { "Ignoring."); return false; } - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_FINAL_URI)) { + if (!intent.hasExtra(VendorIntents.EXTRA_FINAL_URI)) { Log.w(LOG_TAG, "Download result did not include the path to the final " + "temp file. Ignoring."); return false; } - DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); + DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST); String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX; File expectedTokenFile = new File( MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()), @@ -156,27 +157,27 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { "Expected " + expectedTokenFile); return false; } - } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO)) { + } else if (VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { + if (!intent.hasExtra(VendorIntents.EXTRA_SERVICE_INFO)) { Log.w(LOG_TAG, "Temp file request did not include the associated service info." + " Ignoring."); return false; } - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT)) { + if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT)) { Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring."); return false; } - } else if (MbmsDownloadManager.ACTION_CLEANUP.equals(intent.getAction())) { - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO)) { + } else if (VendorIntents.ACTION_CLEANUP.equals(intent.getAction())) { + if (!intent.hasExtra(VendorIntents.EXTRA_SERVICE_INFO)) { Log.w(LOG_TAG, "Cleanup request did not include the associated service info." + " Ignoring."); return false; } - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT)) { + if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT)) { Log.w(LOG_TAG, "Cleanup request did not include the temp file root. Ignoring."); return false; } - if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILES_IN_USE)) { + if (!intent.hasExtra(VendorIntents.EXTRA_TEMP_FILES_IN_USE)) { Log.w(LOG_TAG, "Cleanup request did not include the list of temp files in use. " + "Ignoring."); return false; @@ -186,7 +187,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } private void moveDownloadedFile(Context context, Intent intent) { - DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); + DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST); Intent intentForApp = request.getIntentForApp(); int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT, @@ -200,7 +201,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } Uri destinationUri = request.getDestinationUri(); - Uri finalTempFile = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_FINAL_URI); + Uri finalTempFile = intent.getParcelableExtra(VendorIntents.EXTRA_FINAL_URI); if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) { Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile); setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR); @@ -225,13 +226,13 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } private void cleanupPostMove(Context context, Intent intent) { - DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); + DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST); if (request == null) { Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring."); return; } - List<Uri> tempFiles = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_TEMP_LIST); + List<Uri> tempFiles = intent.getParcelableExtra(VendorIntents.EXTRA_TEMP_LIST); if (tempFiles == null) { return; } @@ -246,15 +247,15 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { private void generateTempFiles(Context context, Intent intent) { FileServiceInfo serviceInfo = - intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO); + intent.getParcelableExtra(VendorIntents.EXTRA_SERVICE_INFO); if (serviceInfo == null) { Log.w(LOG_TAG, "Temp file request did not include the associated service info. " + "Ignoring."); setResultCode(RESULT_MALFORMED_INTENT); return; } - int fdCount = intent.getIntExtra(MbmsDownloadManager.EXTRA_FD_COUNT, 0); - List<Uri> pausedList = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_PAUSED_LIST); + int fdCount = intent.getIntExtra(VendorIntents.EXTRA_FD_COUNT, 0); + List<Uri> pausedList = intent.getParcelableExtra(VendorIntents.EXTRA_PAUSED_LIST); if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) { Log.i(LOG_TAG, "No temp files actually requested. Ending."); @@ -269,8 +270,8 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { generateUrisForPausedFiles(context, serviceInfo, pausedList); Bundle result = new Bundle(); - result.putParcelableArrayList(MbmsDownloadManager.EXTRA_FREE_URI_LIST, freshTempFiles); - result.putParcelableArrayList(MbmsDownloadManager.EXTRA_PAUSED_URI_LIST, pausedFiles); + result.putParcelableArrayList(VendorIntents.EXTRA_FREE_URI_LIST, freshTempFiles); + result.putParcelableArrayList(VendorIntents.EXTRA_PAUSED_URI_LIST, pausedFiles); setResultCode(RESULT_OK); setResultExtras(result); } @@ -353,11 +354,11 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { private void cleanupTempFiles(Context context, Intent intent) { FileServiceInfo serviceInfo = - intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO); + intent.getParcelableExtra(VendorIntents.EXTRA_SERVICE_INFO); File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo.getServiceId()); final List<Uri> filesInUse = - intent.getParcelableArrayListExtra(MbmsDownloadManager.EXTRA_TEMP_FILES_IN_USE); + intent.getParcelableArrayListExtra(VendorIntents.EXTRA_TEMP_FILES_IN_USE); File[] filesToDelete = tempFileDir.listFiles(new FileFilter() { @Override public boolean accept(File file) { diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java index a0834eb6864f..71713d013f97 100644 --- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java +++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java @@ -18,6 +18,7 @@ package android.telephony.mbms.vendor; import android.annotation.NonNull; import android.os.RemoteException; +import android.telephony.mbms.DownloadProgressListener; import android.telephony.mbms.DownloadRequest; import android.telephony.mbms.FileInfo; import android.telephony.mbms.FileServiceInfo; @@ -59,8 +60,8 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { * @hide */ @Override - public int initialize(int subscriptionId, - IMbmsDownloadManagerCallback callback) throws RemoteException { + public final int initialize(int subscriptionId, + final IMbmsDownloadManagerCallback callback) throws RemoteException { return initialize(subscriptionId, new MbmsDownloadManagerCallback() { @Override public void error(int errorCode, String message) throws RemoteException { @@ -133,12 +134,29 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { * @param downloadRequest An object describing the set of files to be downloaded. * @param listener A listener through which the middleware can provide progress updates to * the app while both are still running. - * @return TODO: enumerate possible return values + * @return Any error from {@link android.telephony.mbms.MbmsException.GeneralErrors} + * or {@link MbmsException#SUCCESS} + */ + public int download(DownloadRequest downloadRequest, DownloadProgressListener listener) { + return 0; + } + + /** + * Actual AIDL implementation -- hides the callback AIDL from the API. + * @hide */ @Override - public int download(DownloadRequest downloadRequest, IDownloadProgressListener listener) + public final int download(DownloadRequest downloadRequest, IDownloadProgressListener listener) throws RemoteException { - return 0; + return download(downloadRequest, new DownloadProgressListener() { + @Override + public void progress(DownloadRequest request, FileInfo fileInfo, int + currentDownloadSize, int fullDownloadSize, int currentDecodedSize, int + fullDecodedSize) throws RemoteException { + listener.progress(request, fileInfo, currentDownloadSize, fullDownloadSize, + currentDecodedSize, fullDecodedSize); + } + }); } diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java index 72c6582c2603..843e0482ee1b 100644 --- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java +++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java @@ -47,10 +47,10 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { * or {@link MbmsException#SUCCESS}. Non-successful error codes will be passed to the app via * {@link IMbmsStreamingManagerCallback#error(int, String)}. * - * @param listener The callback to use to communicate with the app. + * @param callback The callback to use to communicate with the app. * @param subscriptionId The subscription ID to use. */ - public int initialize(MbmsStreamingManagerCallback listener, int subscriptionId) + public int initialize(MbmsStreamingManagerCallback callback, int subscriptionId) throws RemoteException { return 0; } @@ -60,10 +60,10 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { * @hide */ @Override - public final int initialize(IMbmsStreamingManagerCallback listener, final int subscriptionId) - throws RemoteException { + public final int initialize(final IMbmsStreamingManagerCallback callback, + final int subscriptionId) throws RemoteException { final int uid = Binder.getCallingUid(); - listener.asBinder().linkToDeath(new DeathRecipient() { + callback.asBinder().linkToDeath(new DeathRecipient() { @Override public void binderDied() { onAppCallbackDied(uid, subscriptionId); @@ -74,7 +74,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onError(int errorCode, String message) { try { - listener.error(errorCode, message); + callback.error(errorCode, message); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -83,7 +83,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) { try { - listener.streamingServicesUpdated(services); + callback.streamingServicesUpdated(services); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -92,7 +92,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onMiddlewareReady() { try { - listener.middlewareReady(); + callback.middlewareReady(); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -133,11 +133,11 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { * * @param subscriptionId The subscription id to use. * @param serviceId The ID of the streaming service that the app has requested. - * @param listener The listener object on which the app wishes to receive updates. + * @param callback The callback object on which the app wishes to receive updates. * @return Any error in {@link android.telephony.mbms.MbmsException.GeneralErrors} */ public int startStreaming(int subscriptionId, String serviceId, - StreamingServiceCallback listener) throws RemoteException { + StreamingServiceCallback callback) throws RemoteException { return 0; } @@ -148,9 +148,9 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { */ @Override public int startStreaming(int subscriptionId, String serviceId, - IStreamingServiceCallback listener) throws RemoteException { + IStreamingServiceCallback callback) throws RemoteException { final int uid = Binder.getCallingUid(); - listener.asBinder().linkToDeath(new DeathRecipient() { + callback.asBinder().linkToDeath(new DeathRecipient() { @Override public void binderDied() { onAppCallbackDied(uid, subscriptionId); @@ -161,7 +161,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onError(int errorCode, String message) { try { - listener.error(errorCode, message); + callback.error(errorCode, message); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -171,7 +171,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { public void onStreamStateUpdated(@StreamingService.StreamingState int state, @StreamingService.StreamingStateChangeReason int reason) { try { - listener.streamStateUpdated(state, reason); + callback.streamStateUpdated(state, reason); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -180,7 +180,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onMediaDescriptionUpdated() { try { - listener.mediaDescriptionUpdated(); + callback.mediaDescriptionUpdated(); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -189,7 +189,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onBroadcastSignalStrengthUpdated(int signalStrength) { try { - listener.broadcastSignalStrengthUpdated(signalStrength); + callback.broadcastSignalStrengthUpdated(signalStrength); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } @@ -198,7 +198,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { @Override public void onStreamMethodUpdated(int methodType) { try { - listener.streamMethodUpdated(methodType); + callback.streamMethodUpdated(methodType); } catch (RemoteException e) { onAppCallbackDied(uid, subscriptionId); } diff --git a/telephony/java/android/telephony/mbms/vendor/VendorIntents.java b/telephony/java/android/telephony/mbms/vendor/VendorIntents.java new file mode 100644 index 000000000000..367c995c6f7d --- /dev/null +++ b/telephony/java/android/telephony/mbms/vendor/VendorIntents.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.telephony.mbms.vendor; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.telephony.mbms.DownloadRequest; +import android.telephony.mbms.MbmsDownloadReceiver; + +import java.io.File; +import java.util.List; + +/** + * @hide + * TODO: future systemapi + */ +public class VendorIntents { + + /** + * The MBMS middleware should send this when a download of single file has completed or + * failed. Mandatory extras are + * {@link android.telephony.MbmsDownloadManager#EXTRA_RESULT} + * {@link android.telephony.MbmsDownloadManager#EXTRA_FILE_INFO} + * {@link #EXTRA_REQUEST} + * {@link #EXTRA_TEMP_LIST} + * {@link #EXTRA_FINAL_URI} + */ + public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = + "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL"; + + /** + * The MBMS middleware should send this when it wishes to request {@code content://} URIs to + * serve as temp files for downloads or when it wishes to resume paused downloads. Mandatory + * extras are + * {@link #EXTRA_REQUEST} + * + * Optional extras are + * {@link #EXTRA_FD_COUNT} (0 if not present) + * {@link #EXTRA_PAUSED_LIST} (empty if not present) + */ + public static final String ACTION_FILE_DESCRIPTOR_REQUEST = + "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST"; + + /** + * The MBMS middleware should send this when it wishes to clean up temp files in the app's + * filesystem. Mandatory extras are: + * {@link #EXTRA_TEMP_FILES_IN_USE} + */ + public static final String ACTION_CLEANUP = + "android.telephony.mbms.action.CLEANUP"; + + /** + * Extra containing a {@link List} of {@link Uri}s that were used as temp files for this + * completed file. These {@link Uri}s should have scheme {@code file://}, and the temp + * files will be deleted upon receipt of the intent. + * May be null. + */ + public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST"; + + /** + * Extra containing an integer indicating the number of temp files requested. + */ + public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT"; + + /** + * Extra containing a list of {@link Uri}s that the middleware is requesting access to via + * {@link #ACTION_FILE_DESCRIPTOR_REQUEST} in order to resume downloading. These {@link Uri}s + * should have scheme {@code file://}. + */ + public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST"; + + /** + * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the + * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These are temp files that are meant + * to be used for new file downloads. + */ + public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST"; + + /** + * Extra containing a list of {@link android.telephony.mbms.UriPathPair}s, used in the + * response to {@link #ACTION_FILE_DESCRIPTOR_REQUEST}. These + * {@link android.telephony.mbms.UriPathPair}s contain {@code content://} URIs that provide + * access to previously paused downloads. + */ + public static final String EXTRA_PAUSED_URI_LIST = + "android.telephony.mbms.extra.PAUSED_URI_LIST"; + + /** + * Extra containing a string that points to the middleware's knowledge of where the temp file + * root for the app is. The path should be a canonical path as returned by + * {@link File#getCanonicalPath()} + */ + public static final String EXTRA_TEMP_FILE_ROOT = + "android.telephony.mbms.extra.TEMP_FILE_ROOT"; + + /** + * Extra containing a list of {@link Uri}s indicating temp files which the middleware is + * still using. + */ + public static final String EXTRA_TEMP_FILES_IN_USE = + "android.telephony.mbms.extra.TEMP_FILES_IN_USE"; + + /** + * Extra containing the {@link DownloadRequest} for which the download result or file + * descriptor request is for. Must not be null. + */ + public static final String EXTRA_REQUEST = "android.telephony.mbms.extra.REQUEST"; + + /** + * Extra containing a single {@link Uri} indicating the path to the temp file in which the + * decoded downloaded file resides. Must not be null. + */ + public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI"; + + /** + * Extra containing an instance of {@link android.telephony.mbms.ServiceInfo}, used by + * file-descriptor requests and cleanup requests to specify which service they want to + * request temp files or clean up temp files for, respectively. + */ + public static final String EXTRA_SERVICE_INFO = + "android.telephony.mbms.extra.SERVICE_INFO"; + + /** + * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that + * the various intents from the middleware should be targeted towards. + * @param uid The uid of the frontend app. + * @return The component name of the receiver that the middleware should send its intents to, + * or null if the app didn't declare it in the manifest. + */ + public static ComponentName getAppReceiverFromUid(Context context, int uid) { + String[] packageNames = context.getPackageManager().getPackagesForUid(uid); + if (packageNames == null) { + return null; + } + + for (String packageName : packageNames) { + ComponentName candidate = new ComponentName(packageName, + MbmsDownloadReceiver.class.getCanonicalName()); + Intent queryIntent = new Intent(); + queryIntent.setComponent(candidate); + List<ResolveInfo> receivers = + context.getPackageManager().queryBroadcastReceivers(queryIntent, 0); + if (receivers != null && receivers.size() > 0) { + return candidate; + } + } + return null; + } +} |