Merge "Embms adjustments for 7/28" am: 3f6a95e8b0

am: aeb64f7f98

Change-Id: I88b9f6fb07b9e7e10bb375d2e8bef968da51c20c
This commit is contained in:
Hall Liu
2017-08-23 22:22:48 +00:00
committed by android-build-merger
7 changed files with 277 additions and 233 deletions

View File

@@ -18,18 +18,19 @@ package android.telephony;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.telephony.mbms.DownloadProgressListener;
import android.telephony.mbms.FileInfo; import android.telephony.mbms.FileInfo;
import android.telephony.mbms.DownloadRequest; import android.telephony.mbms.DownloadRequest;
import android.telephony.mbms.IDownloadProgressListener;
import android.telephony.mbms.MbmsDownloadManagerCallback; import android.telephony.mbms.MbmsDownloadManagerCallback;
import android.telephony.mbms.MbmsDownloadReceiver; import android.telephony.mbms.MbmsDownloadReceiver;
import android.telephony.mbms.MbmsException; import android.telephony.mbms.MbmsException;
@@ -52,147 +53,38 @@ import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
public class MbmsDownloadManager { public class MbmsDownloadManager {
private static final String LOG_TAG = MbmsDownloadManager.class.getSimpleName(); 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 = public static final String MBMS_DOWNLOAD_SERVICE_ACTION =
"android.telephony.action.EmbmsDownload"; "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 * Integer extra indicating the result code of the download. One of
* {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, or {@link #RESULT_CANCELLED}. * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, or {@link #RESULT_CANCELLED}.
* TODO: Not systemapi.
*/ */
public static final String EXTRA_RESULT = "android.telephony.mbms.extra.RESULT"; public static final String EXTRA_RESULT = "android.telephony.mbms.extra.RESULT";
/** /**
* Extra containing the {@link android.telephony.mbms.FileInfo} for which the download result * Extra containing the {@link android.telephony.mbms.FileInfo} for which the download result
* is for. Must not be null. * is for. Must not be null.
* TODO: Not systemapi.
*/ */
public static final String EXTRA_FILE_INFO = "android.telephony.mbms.extra.FILE_INFO"; 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 * Extra containing a single {@link Uri} indicating the location of the successfully
* downloaded file. Set on the intent provided via * downloaded file. Set on the intent provided via
* {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}. * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}.
* Will always be set to a non-null value if {@link #EXTRA_RESULT} is set to * Will always be set to a non-null value if {@link #EXTRA_RESULT} is set to
* {@link #RESULT_SUCCESSFUL}. * {@link #RESULT_SUCCESSFUL}.
* TODO: Not systemapi.
*/ */
public static final String EXTRA_COMPLETED_FILE_URI = public static final String EXTRA_COMPLETED_FILE_URI =
"android.telephony.mbms.extra.COMPLETED_FILE_URI"; "android.telephony.mbms.extra.COMPLETED_FILE_URI";
public static final int RESULT_SUCCESSFUL = 1; public static final int RESULT_SUCCESSFUL = 1;
public static final int RESULT_CANCELLED = 2; public static final int RESULT_CANCELLED = 2;
public static final int RESULT_EXPIRED = 3; public static final int RESULT_EXPIRED = 3;
public static final int RESULT_IO_ERROR = 4;
// TODO - more results! // TODO - more results!
/** @hide */ /** @hide */
@@ -375,14 +267,15 @@ public class MbmsDownloadManager {
* local instance of {@link android.content.SharedPreferences} and by the middleware. * local instance of {@link android.content.SharedPreferences} and by the middleware.
* *
* If this method is not called at least once before calling * 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 * 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}. * {@link android.telephony.mbms.MbmsTempFileProvider#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY}.
* *
* Before calling this method, the app must cancel all of its pending * Before calling this method, the app must cancel all of its pending
* {@link DownloadRequest}s via {@link #cancelDownload(DownloadRequest)}. If this is not done, * {@link DownloadRequest}s via {@link #cancelDownload(DownloadRequest)}. If this is not done,
* an {@link MbmsException} will be thrown with code * 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 * The {@link File} supplied as a root temp file directory must already exist. If not, an
* {@link IllegalArgumentException} will be thrown. * {@link IllegalArgumentException} will be thrown.
@@ -422,6 +315,26 @@ public class MbmsDownloadManager {
prefs.edit().putString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, filePath).apply(); prefs.edit().putString(MbmsTempFileProvider.TEMP_FILE_ROOT_PREF_NAME, filePath).apply();
} }
/**
* 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. * Requests a download of a file that is available via multicast.
* *
@@ -443,7 +356,7 @@ public class MbmsDownloadManager {
* @param progressListener Optional listener that will be provided progress updates * @param progressListener Optional listener that will be provided progress updates
* if the app is running. * if the app is running.
*/ */
public void download(DownloadRequest request, IDownloadProgressListener progressListener) public void download(DownloadRequest request, DownloadProgressListener progressListener)
throws MbmsException { throws MbmsException {
IMbmsDownloadService downloadService = mService.get(); IMbmsDownloadService downloadService = mService.get();
if (downloadService == null) { if (downloadService == null) {
@@ -473,7 +386,7 @@ public class MbmsDownloadManager {
/** /**
* Returns a list of pending {@link DownloadRequest}s that originated from this application. * Returns a list of pending {@link DownloadRequest}s that originated from this application.
* A pending request is one that was issued via * 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)}. * {@link #cancelDownload(DownloadRequest)}.
* @return A list, possibly empty, of {@link DownloadRequest}s * @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) { private void writeDownloadRequestToken(DownloadRequest request) {
File token = getDownloadRequestTokenPath(request); File token = getDownloadRequestTokenPath(request);
if (!token.getParentFile().exists()) { if (!token.getParentFile().exists()) {

View File

@@ -16,6 +16,8 @@
package android.telephony.mbms; package android.telephony.mbms;
import android.os.RemoteException;
/** /**
* A optional listener class used by download clients to track progress. * A optional listener class used by download clients to track progress.
* @hide * @hide
@@ -38,8 +40,9 @@ public class DownloadProgressListener extends IDownloadProgressListener.Stub {
* @param currentDecodedSize is the number of bytes that have been decoded. * @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. * @param fullDecodedSize is the total number of bytes that make up the final decoded content.
*/ */
@Override
public void progress(DownloadRequest request, FileInfo fileInfo, public void progress(DownloadRequest request, FileInfo fileInfo,
int currentDownloadSize, int fullDownloadSize, int currentDownloadSize, int fullDownloadSize,
int currentDecodedSize, int fullDecodedSize) { int currentDecodedSize, int fullDecodedSize) throws RemoteException {
} }
} }

View File

@@ -38,16 +38,6 @@ public class FileInfo implements Parcelable {
*/ */
private final String mimeType; 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 = public static final Parcelable.Creator<FileInfo> CREATOR =
new Parcelable.Creator<FileInfo>() { new Parcelable.Creator<FileInfo>() {
@Override @Override
@@ -65,29 +55,20 @@ public class FileInfo implements Parcelable {
* @hide * @hide
* TODO: systemapi * TODO: systemapi
*/ */
public FileInfo(Uri uri, String mimeType, long size, byte[] md5Hash) { public FileInfo(Uri uri, String mimeType) {
this.uri = uri; this.uri = uri;
this.mimeType = mimeType; this.mimeType = mimeType;
this.size = size;
this.md5Hash = md5Hash;
} }
private FileInfo(Parcel in) { private FileInfo(Parcel in) {
uri = in.readParcelable(null); uri = in.readParcelable(null);
mimeType = in.readString(); mimeType = in.readString();
size = in.readLong();
int arraySize = in.readInt();
md5Hash = new byte[arraySize];
in.readByteArray(md5Hash);
} }
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(uri, flags); dest.writeParcelable(uri, flags);
dest.writeString(mimeType); dest.writeString(mimeType);
dest.writeLong(size);
dest.writeInt(md5Hash.length);
dest.writeByteArray(md5Hash);
} }
@Override @Override
@@ -102,12 +83,4 @@ public class FileInfo implements Parcelable {
public String getMimeType() { public String getMimeType() {
return mimeType; return mimeType;
} }
public long getSize() {
return size;
}
public byte[] getMd5Hash() {
return md5Hash;
}
} }

View File

@@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.telephony.MbmsDownloadManager; import android.telephony.MbmsDownloadManager;
import android.telephony.mbms.vendor.VendorIntents;
import android.util.Log; import android.util.Log;
import java.io.File; 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 * Indicates that the intent sent had an invalid action. This will be the result if
* {@link Intent#getAction()} returns anything other than * {@link Intent#getAction()} returns anything other than
* {@link MbmsDownloadManager#ACTION_DOWNLOAD_RESULT_INTERNAL}, * {@link VendorIntents#ACTION_DOWNLOAD_RESULT_INTERNAL},
* {@link MbmsDownloadManager#ACTION_FILE_DESCRIPTOR_REQUEST}, or * {@link VendorIntents#ACTION_FILE_DESCRIPTOR_REQUEST}, or
* {@link MbmsDownloadManager#ACTION_CLEANUP}. * {@link VendorIntents#ACTION_CLEANUP}.
* This is a fatal result code and no result extras should be expected. * This is a fatal result code and no result extras should be expected.
*/ */
public static final int RESULT_INVALID_ACTION = 1; 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; 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. * does not match what the app has stored.
* This is a fatal result code and no result extras should be expected. * 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); setResultCode(RESULT_MALFORMED_INTENT);
return; 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())) { MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath())) {
setResultCode(RESULT_BAD_TEMP_FILE_ROOT); setResultCode(RESULT_BAD_TEMP_FILE_ROOT);
return; return;
} }
if (MbmsDownloadManager.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { if (VendorIntents.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) {
moveDownloadedFile(context, intent); moveDownloadedFile(context, intent);
cleanupPostMove(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); generateTempFiles(context, intent);
} else if (MbmsDownloadManager.ACTION_CLEANUP.equals(intent.getAction())) { } else if (VendorIntents.ACTION_CLEANUP.equals(intent.getAction())) {
cleanupTempFiles(context, intent); cleanupTempFiles(context, intent);
} else { } else {
setResultCode(RESULT_INVALID_ACTION); setResultCode(RESULT_INVALID_ACTION);
@@ -123,16 +124,16 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
} }
private boolean verifyIntentContents(Context context, Intent intent) { 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)) { if (!intent.hasExtra(MbmsDownloadManager.EXTRA_RESULT)) {
Log.w(LOG_TAG, "Download result did not include a result code. Ignoring."); Log.w(LOG_TAG, "Download result did not include a result code. Ignoring.");
return false; 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."); Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring.");
return false; 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."); Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring.");
return false; return false;
} }
@@ -141,12 +142,12 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
"Ignoring."); "Ignoring.");
return false; 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 " + Log.w(LOG_TAG, "Download result did not include the path to the final " +
"temp file. Ignoring."); "temp file. Ignoring.");
return false; return false;
} }
DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST);
String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX; String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
File expectedTokenFile = new File( File expectedTokenFile = new File(
MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()), MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()),
@@ -156,27 +157,27 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
"Expected " + expectedTokenFile); "Expected " + expectedTokenFile);
return false; return false;
} }
} else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { } else if (VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
if (!intent.hasExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO)) { if (!intent.hasExtra(VendorIntents.EXTRA_SERVICE_INFO)) {
Log.w(LOG_TAG, "Temp file request did not include the associated service info." + Log.w(LOG_TAG, "Temp file request did not include the associated service info." +
" Ignoring."); " Ignoring.");
return false; 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."); Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring.");
return false; return false;
} }
} else if (MbmsDownloadManager.ACTION_CLEANUP.equals(intent.getAction())) { } else if (VendorIntents.ACTION_CLEANUP.equals(intent.getAction())) {
if (!intent.hasExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO)) { if (!intent.hasExtra(VendorIntents.EXTRA_SERVICE_INFO)) {
Log.w(LOG_TAG, "Cleanup request did not include the associated service info." + Log.w(LOG_TAG, "Cleanup request did not include the associated service info." +
" Ignoring."); " Ignoring.");
return false; 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."); Log.w(LOG_TAG, "Cleanup request did not include the temp file root. Ignoring.");
return false; 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. " + Log.w(LOG_TAG, "Cleanup request did not include the list of temp files in use. " +
"Ignoring."); "Ignoring.");
return false; return false;
@@ -186,7 +187,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
} }
private void moveDownloadedFile(Context context, Intent intent) { 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(); Intent intentForApp = request.getIntentForApp();
int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT, int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT,
@@ -200,7 +201,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
} }
Uri destinationUri = request.getDestinationUri(); 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)) { if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) {
Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile); Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR); setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
@@ -225,13 +226,13 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
} }
private void cleanupPostMove(Context context, Intent intent) { private void cleanupPostMove(Context context, Intent intent) {
DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); DownloadRequest request = intent.getParcelableExtra(VendorIntents.EXTRA_REQUEST);
if (request == null) { if (request == null) {
Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring."); Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring.");
return; return;
} }
List<Uri> tempFiles = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_TEMP_LIST); List<Uri> tempFiles = intent.getParcelableExtra(VendorIntents.EXTRA_TEMP_LIST);
if (tempFiles == null) { if (tempFiles == null) {
return; return;
} }
@@ -246,15 +247,15 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
private void generateTempFiles(Context context, Intent intent) { private void generateTempFiles(Context context, Intent intent) {
FileServiceInfo serviceInfo = FileServiceInfo serviceInfo =
intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO); intent.getParcelableExtra(VendorIntents.EXTRA_SERVICE_INFO);
if (serviceInfo == null) { if (serviceInfo == null) {
Log.w(LOG_TAG, "Temp file request did not include the associated service info. " + Log.w(LOG_TAG, "Temp file request did not include the associated service info. " +
"Ignoring."); "Ignoring.");
setResultCode(RESULT_MALFORMED_INTENT); setResultCode(RESULT_MALFORMED_INTENT);
return; return;
} }
int fdCount = intent.getIntExtra(MbmsDownloadManager.EXTRA_FD_COUNT, 0); int fdCount = intent.getIntExtra(VendorIntents.EXTRA_FD_COUNT, 0);
List<Uri> pausedList = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_PAUSED_LIST); List<Uri> pausedList = intent.getParcelableExtra(VendorIntents.EXTRA_PAUSED_LIST);
if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) { if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) {
Log.i(LOG_TAG, "No temp files actually requested. Ending."); Log.i(LOG_TAG, "No temp files actually requested. Ending.");
@@ -269,8 +270,8 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
generateUrisForPausedFiles(context, serviceInfo, pausedList); generateUrisForPausedFiles(context, serviceInfo, pausedList);
Bundle result = new Bundle(); Bundle result = new Bundle();
result.putParcelableArrayList(MbmsDownloadManager.EXTRA_FREE_URI_LIST, freshTempFiles); result.putParcelableArrayList(VendorIntents.EXTRA_FREE_URI_LIST, freshTempFiles);
result.putParcelableArrayList(MbmsDownloadManager.EXTRA_PAUSED_URI_LIST, pausedFiles); result.putParcelableArrayList(VendorIntents.EXTRA_PAUSED_URI_LIST, pausedFiles);
setResultCode(RESULT_OK); setResultCode(RESULT_OK);
setResultExtras(result); setResultExtras(result);
} }
@@ -353,11 +354,11 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
private void cleanupTempFiles(Context context, Intent intent) { private void cleanupTempFiles(Context context, Intent intent) {
FileServiceInfo serviceInfo = FileServiceInfo serviceInfo =
intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO); intent.getParcelableExtra(VendorIntents.EXTRA_SERVICE_INFO);
File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context,
serviceInfo.getServiceId()); serviceInfo.getServiceId());
final List<Uri> filesInUse = 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() { File[] filesToDelete = tempFileDir.listFiles(new FileFilter() {
@Override @Override
public boolean accept(File file) { public boolean accept(File file) {

View File

@@ -18,6 +18,7 @@ package android.telephony.mbms.vendor;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.os.RemoteException; import android.os.RemoteException;
import android.telephony.mbms.DownloadProgressListener;
import android.telephony.mbms.DownloadRequest; import android.telephony.mbms.DownloadRequest;
import android.telephony.mbms.FileInfo; import android.telephony.mbms.FileInfo;
import android.telephony.mbms.FileServiceInfo; import android.telephony.mbms.FileServiceInfo;
@@ -59,8 +60,8 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub {
* @hide * @hide
*/ */
@Override @Override
public int initialize(int subscriptionId, public final int initialize(int subscriptionId,
IMbmsDownloadManagerCallback callback) throws RemoteException { final IMbmsDownloadManagerCallback callback) throws RemoteException {
return initialize(subscriptionId, new MbmsDownloadManagerCallback() { return initialize(subscriptionId, new MbmsDownloadManagerCallback() {
@Override @Override
public void error(int errorCode, String message) throws RemoteException { 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 downloadRequest An object describing the set of files to be downloaded.
* @param listener A listener through which the middleware can provide progress updates to * @param listener A listener through which the middleware can provide progress updates to
* the app while both are still running. * 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 @Override
public int download(DownloadRequest downloadRequest, IDownloadProgressListener listener) public final int download(DownloadRequest downloadRequest, IDownloadProgressListener listener)
throws RemoteException { 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);
}
});
} }

View File

@@ -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 * or {@link MbmsException#SUCCESS}. Non-successful error codes will be passed to the app via
* {@link IMbmsStreamingManagerCallback#error(int, String)}. * {@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. * @param subscriptionId The subscription ID to use.
*/ */
public int initialize(MbmsStreamingManagerCallback listener, int subscriptionId) public int initialize(MbmsStreamingManagerCallback callback, int subscriptionId)
throws RemoteException { throws RemoteException {
return 0; return 0;
} }
@@ -60,10 +60,10 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
* @hide * @hide
*/ */
@Override @Override
public final int initialize(IMbmsStreamingManagerCallback listener, final int subscriptionId) public final int initialize(final IMbmsStreamingManagerCallback callback,
throws RemoteException { final int subscriptionId) throws RemoteException {
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
listener.asBinder().linkToDeath(new DeathRecipient() { callback.asBinder().linkToDeath(new DeathRecipient() {
@Override @Override
public void binderDied() { public void binderDied() {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
@@ -74,7 +74,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onError(int errorCode, String message) { public void onError(int errorCode, String message) {
try { try {
listener.error(errorCode, message); callback.error(errorCode, message);
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -83,7 +83,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) { public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) {
try { try {
listener.streamingServicesUpdated(services); callback.streamingServicesUpdated(services);
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -92,7 +92,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onMiddlewareReady() { public void onMiddlewareReady() {
try { try {
listener.middlewareReady(); callback.middlewareReady();
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -133,11 +133,11 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
* *
* @param subscriptionId The subscription id to use. * @param subscriptionId The subscription id to use.
* @param serviceId The ID of the streaming service that the app has requested. * @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} * @return Any error in {@link android.telephony.mbms.MbmsException.GeneralErrors}
*/ */
public int startStreaming(int subscriptionId, String serviceId, public int startStreaming(int subscriptionId, String serviceId,
StreamingServiceCallback listener) throws RemoteException { StreamingServiceCallback callback) throws RemoteException {
return 0; return 0;
} }
@@ -148,9 +148,9 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
*/ */
@Override @Override
public int startStreaming(int subscriptionId, String serviceId, public int startStreaming(int subscriptionId, String serviceId,
IStreamingServiceCallback listener) throws RemoteException { IStreamingServiceCallback callback) throws RemoteException {
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
listener.asBinder().linkToDeath(new DeathRecipient() { callback.asBinder().linkToDeath(new DeathRecipient() {
@Override @Override
public void binderDied() { public void binderDied() {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
@@ -161,7 +161,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onError(int errorCode, String message) { public void onError(int errorCode, String message) {
try { try {
listener.error(errorCode, message); callback.error(errorCode, message);
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -171,7 +171,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
public void onStreamStateUpdated(@StreamingService.StreamingState int state, public void onStreamStateUpdated(@StreamingService.StreamingState int state,
@StreamingService.StreamingStateChangeReason int reason) { @StreamingService.StreamingStateChangeReason int reason) {
try { try {
listener.streamStateUpdated(state, reason); callback.streamStateUpdated(state, reason);
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -180,7 +180,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onMediaDescriptionUpdated() { public void onMediaDescriptionUpdated() {
try { try {
listener.mediaDescriptionUpdated(); callback.mediaDescriptionUpdated();
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -189,7 +189,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onBroadcastSignalStrengthUpdated(int signalStrength) { public void onBroadcastSignalStrengthUpdated(int signalStrength) {
try { try {
listener.broadcastSignalStrengthUpdated(signalStrength); callback.broadcastSignalStrengthUpdated(signalStrength);
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }
@@ -198,7 +198,7 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub {
@Override @Override
public void onStreamMethodUpdated(int methodType) { public void onStreamMethodUpdated(int methodType) {
try { try {
listener.streamMethodUpdated(methodType); callback.streamMethodUpdated(methodType);
} catch (RemoteException e) { } catch (RemoteException e) {
onAppCallbackDied(uid, subscriptionId); onAppCallbackDied(uid, subscriptionId);
} }

View File

@@ -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;
}
}