Loading telephony/java/android/telephony/MbmsDownloadManager.java +54 −14 Original line number Original line Diff line number Diff line Loading @@ -388,21 +388,10 @@ public class MbmsDownloadManager { tempRootDirectory.mkdirs(); tempRootDirectory.mkdirs(); setTempFileRootDirectory(tempRootDirectory); setTempFileRootDirectory(tempRootDirectory); } } request.setAppName(mDownloadAppName); request.setAppName(mDownloadAppName); // Check if the request is a multipart download. If so, validate that the destination is // a directory that exists. checkValidDownloadDestination(request); // TODO: figure out what qualifies a request as a multipart download request. writeDownloadRequestToken(request); if (request.getSourceUri().getLastPathSegment() != null && request.getSourceUri().getLastPathSegment().contains("*")) { File toFile = new File(request.getDestinationUri().getSchemeSpecificPart()); if (!toFile.isDirectory()) { throw new IllegalArgumentException("Multipart download must specify valid " + "destination directory."); } } // TODO: check to make sure destination is clear // TODO: write download request token try { try { downloadService.download(request, callback); downloadService.download(request, callback); } catch (RemoteException e) { } catch (RemoteException e) { Loading Loading @@ -435,6 +424,7 @@ public class MbmsDownloadManager { * <li>ERROR_MSDC_UNKNOWN_REQUEST</li> * <li>ERROR_MSDC_UNKNOWN_REQUEST</li> */ */ public int cancelDownload(DownloadRequest downloadRequest) { public int cancelDownload(DownloadRequest downloadRequest) { // TODO: don't forget to delete the token return 0; return 0; } } Loading Loading @@ -518,4 +508,54 @@ public class MbmsDownloadManager { Log.i(LOG_TAG, "Remote exception while disposing of service"); Log.i(LOG_TAG, "Remote exception while disposing of service"); } } } } private void writeDownloadRequestToken(DownloadRequest request) { // TODO: figure out when this token eventually gets deleted File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForRequest(mContext, request); if (!tempFileLocation.exists()) { tempFileLocation.mkdirs(); } String downloadTokenFileName = request.getHash() + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX; File token = new File(tempFileLocation, downloadTokenFileName); if (token.exists()) { Log.w(LOG_TAG, "Download token " + downloadTokenFileName + " already exists"); return; } try { if (!token.createNewFile()) { throw new RuntimeException("Failed to create download token for request " + request); } } catch (IOException e) { throw new RuntimeException("Failed to create download token for request " + request + " due to IOException " + e); } } /** * Verifies the following: * If a request is multi-part, * 1. Destination Uri must exist and be a directory * 2. Directory specified must contain no files. * Otherwise * 1. The file specified by the destination Uri must not exist. */ private void checkValidDownloadDestination(DownloadRequest request) { File toFile = new File(request.getDestinationUri().getSchemeSpecificPart()); if (request.isMultipartDownload()) { if (!toFile.isDirectory()) { throw new IllegalArgumentException("Multipart download must specify valid " + "destination directory."); } if (toFile.listFiles().length > 0) { throw new IllegalArgumentException("Destination directory must be clear of all " + "files."); } } else { if (toFile.exists()) { throw new IllegalArgumentException("Destination file must not exist."); } } } } } telephony/java/android/telephony/mbms/DownloadRequest.java +55 −2 Original line number Original line Diff line number Diff line Loading @@ -20,15 +20,22 @@ import android.content.Intent; import android.net.Uri; import android.net.Uri; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.util.Base64; import java.lang.IllegalStateException; import java.lang.IllegalStateException; import java.net.URISyntaxException; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** /** * A Parcelable class describing a pending Cell-Broadcast download request * A Parcelable class describing a pending Cell-Broadcast download request * @hide * @hide */ */ public class DownloadRequest implements Parcelable { public class DownloadRequest implements Parcelable { // Version code used to keep token calculation consistent. private static final int CURRENT_VERSION = 1; /** @hide */ /** @hide */ public static class Builder { public static class Builder { private int id; private int id; Loading @@ -37,6 +44,7 @@ public class DownloadRequest implements Parcelable { private Uri dest; private Uri dest; private int subscriptionId; private int subscriptionId; private String appIntent; private String appIntent; private int version = CURRENT_VERSION; public Builder setId(int id) { public Builder setId(int id) { this.id = id; this.id = id; Loading Loading @@ -68,9 +76,14 @@ public class DownloadRequest implements Parcelable { return this; return this; } } public Builder setVersion(int version) { this.version = version; return this; } public DownloadRequest build() { public DownloadRequest build() { return new DownloadRequest(id, serviceInfo, source, dest, return new DownloadRequest(id, serviceInfo, source, dest, subscriptionId, appIntent, null); subscriptionId, appIntent, null, version); } } } } Loading @@ -80,11 +93,12 @@ public class DownloadRequest implements Parcelable { private final Uri destinationUri; private final Uri destinationUri; private final int subscriptionId; private final int subscriptionId; private final String serializedResultIntentForApp; private final String serializedResultIntentForApp; private final int version; private String appName; // not the Android app Name, the embms app name private String appName; // not the Android app Name, the embms app name private DownloadRequest(int id, FileServiceInfo serviceInfo, private DownloadRequest(int id, FileServiceInfo serviceInfo, Uri source, Uri dest, Uri source, Uri dest, int sub, String appIntent, String name) { int sub, String appIntent, String name, int version) { downloadId = id; downloadId = id; fileServiceInfo = serviceInfo; fileServiceInfo = serviceInfo; sourceUri = source; sourceUri = source; Loading @@ -92,6 +106,7 @@ public class DownloadRequest implements Parcelable { subscriptionId = sub; subscriptionId = sub; serializedResultIntentForApp = appIntent; serializedResultIntentForApp = appIntent; appName = name; appName = name; this.version = version; } } public static DownloadRequest copy(DownloadRequest other) { public static DownloadRequest copy(DownloadRequest other) { Loading @@ -106,6 +121,7 @@ public class DownloadRequest implements Parcelable { subscriptionId = dr.subscriptionId; subscriptionId = dr.subscriptionId; serializedResultIntentForApp = dr.serializedResultIntentForApp; serializedResultIntentForApp = dr.serializedResultIntentForApp; appName = dr.appName; appName = dr.appName; version = dr.version; } } private DownloadRequest(Parcel in) { private DownloadRequest(Parcel in) { Loading @@ -116,6 +132,7 @@ public class DownloadRequest implements Parcelable { subscriptionId = in.readInt(); subscriptionId = in.readInt(); serializedResultIntentForApp = in.readString(); serializedResultIntentForApp = in.readString(); appName = in.readString(); appName = in.readString(); version = in.readInt(); } } public int describeContents() { public int describeContents() { Loading @@ -130,6 +147,7 @@ public class DownloadRequest implements Parcelable { out.writeInt(subscriptionId); out.writeInt(subscriptionId); out.writeString(serializedResultIntentForApp); out.writeString(serializedResultIntentForApp); out.writeString(appName); out.writeString(appName); out.writeInt(version); } } public int getDownloadId() { public int getDownloadId() { Loading Loading @@ -172,6 +190,10 @@ public class DownloadRequest implements Parcelable { return appName; return appName; } } public int getVersion() { return version; } public static final Parcelable.Creator<DownloadRequest> CREATOR = public static final Parcelable.Creator<DownloadRequest> CREATOR = new Parcelable.Creator<DownloadRequest>() { new Parcelable.Creator<DownloadRequest>() { public DownloadRequest createFromParcel(Parcel in) { public DownloadRequest createFromParcel(Parcel in) { Loading @@ -181,4 +203,35 @@ public class DownloadRequest implements Parcelable { return new DownloadRequest[size]; return new DownloadRequest[size]; } } }; }; /** * @hide */ public boolean isMultipartDownload() { // TODO: figure out what qualifies a request as a multipart download request. return getSourceUri().getLastPathSegment() != null && getSourceUri().getLastPathSegment().contains("*"); } /** * Retrieves the hash string that should be used as the filename when storing a token for * this DownloadRequest. * @hide */ public String getHash() { MessageDigest digest; try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Could not get sha256 hash object"); } if (version >= 1) { // Hash the source URI, destination URI, and the app intent digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8)); digest.update(destinationUri.toString().getBytes(StandardCharsets.UTF_8)); digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8)); } // Add updates for future versions here return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP); } } } telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +17 −17 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import java.util.UUID; public class MbmsDownloadReceiver extends BroadcastReceiver { public class MbmsDownloadReceiver extends BroadcastReceiver { private static final String LOG_TAG = "MbmsDownloadReceiver"; private static final String LOG_TAG = "MbmsDownloadReceiver"; private static final String TEMP_FILE_SUFFIX = ".embms.temp"; private static final String TEMP_FILE_SUFFIX = ".embms.temp"; public static final String DOWNLOAD_TOKEN_SUFFIX = ".download_token"; private static final int MAX_TEMP_FILE_RETRIES = 5; private static final int MAX_TEMP_FILE_RETRIES = 5; public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority"; public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority"; Loading @@ -50,7 +51,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { if (!verifyIntentContents(intent)) { if (!verifyIntentContents(context, intent)) { setResultCode(1 /* TODO: define error constants */); setResultCode(1 /* TODO: define error constants */); return; return; } } Loading @@ -69,7 +70,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { // TODO: Add handling for ACTION_CLEANUP // TODO: Add handling for ACTION_CLEANUP } } private boolean verifyIntentContents(Intent intent) { private boolean verifyIntentContents(Context context, Intent intent) { if (MbmsDownloadManager.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { if (MbmsDownloadManager.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."); Loading @@ -93,8 +94,19 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { "temp file. Ignoring."); "temp file. Ignoring."); return false; return false; } } DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX; File expectedTokenFile = new File( MbmsUtils.getEmbmsTempFileDirForRequest(context, request), expectedTokenFileName); if (!expectedTokenFile.exists()) { Log.w(LOG_TAG, "Supplied download request does not match a token that we have. " + "Expected " + expectedTokenFile); return false; } return true; return true; } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { // TODO: get rid of the request argument for a file descriptor request. if (!intent.hasExtra(MbmsDownloadManager.EXTRA_REQUEST)) { if (!intent.hasExtra(MbmsDownloadManager.EXTRA_REQUEST)) { Log.w(LOG_TAG, "Temp file request not include the associated request. Ignoring."); Log.w(LOG_TAG, "Temp file request not include the associated request. Ignoring."); return false; return false; Loading @@ -112,7 +124,6 @@ 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(MbmsDownloadManager.EXTRA_REQUEST); // TODO: check request against token Intent intentForApp = request.getIntentForApp(); Intent intentForApp = request.getIntentForApp(); int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT, int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT, Loading Loading @@ -149,7 +160,6 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } } private void cleanupPostMove(Context context, Intent intent) { private void cleanupPostMove(Context context, Intent intent) { // TODO: account for in-use temp files DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.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."); Loading Loading @@ -199,7 +209,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { private ArrayList<UriPathPair> generateFreshTempFiles(Context context, DownloadRequest request, private ArrayList<UriPathPair> generateFreshTempFiles(Context context, DownloadRequest request, int freshFdCount) { int freshFdCount) { File tempFileDir = getEmbmsTempFileDirForRequest(context, request); File tempFileDir = MbmsUtils.getEmbmsTempFileDirForRequest(context, request); if (!tempFileDir.exists()) { if (!tempFileDir.exists()) { tempFileDir.mkdirs(); tempFileDir.mkdirs(); } } Loading Loading @@ -345,24 +355,14 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return false; return false; } } if (!MbmsUtils.isContainedIn(getEmbmsTempFileDirForRequest(context, request), tempFile)) { if (!MbmsUtils.isContainedIn( MbmsUtils.getEmbmsTempFileDirForRequest(context, request), tempFile)) { return false; return false; } } return true; return true; } } /** * Returns a File linked to the directory used to store temp files for this request */ private static File getEmbmsTempFileDirForRequest(Context context, DownloadRequest request) { File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context); // TODO: better naming scheme for temp file dirs String tempFileDirName = String.valueOf(request.getFileServiceInfo().getServiceId()); return new File(embmsTempFileDir, tempFileDirName); } private String getFileProviderAuthorityCached(Context context) { private String getFileProviderAuthorityCached(Context context) { if (mFileProviderAuthorityCache != null) { if (mFileProviderAuthorityCache != null) { return mFileProviderAuthorityCache; return mFileProviderAuthorityCache; Loading telephony/java/android/telephony/mbms/MbmsUtils.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -85,4 +85,14 @@ public class MbmsUtils { context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE); context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE); } } /** * Returns a File linked to the directory used to store temp files for this request */ public static File getEmbmsTempFileDirForRequest(Context context, DownloadRequest request) { File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context); String tempFileDirName = String.valueOf(request.getFileServiceInfo().getServiceId()); return new File(embmsTempFileDir, tempFileDirName); } } } Loading
telephony/java/android/telephony/MbmsDownloadManager.java +54 −14 Original line number Original line Diff line number Diff line Loading @@ -388,21 +388,10 @@ public class MbmsDownloadManager { tempRootDirectory.mkdirs(); tempRootDirectory.mkdirs(); setTempFileRootDirectory(tempRootDirectory); setTempFileRootDirectory(tempRootDirectory); } } request.setAppName(mDownloadAppName); request.setAppName(mDownloadAppName); // Check if the request is a multipart download. If so, validate that the destination is // a directory that exists. checkValidDownloadDestination(request); // TODO: figure out what qualifies a request as a multipart download request. writeDownloadRequestToken(request); if (request.getSourceUri().getLastPathSegment() != null && request.getSourceUri().getLastPathSegment().contains("*")) { File toFile = new File(request.getDestinationUri().getSchemeSpecificPart()); if (!toFile.isDirectory()) { throw new IllegalArgumentException("Multipart download must specify valid " + "destination directory."); } } // TODO: check to make sure destination is clear // TODO: write download request token try { try { downloadService.download(request, callback); downloadService.download(request, callback); } catch (RemoteException e) { } catch (RemoteException e) { Loading Loading @@ -435,6 +424,7 @@ public class MbmsDownloadManager { * <li>ERROR_MSDC_UNKNOWN_REQUEST</li> * <li>ERROR_MSDC_UNKNOWN_REQUEST</li> */ */ public int cancelDownload(DownloadRequest downloadRequest) { public int cancelDownload(DownloadRequest downloadRequest) { // TODO: don't forget to delete the token return 0; return 0; } } Loading Loading @@ -518,4 +508,54 @@ public class MbmsDownloadManager { Log.i(LOG_TAG, "Remote exception while disposing of service"); Log.i(LOG_TAG, "Remote exception while disposing of service"); } } } } private void writeDownloadRequestToken(DownloadRequest request) { // TODO: figure out when this token eventually gets deleted File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForRequest(mContext, request); if (!tempFileLocation.exists()) { tempFileLocation.mkdirs(); } String downloadTokenFileName = request.getHash() + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX; File token = new File(tempFileLocation, downloadTokenFileName); if (token.exists()) { Log.w(LOG_TAG, "Download token " + downloadTokenFileName + " already exists"); return; } try { if (!token.createNewFile()) { throw new RuntimeException("Failed to create download token for request " + request); } } catch (IOException e) { throw new RuntimeException("Failed to create download token for request " + request + " due to IOException " + e); } } /** * Verifies the following: * If a request is multi-part, * 1. Destination Uri must exist and be a directory * 2. Directory specified must contain no files. * Otherwise * 1. The file specified by the destination Uri must not exist. */ private void checkValidDownloadDestination(DownloadRequest request) { File toFile = new File(request.getDestinationUri().getSchemeSpecificPart()); if (request.isMultipartDownload()) { if (!toFile.isDirectory()) { throw new IllegalArgumentException("Multipart download must specify valid " + "destination directory."); } if (toFile.listFiles().length > 0) { throw new IllegalArgumentException("Destination directory must be clear of all " + "files."); } } else { if (toFile.exists()) { throw new IllegalArgumentException("Destination file must not exist."); } } } } }
telephony/java/android/telephony/mbms/DownloadRequest.java +55 −2 Original line number Original line Diff line number Diff line Loading @@ -20,15 +20,22 @@ import android.content.Intent; import android.net.Uri; import android.net.Uri; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.util.Base64; import java.lang.IllegalStateException; import java.lang.IllegalStateException; import java.net.URISyntaxException; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** /** * A Parcelable class describing a pending Cell-Broadcast download request * A Parcelable class describing a pending Cell-Broadcast download request * @hide * @hide */ */ public class DownloadRequest implements Parcelable { public class DownloadRequest implements Parcelable { // Version code used to keep token calculation consistent. private static final int CURRENT_VERSION = 1; /** @hide */ /** @hide */ public static class Builder { public static class Builder { private int id; private int id; Loading @@ -37,6 +44,7 @@ public class DownloadRequest implements Parcelable { private Uri dest; private Uri dest; private int subscriptionId; private int subscriptionId; private String appIntent; private String appIntent; private int version = CURRENT_VERSION; public Builder setId(int id) { public Builder setId(int id) { this.id = id; this.id = id; Loading Loading @@ -68,9 +76,14 @@ public class DownloadRequest implements Parcelable { return this; return this; } } public Builder setVersion(int version) { this.version = version; return this; } public DownloadRequest build() { public DownloadRequest build() { return new DownloadRequest(id, serviceInfo, source, dest, return new DownloadRequest(id, serviceInfo, source, dest, subscriptionId, appIntent, null); subscriptionId, appIntent, null, version); } } } } Loading @@ -80,11 +93,12 @@ public class DownloadRequest implements Parcelable { private final Uri destinationUri; private final Uri destinationUri; private final int subscriptionId; private final int subscriptionId; private final String serializedResultIntentForApp; private final String serializedResultIntentForApp; private final int version; private String appName; // not the Android app Name, the embms app name private String appName; // not the Android app Name, the embms app name private DownloadRequest(int id, FileServiceInfo serviceInfo, private DownloadRequest(int id, FileServiceInfo serviceInfo, Uri source, Uri dest, Uri source, Uri dest, int sub, String appIntent, String name) { int sub, String appIntent, String name, int version) { downloadId = id; downloadId = id; fileServiceInfo = serviceInfo; fileServiceInfo = serviceInfo; sourceUri = source; sourceUri = source; Loading @@ -92,6 +106,7 @@ public class DownloadRequest implements Parcelable { subscriptionId = sub; subscriptionId = sub; serializedResultIntentForApp = appIntent; serializedResultIntentForApp = appIntent; appName = name; appName = name; this.version = version; } } public static DownloadRequest copy(DownloadRequest other) { public static DownloadRequest copy(DownloadRequest other) { Loading @@ -106,6 +121,7 @@ public class DownloadRequest implements Parcelable { subscriptionId = dr.subscriptionId; subscriptionId = dr.subscriptionId; serializedResultIntentForApp = dr.serializedResultIntentForApp; serializedResultIntentForApp = dr.serializedResultIntentForApp; appName = dr.appName; appName = dr.appName; version = dr.version; } } private DownloadRequest(Parcel in) { private DownloadRequest(Parcel in) { Loading @@ -116,6 +132,7 @@ public class DownloadRequest implements Parcelable { subscriptionId = in.readInt(); subscriptionId = in.readInt(); serializedResultIntentForApp = in.readString(); serializedResultIntentForApp = in.readString(); appName = in.readString(); appName = in.readString(); version = in.readInt(); } } public int describeContents() { public int describeContents() { Loading @@ -130,6 +147,7 @@ public class DownloadRequest implements Parcelable { out.writeInt(subscriptionId); out.writeInt(subscriptionId); out.writeString(serializedResultIntentForApp); out.writeString(serializedResultIntentForApp); out.writeString(appName); out.writeString(appName); out.writeInt(version); } } public int getDownloadId() { public int getDownloadId() { Loading Loading @@ -172,6 +190,10 @@ public class DownloadRequest implements Parcelable { return appName; return appName; } } public int getVersion() { return version; } public static final Parcelable.Creator<DownloadRequest> CREATOR = public static final Parcelable.Creator<DownloadRequest> CREATOR = new Parcelable.Creator<DownloadRequest>() { new Parcelable.Creator<DownloadRequest>() { public DownloadRequest createFromParcel(Parcel in) { public DownloadRequest createFromParcel(Parcel in) { Loading @@ -181,4 +203,35 @@ public class DownloadRequest implements Parcelable { return new DownloadRequest[size]; return new DownloadRequest[size]; } } }; }; /** * @hide */ public boolean isMultipartDownload() { // TODO: figure out what qualifies a request as a multipart download request. return getSourceUri().getLastPathSegment() != null && getSourceUri().getLastPathSegment().contains("*"); } /** * Retrieves the hash string that should be used as the filename when storing a token for * this DownloadRequest. * @hide */ public String getHash() { MessageDigest digest; try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Could not get sha256 hash object"); } if (version >= 1) { // Hash the source URI, destination URI, and the app intent digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8)); digest.update(destinationUri.toString().getBytes(StandardCharsets.UTF_8)); digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8)); } // Add updates for future versions here return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP); } } }
telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +17 −17 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import java.util.UUID; public class MbmsDownloadReceiver extends BroadcastReceiver { public class MbmsDownloadReceiver extends BroadcastReceiver { private static final String LOG_TAG = "MbmsDownloadReceiver"; private static final String LOG_TAG = "MbmsDownloadReceiver"; private static final String TEMP_FILE_SUFFIX = ".embms.temp"; private static final String TEMP_FILE_SUFFIX = ".embms.temp"; public static final String DOWNLOAD_TOKEN_SUFFIX = ".download_token"; private static final int MAX_TEMP_FILE_RETRIES = 5; private static final int MAX_TEMP_FILE_RETRIES = 5; public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority"; public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority"; Loading @@ -50,7 +51,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { if (!verifyIntentContents(intent)) { if (!verifyIntentContents(context, intent)) { setResultCode(1 /* TODO: define error constants */); setResultCode(1 /* TODO: define error constants */); return; return; } } Loading @@ -69,7 +70,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { // TODO: Add handling for ACTION_CLEANUP // TODO: Add handling for ACTION_CLEANUP } } private boolean verifyIntentContents(Intent intent) { private boolean verifyIntentContents(Context context, Intent intent) { if (MbmsDownloadManager.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) { if (MbmsDownloadManager.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."); Loading @@ -93,8 +94,19 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { "temp file. Ignoring."); "temp file. Ignoring."); return false; return false; } } DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX; File expectedTokenFile = new File( MbmsUtils.getEmbmsTempFileDirForRequest(context, request), expectedTokenFileName); if (!expectedTokenFile.exists()) { Log.w(LOG_TAG, "Supplied download request does not match a token that we have. " + "Expected " + expectedTokenFile); return false; } return true; return true; } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) { // TODO: get rid of the request argument for a file descriptor request. if (!intent.hasExtra(MbmsDownloadManager.EXTRA_REQUEST)) { if (!intent.hasExtra(MbmsDownloadManager.EXTRA_REQUEST)) { Log.w(LOG_TAG, "Temp file request not include the associated request. Ignoring."); Log.w(LOG_TAG, "Temp file request not include the associated request. Ignoring."); return false; return false; Loading @@ -112,7 +124,6 @@ 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(MbmsDownloadManager.EXTRA_REQUEST); // TODO: check request against token Intent intentForApp = request.getIntentForApp(); Intent intentForApp = request.getIntentForApp(); int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT, int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT, Loading Loading @@ -149,7 +160,6 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } } private void cleanupPostMove(Context context, Intent intent) { private void cleanupPostMove(Context context, Intent intent) { // TODO: account for in-use temp files DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST); DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.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."); Loading Loading @@ -199,7 +209,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { private ArrayList<UriPathPair> generateFreshTempFiles(Context context, DownloadRequest request, private ArrayList<UriPathPair> generateFreshTempFiles(Context context, DownloadRequest request, int freshFdCount) { int freshFdCount) { File tempFileDir = getEmbmsTempFileDirForRequest(context, request); File tempFileDir = MbmsUtils.getEmbmsTempFileDirForRequest(context, request); if (!tempFileDir.exists()) { if (!tempFileDir.exists()) { tempFileDir.mkdirs(); tempFileDir.mkdirs(); } } Loading Loading @@ -345,24 +355,14 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return false; return false; } } if (!MbmsUtils.isContainedIn(getEmbmsTempFileDirForRequest(context, request), tempFile)) { if (!MbmsUtils.isContainedIn( MbmsUtils.getEmbmsTempFileDirForRequest(context, request), tempFile)) { return false; return false; } } return true; return true; } } /** * Returns a File linked to the directory used to store temp files for this request */ private static File getEmbmsTempFileDirForRequest(Context context, DownloadRequest request) { File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context); // TODO: better naming scheme for temp file dirs String tempFileDirName = String.valueOf(request.getFileServiceInfo().getServiceId()); return new File(embmsTempFileDir, tempFileDirName); } private String getFileProviderAuthorityCached(Context context) { private String getFileProviderAuthorityCached(Context context) { if (mFileProviderAuthorityCache != null) { if (mFileProviderAuthorityCache != null) { return mFileProviderAuthorityCache; return mFileProviderAuthorityCache; Loading
telephony/java/android/telephony/mbms/MbmsUtils.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -85,4 +85,14 @@ public class MbmsUtils { context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE); context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE); } } /** * Returns a File linked to the directory used to store temp files for this request */ public static File getEmbmsTempFileDirForRequest(Context context, DownloadRequest request) { File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context); String tempFileDirName = String.valueOf(request.getFileServiceInfo().getServiceId()); return new File(embmsTempFileDir, tempFileDirName); } } }