summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--telephony/java/android/telephony/MbmsDownloadManager.java7
-rw-r--r--telephony/java/android/telephony/mbms/DownloadRequest.java134
-rw-r--r--telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java28
-rw-r--r--telephony/java/android/telephony/mbms/MbmsUtils.java5
4 files changed, 126 insertions, 48 deletions
diff --git a/telephony/java/android/telephony/MbmsDownloadManager.java b/telephony/java/android/telephony/MbmsDownloadManager.java
index b3f46c22ba0a..231f2c8660e9 100644
--- a/telephony/java/android/telephony/MbmsDownloadManager.java
+++ b/telephony/java/android/telephony/MbmsDownloadManager.java
@@ -93,19 +93,21 @@ public class MbmsDownloadManager {
/**
* 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: future systemapi (here and and all extras) except the two for the app intent
+ * 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";
@@ -180,6 +182,7 @@ public class MbmsDownloadManager {
* {@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";
@@ -554,7 +557,7 @@ public class MbmsDownloadManager {
private File getDownloadRequestTokenPath(DownloadRequest request) {
File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
- request.getFileServiceInfo());
+ request.getFileServiceId());
String downloadTokenFileName = request.getHash()
+ MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX;
return new File(tempFileLocation, downloadTokenFileName);
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index 345729d82dea..01e0bbdfc0a0 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -21,7 +21,14 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Base64;
-
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@@ -35,24 +42,52 @@ import java.util.Objects;
public class DownloadRequest implements Parcelable {
// Version code used to keep token calculation consistent.
private static final int CURRENT_VERSION = 1;
+ private static final String LOG_TAG = "MbmsDownloadRequest";
+
+ /**
+ * Maximum permissible length for the app's download-completion intent, when serialized via
+ * {@link Intent#toUri(int)}.
+ */
+ public static final int MAX_APP_INTENT_SIZE = 50000;
+
+ /**
+ * Maximum permissible length for the app's destination path, when serialized via
+ * {@link Uri#toString()}.
+ */
+ public static final int MAX_DESTINATION_URI_SIZE = 50000;
/** @hide */
+ private static class OpaqueDataContainer implements Serializable {
+ private final String destinationUri;
+ private final String appIntent;
+ private final int version;
+
+ public OpaqueDataContainer(String destinationUri, String appIntent, int version) {
+ this.destinationUri = destinationUri;
+ this.appIntent = appIntent;
+ this.version = version;
+ }
+ }
+
public static class Builder {
- private int id;
- private FileServiceInfo serviceInfo;
+ private String fileServiceId;
private Uri source;
private Uri dest;
private int subscriptionId;
private String appIntent;
private int version = CURRENT_VERSION;
- public Builder setId(int id) {
- this.id = id;
+ public Builder setServiceInfo(FileServiceInfo serviceInfo) {
+ fileServiceId = serviceInfo.getServiceId();
return this;
}
- public Builder setServiceInfo(FileServiceInfo serviceInfo) {
- this.serviceInfo = serviceInfo;
+ /**
+ * @hide
+ * TODO: systemapi
+ */
+ public Builder setServiceId(String serviceId) {
+ fileServiceId = serviceId;
return this;
}
@@ -62,6 +97,10 @@ public class DownloadRequest implements Parcelable {
}
public Builder setDest(Uri dest) {
+ if (dest.toString().length() > MAX_DESTINATION_URI_SIZE) {
+ throw new IllegalArgumentException("Destination uri must not exceed length " +
+ MAX_DESTINATION_URI_SIZE);
+ }
this.dest = dest;
return this;
}
@@ -73,33 +112,53 @@ public class DownloadRequest implements Parcelable {
public Builder setAppIntent(Intent intent) {
this.appIntent = intent.toUri(0);
+ if (this.appIntent.length() > MAX_APP_INTENT_SIZE) {
+ throw new IllegalArgumentException("App intent must not exceed length " +
+ MAX_APP_INTENT_SIZE);
+ }
return this;
}
- public Builder setVersion(int version) {
- this.version = version;
+ /**
+ * For use by middleware only
+ * TODO: systemapi
+ * @hide
+ */
+ public Builder setOpaqueData(byte[] data) {
+ try {
+ ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(data));
+ OpaqueDataContainer dataContainer = (OpaqueDataContainer) stream.readObject();
+ version = dataContainer.version;
+ appIntent = dataContainer.appIntent;
+ dest = Uri.parse(dataContainer.destinationUri);
+ } catch (IOException e) {
+ // Really should never happen
+ Log.e(LOG_TAG, "Got IOException trying to parse opaque data");
+ throw new IllegalArgumentException(e);
+ } catch (ClassNotFoundException e) {
+ Log.e(LOG_TAG, "Got ClassNotFoundException trying to parse opaque data");
+ throw new IllegalArgumentException(e);
+ }
return this;
}
public DownloadRequest build() {
- return new DownloadRequest(id, serviceInfo, source, dest,
+ return new DownloadRequest(fileServiceId, source, dest,
subscriptionId, appIntent, version);
}
}
- private final int downloadId;
- private final FileServiceInfo fileServiceInfo;
+ private final String fileServiceId;
private final Uri sourceUri;
private final Uri destinationUri;
private final int subscriptionId;
private final String serializedResultIntentForApp;
private final int version;
- private DownloadRequest(int id, FileServiceInfo serviceInfo,
+ private DownloadRequest(String fileServiceId,
Uri source, Uri dest,
int sub, String appIntent, int version) {
- downloadId = id;
- fileServiceInfo = serviceInfo;
+ this.fileServiceId = fileServiceId;
sourceUri = source;
destinationUri = dest;
subscriptionId = sub;
@@ -112,8 +171,7 @@ public class DownloadRequest implements Parcelable {
}
private DownloadRequest(DownloadRequest dr) {
- downloadId = dr.downloadId;
- fileServiceInfo = dr.fileServiceInfo;
+ fileServiceId = dr.fileServiceId;
sourceUri = dr.sourceUri;
destinationUri = dr.destinationUri;
subscriptionId = dr.subscriptionId;
@@ -122,8 +180,7 @@ public class DownloadRequest implements Parcelable {
}
private DownloadRequest(Parcel in) {
- downloadId = in.readInt();
- fileServiceInfo = in.readParcelable(getClass().getClassLoader());
+ fileServiceId = in.readString();
sourceUri = in.readParcelable(getClass().getClassLoader());
destinationUri = in.readParcelable(getClass().getClassLoader());
subscriptionId = in.readInt();
@@ -136,8 +193,7 @@ public class DownloadRequest implements Parcelable {
}
public void writeToParcel(Parcel out, int flags) {
- out.writeInt(downloadId);
- out.writeParcelable(fileServiceInfo, flags);
+ out.writeString(fileServiceId);
out.writeParcelable(sourceUri, flags);
out.writeParcelable(destinationUri, flags);
out.writeInt(subscriptionId);
@@ -145,12 +201,8 @@ public class DownloadRequest implements Parcelable {
out.writeInt(version);
}
- public int getDownloadId() {
- return downloadId;
- }
-
- public FileServiceInfo getFileServiceInfo() {
- return fileServiceInfo;
+ public String getFileServiceId() {
+ return fileServiceId;
}
public Uri getSourceUri() {
@@ -173,6 +225,27 @@ public class DownloadRequest implements Parcelable {
}
}
+ /**
+ * @hide
+ * TODO: systemapi
+ */
+ public byte[] getOpaqueData() {
+ try {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream stream = new ObjectOutputStream(byteArrayOutputStream);
+ OpaqueDataContainer container = new OpaqueDataContainer(
+ destinationUri.toString(), serializedResultIntentForApp, version);
+ stream.writeObject(container);
+ stream.flush();
+ return byteArrayOutputStream.toByteArray();
+ } catch (IOException e) {
+ // Really should never happen
+ Log.e(LOG_TAG, "Got IOException trying to serialize opaque data");
+ return null;
+ }
+ }
+
+ /** @hide */
public int getVersion() {
return version;
}
@@ -228,10 +301,9 @@ public class DownloadRequest implements Parcelable {
return false;
}
DownloadRequest request = (DownloadRequest) o;
- return downloadId == request.downloadId &&
- subscriptionId == request.subscriptionId &&
+ return subscriptionId == request.subscriptionId &&
version == request.version &&
- Objects.equals(fileServiceInfo, request.fileServiceInfo) &&
+ Objects.equals(fileServiceId, request.fileServiceId) &&
Objects.equals(sourceUri, request.sourceUri) &&
Objects.equals(destinationUri, request.destinationUri) &&
Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp);
@@ -239,7 +311,7 @@ public class DownloadRequest implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(downloadId, fileServiceInfo, sourceUri, destinationUri,
+ return Objects.hash(fileServiceId, sourceUri, destinationUri,
subscriptionId, serializedResultIntentForApp, version);
}
}
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index 5bc53a82a3bb..361716546fb9 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -83,7 +83,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4;
/**
- * Indicates that the manager weas unable to generate one or more of the requested file
+ * Indicates that the manager was unable to generate one or more of the requested file
* descriptors.
* This is a non-fatal result code -- some file descriptors may still be generated, but there
* is no guarantee that they will be the same number as requested.
@@ -149,7 +149,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST);
String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
File expectedTokenFile = new File(
- MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceInfo()),
+ MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()),
expectedTokenFileName);
if (!expectedTokenFile.exists()) {
Log.w(LOG_TAG, "Supplied download request does not match a token that we have. " +
@@ -201,22 +201,24 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
Uri destinationUri = request.getDestinationUri();
Uri finalTempFile = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_FINAL_URI);
- if (!verifyTempFilePath(context, request.getFileServiceInfo(), finalTempFile)) {
+ if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) {
Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
return;
}
- String relativePath = calculateDestinationFileRelativePath(request,
- (FileInfo) intent.getParcelableExtra(MbmsDownloadManager.EXTRA_FILE_INFO));
+ FileInfo completedFileInfo =
+ (FileInfo) intent.getParcelableExtra(MbmsDownloadManager.EXTRA_FILE_INFO);
+ String relativePath = calculateDestinationFileRelativePath(request, completedFileInfo);
Uri finalFileLocation = moveTempFile(finalTempFile, destinationUri, relativePath);
if (finalFileLocation == null) {
Log.w(LOG_TAG, "Failed to move temp file to final destination");
- // TODO: how do we notify the app of this?
setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
+ return;
}
intentForApp.putExtra(MbmsDownloadManager.EXTRA_COMPLETED_FILE_URI, finalFileLocation);
+ intentForApp.putExtra(MbmsDownloadManager.EXTRA_FILE_INFO, completedFileInfo);
context.sendBroadcast(intentForApp);
setResultCode(RESULT_OK);
@@ -235,7 +237,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
}
for (Uri tempFileUri : tempFiles) {
- if (verifyTempFilePath(context, request.getFileServiceInfo(), tempFileUri)) {
+ if (verifyTempFilePath(context, request.getFileServiceId(), tempFileUri)) {
File tempFile = new File(tempFileUri.getSchemeSpecificPart());
tempFile.delete();
}
@@ -276,7 +278,8 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
private ArrayList<UriPathPair> generateFreshTempFiles(Context context,
FileServiceInfo serviceInfo,
int freshFdCount) {
- File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo);
+ File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context,
+ serviceInfo.getServiceId());
if (!tempFileDir.exists()) {
tempFileDir.mkdirs();
}
@@ -327,7 +330,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
ArrayList<UriPathPair> result = new ArrayList<>(pausedFiles.size());
for (Uri fileUri : pausedFiles) {
- if (!verifyTempFilePath(context, serviceInfo, fileUri)) {
+ if (!verifyTempFilePath(context, serviceInfo.getServiceId(), fileUri)) {
Log.w(LOG_TAG, "Supplied file " + fileUri + " is not a valid temp file to resume");
setResultCode(RESULT_TEMP_FILE_GENERATION_ERROR);
continue;
@@ -351,7 +354,8 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
private void cleanupTempFiles(Context context, Intent intent) {
FileServiceInfo serviceInfo =
intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO);
- File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo);
+ File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context,
+ serviceInfo.getServiceId());
List<Uri> filesInUse =
intent.getParcelableArrayListExtra(MbmsDownloadManager.EXTRA_TEMP_FILES_IN_USE);
File[] filesToDelete = tempFileDir.listFiles(new FileFilter() {
@@ -439,7 +443,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
return null;
}
- private static boolean verifyTempFilePath(Context context, FileServiceInfo serviceInfo,
+ private static boolean verifyTempFilePath(Context context, String serviceId,
Uri filePath) {
if (!ContentResolver.SCHEME_FILE.equals(filePath.getScheme())) {
Log.w(LOG_TAG, "Uri " + filePath + " does not have a file scheme");
@@ -454,7 +458,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
}
if (!MbmsUtils.isContainedIn(
- MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo), tempFile)) {
+ MbmsUtils.getEmbmsTempFileDirForService(context, serviceId), tempFile)) {
return false;
}
diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java
index b28950ec758f..1e03fb9584b4 100644
--- a/telephony/java/android/telephony/mbms/MbmsUtils.java
+++ b/telephony/java/android/telephony/mbms/MbmsUtils.java
@@ -89,10 +89,9 @@ public class MbmsUtils {
/**
* Returns a File linked to the directory used to store temp files for this file service
*/
- public static File getEmbmsTempFileDirForService(Context context, FileServiceInfo serviceInfo) {
+ public static File getEmbmsTempFileDirForService(Context context, String serviceId) {
File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context);
- String tempFileDirName = String.valueOf(serviceInfo.getServiceId());
- return new File(embmsTempFileDir, tempFileDirName);
+ return new File(embmsTempFileDir, serviceId);
}
}