Merge "API council suggested edits, part 3"
diff --git a/api/current.txt b/api/current.txt
index 8fc70fa..e1edb04 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -39766,6 +39766,7 @@
     method public void unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback);
     field public static final java.lang.String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
     field public static final java.lang.String EXTRA_MBMS_COMPLETED_FILE_URI = "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_REQUEST = "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
     field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
     field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
     field public static final int RESULT_CANCELLED = 2; // 0x2
@@ -40421,7 +40422,6 @@
   public final class DownloadRequest implements android.os.Parcelable {
     method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
     method public int describeContents();
-    method public android.net.Uri getDestinationUri();
     method public java.lang.String getFileServiceId();
     method public static int getMaxAppIntentSize();
     method public static int getMaxDestinationUriSize();
@@ -40435,7 +40435,6 @@
     ctor public DownloadRequest.Builder();
     method public android.telephony.mbms.DownloadRequest build();
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
-    method public android.telephony.mbms.DownloadRequest.Builder setDest(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
     method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
@@ -40474,20 +40473,19 @@
     method public void onMiddlewareReady();
   }
 
-  public class MbmsException extends java.lang.Exception {
-    method public int getErrorCode();
+  public class MbmsErrors {
     field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3
     field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
     field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
     field public static final int SUCCESS = 0; // 0x0
   }
 
-  public static class MbmsException.DownloadErrors {
+  public static class MbmsErrors.DownloadErrors {
     field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
     field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
   }
 
-  public static class MbmsException.GeneralErrors {
+  public static class MbmsErrors.GeneralErrors {
     field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf
     field public static final int ERROR_IN_E911 = 204; // 0xcc
     field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9
@@ -40497,13 +40495,13 @@
     field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce
   }
 
-  public static class MbmsException.InitializationErrors {
+  public static class MbmsErrors.InitializationErrors {
     field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66
     field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65
     field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67
   }
 
-  public static class MbmsException.StreamingErrors {
+  public static class MbmsErrors.StreamingErrors {
     field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d
     field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
diff --git a/api/system-current.txt b/api/system-current.txt
index 5d1c754..c70b790 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -43195,6 +43195,7 @@
     method public void unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback);
     field public static final java.lang.String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
     field public static final java.lang.String EXTRA_MBMS_COMPLETED_FILE_URI = "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_REQUEST = "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
     field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
     field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
     field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
@@ -43935,7 +43936,6 @@
   public final class DownloadRequest implements android.os.Parcelable {
     method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
     method public int describeContents();
-    method public android.net.Uri getDestinationUri();
     method public java.lang.String getFileServiceId();
     method public static int getMaxAppIntentSize();
     method public static int getMaxDestinationUriSize();
@@ -43950,7 +43950,6 @@
     ctor public DownloadRequest.Builder();
     method public android.telephony.mbms.DownloadRequest build();
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
-    method public android.telephony.mbms.DownloadRequest.Builder setDest(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setOpaqueData(byte[]);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceId(java.lang.String);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
@@ -43984,6 +43983,7 @@
   public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
     ctor public MbmsDownloadReceiver();
     method public void onReceive(android.content.Context, android.content.Intent);
+    field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6
     field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3
     field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4
     field public static final int RESULT_INVALID_ACTION = 1; // 0x1
@@ -43999,20 +43999,19 @@
     method public void onMiddlewareReady();
   }
 
-  public class MbmsException extends java.lang.Exception {
-    method public int getErrorCode();
+  public class MbmsErrors {
     field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3
     field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
     field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
     field public static final int SUCCESS = 0; // 0x0
   }
 
-  public static class MbmsException.DownloadErrors {
+  public static class MbmsErrors.DownloadErrors {
     field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
     field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
   }
 
-  public static class MbmsException.GeneralErrors {
+  public static class MbmsErrors.GeneralErrors {
     field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf
     field public static final int ERROR_IN_E911 = 204; // 0xcc
     field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9
@@ -44022,13 +44021,13 @@
     field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce
   }
 
-  public static class MbmsException.InitializationErrors {
+  public static class MbmsErrors.InitializationErrors {
     field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66
     field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65
     field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67
   }
 
-  public static class MbmsException.StreamingErrors {
+  public static class MbmsErrors.StreamingErrors {
     field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d
     field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
@@ -44135,7 +44134,6 @@
     field public static final java.lang.String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
     field public static final java.lang.String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
     field public static final java.lang.String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
-    field public static final java.lang.String EXTRA_REQUEST = "android.telephony.mbms.extra.REQUEST";
     field public static final java.lang.String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
     field public static final java.lang.String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
     field public static final java.lang.String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
diff --git a/api/test-current.txt b/api/test-current.txt
index c9eb0c2..728e857 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -39988,6 +39988,7 @@
     method public void unregisterStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback);
     field public static final java.lang.String DEFAULT_TOP_LEVEL_TEMP_DIRECTORY = "androidMbmsTempFileRoot";
     field public static final java.lang.String EXTRA_MBMS_COMPLETED_FILE_URI = "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
+    field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_REQUEST = "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
     field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT";
     field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO";
     field public static final int RESULT_CANCELLED = 2; // 0x2
@@ -40643,7 +40644,6 @@
   public final class DownloadRequest implements android.os.Parcelable {
     method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
     method public int describeContents();
-    method public android.net.Uri getDestinationUri();
     method public java.lang.String getFileServiceId();
     method public static int getMaxAppIntentSize();
     method public static int getMaxDestinationUriSize();
@@ -40657,7 +40657,6 @@
     ctor public DownloadRequest.Builder();
     method public android.telephony.mbms.DownloadRequest build();
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
-    method public android.telephony.mbms.DownloadRequest.Builder setDest(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
     method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri);
     method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
@@ -40696,20 +40695,19 @@
     method public void onMiddlewareReady();
   }
 
-  public class MbmsException extends java.lang.Exception {
-    method public int getErrorCode();
+  public class MbmsErrors {
     field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3
     field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
     field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
     field public static final int SUCCESS = 0; // 0x0
   }
 
-  public static class MbmsException.DownloadErrors {
+  public static class MbmsErrors.DownloadErrors {
     field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
     field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
   }
 
-  public static class MbmsException.GeneralErrors {
+  public static class MbmsErrors.GeneralErrors {
     field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf
     field public static final int ERROR_IN_E911 = 204; // 0xcc
     field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9
@@ -40719,13 +40717,13 @@
     field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce
   }
 
-  public static class MbmsException.InitializationErrors {
+  public static class MbmsErrors.InitializationErrors {
     field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66
     field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65
     field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67
   }
 
-  public static class MbmsException.StreamingErrors {
+  public static class MbmsErrors.StreamingErrors {
     field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d
     field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f
     field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index f991c5e..ebac041 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -38,7 +38,7 @@
 import android.telephony.mbms.InternalDownloadStateCallback;
 import android.telephony.mbms.MbmsDownloadSessionCallback;
 import android.telephony.mbms.MbmsDownloadReceiver;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsErrors;
 import android.telephony.mbms.MbmsTempFileProvider;
 import android.telephony.mbms.MbmsUtils;
 import android.telephony.mbms.vendor.IMbmsDownloadService;
@@ -97,14 +97,26 @@
     /**
      * {@link Uri} extra that Android will attach to the intent supplied via
      * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
-     * Indicates the location of the successfully
-     * downloaded file. Will always be set to a non-null value if
+     * Indicates the location of the successfully downloaded file within the temp file root set
+     * via {@link #setTempFileRootDirectory(File)}.
+     * While you may use this file in-place, it is highly encouraged that you move
+     * this file to a different location after receiving the download completion intent, as this
+     * file resides within the temp file directory.
+     *
+     * Will always be set to a non-null value if
      * {@link #EXTRA_MBMS_DOWNLOAD_RESULT} is set to {@link #RESULT_SUCCESSFUL}.
      */
     public static final String EXTRA_MBMS_COMPLETED_FILE_URI =
             "android.telephony.extra.MBMS_COMPLETED_FILE_URI";
 
     /**
+     * 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_MBMS_DOWNLOAD_REQUEST =
+            "android.telephony.extra.MBMS_DOWNLOAD_REQUEST";
+
+    /**
      * The default directory name for all MBMS temp files. If you call
      * {@link #download(DownloadRequest)} without first calling
      * {@link #setTempFileRootDirectory(File)}, this directory will be created for you under the
@@ -175,7 +187,7 @@
     private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
         @Override
         public void binderDied() {
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, "Received death notification");
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, "Received death notification");
         }
     };
 
@@ -242,7 +254,7 @@
         MbmsDownloadSession session =
                 new MbmsDownloadSession(context, callback, subscriptionId, handler);
         final int result = session.bindAndInitialize();
-        if (result != MbmsException.SUCCESS) {
+        if (result != MbmsErrors.SUCCESS) {
             sIsInitialized.set(false);
             handler.post(new Runnable() {
                 @Override
@@ -272,12 +284,12 @@
                         } catch (RuntimeException e) {
                             Log.e(LOG_TAG, "Runtime exception during initialization");
                             sendErrorToApp(
-                                    MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
                                     e.toString());
                             sIsInitialized.set(false);
                             return;
                         }
-                        if (result != MbmsException.SUCCESS) {
+                        if (result != MbmsErrors.SUCCESS) {
                             sendErrorToApp(result, "Error returned during initialization");
                             sIsInitialized.set(false);
                             return;
@@ -285,7 +297,7 @@
                         try {
                             downloadService.asBinder().linkToDeath(mDeathRecipient, 0);
                         } catch (RemoteException e) {
-                            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST,
+                            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
                                     "Middleware lost during initialization");
                             sIsInitialized.set(false);
                             return;
@@ -327,13 +339,13 @@
         }
         try {
             int returnCode = downloadService.requestUpdateFileServices(mSubscriptionId, classList);
-            if (returnCode != MbmsException.SUCCESS) {
+            if (returnCode != MbmsErrors.SUCCESS) {
                 sendErrorToApp(returnCode, null);
             }
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Remote process died");
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
         }
     }
 
@@ -352,7 +364,7 @@
      * Before calling this method, the app must cancel all of its pending
      * {@link DownloadRequest}s via {@link #cancelDownload(DownloadRequest)}. If this is not done,
      * you will receive an asynchronous error with code
-     * {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} unless the
+     * {@link MbmsErrors.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
@@ -381,12 +393,12 @@
 
         try {
             int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath);
-            if (result != MbmsException.SUCCESS) {
+            if (result != MbmsErrors.SUCCESS) {
                 sendErrorToApp(result, null);
             }
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return;
         }
 
@@ -464,13 +476,12 @@
             setTempFileRootDirectory(tempRootDirectory);
         }
 
-        checkValidDownloadDestination(request);
         writeDownloadRequestToken(request);
         try {
             downloadService.download(request);
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
         }
     }
 
@@ -491,7 +502,7 @@
             return downloadService.listPendingDownloads(mSubscriptionId);
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return Collections.emptyList();
         }
     }
@@ -523,8 +534,8 @@
 
         try {
             int result = downloadService.registerStateCallback(request, internalCallback);
-            if (result != MbmsException.SUCCESS) {
-                if (result == MbmsException.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+            if (result != MbmsErrors.SUCCESS) {
+                if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
                     throw new IllegalArgumentException("Unknown download request.");
                 }
                 sendErrorToApp(result, null);
@@ -532,7 +543,7 @@
             }
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return;
         }
         mInternalDownloadCallbacks.put(callback, internalCallback);
@@ -563,15 +574,15 @@
 
             try {
                 int result = downloadService.unregisterStateCallback(request, internalCallback);
-                if (result != MbmsException.SUCCESS) {
-                    if (result == MbmsException.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+                if (result != MbmsErrors.SUCCESS) {
+                    if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
                         throw new IllegalArgumentException("Unknown download request.");
                     }
                     sendErrorToApp(result, null);
                 }
             } catch (RemoteException e) {
                 mService.set(null);
-                sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+                sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             }
         } finally {
             InternalDownloadStateCallback internalCallback =
@@ -598,8 +609,8 @@
 
         try {
             int result = downloadService.cancelDownload(downloadRequest);
-            if (result != MbmsException.SUCCESS) {
-                if (result == MbmsException.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+            if (result != MbmsErrors.SUCCESS) {
+                if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
                     throw new IllegalArgumentException("Unknown download request.");
                 }
                 sendErrorToApp(result, null);
@@ -607,7 +618,7 @@
             }
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return;
         }
         deleteDownloadRequestToken(downloadRequest);
@@ -635,7 +646,7 @@
             return downloadService.getDownloadStatus(downloadRequest, fileInfo);
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return STATUS_UNKNOWN;
         }
     }
@@ -668,15 +679,15 @@
 
         try {
             int result = downloadService.resetDownloadKnowledge(downloadRequest);
-            if (result != MbmsException.SUCCESS) {
-                if (result == MbmsException.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+            if (result != MbmsErrors.SUCCESS) {
+                if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
                     throw new IllegalArgumentException("Unknown download request.");
                 }
                 sendErrorToApp(result, null);
             }
         } catch (RemoteException e) {
             mService.set(null);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
         }
     }
 
@@ -752,32 +763,6 @@
         return new File(tempFileLocation, downloadTokenFileName);
     }
 
-    /**
-     * 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.");
-            }
-        }
-    }
-
     private void sendErrorToApp(int errorCode, String message) {
         try {
             mInternalCallback.onError(errorCode, message);
diff --git a/telephony/java/android/telephony/MbmsStreamingSession.java b/telephony/java/android/telephony/MbmsStreamingSession.java
index 32dd532..a8c4607 100644
--- a/telephony/java/android/telephony/MbmsStreamingSession.java
+++ b/telephony/java/android/telephony/MbmsStreamingSession.java
@@ -29,7 +29,7 @@
 import android.os.RemoteException;
 import android.telephony.mbms.InternalStreamingSessionCallback;
 import android.telephony.mbms.InternalStreamingServiceCallback;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsErrors;
 import android.telephony.mbms.MbmsStreamingSessionCallback;
 import android.telephony.mbms.MbmsUtils;
 import android.telephony.mbms.StreamingService;
@@ -69,7 +69,7 @@
         @Override
         public void binderDied() {
             sIsInitialized.set(false);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, "Received death notification");
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, "Received death notification");
         }
     };
 
@@ -124,7 +124,7 @@
                 subscriptionId, handler);
 
         final int result = session.bindAndInitialize();
-        if (result != MbmsException.SUCCESS) {
+        if (result != MbmsErrors.SUCCESS) {
             sIsInitialized.set(false);
             handler.post(new Runnable() {
                 @Override
@@ -203,14 +203,14 @@
         try {
             int returnCode = streamingService.requestUpdateStreamingServices(
                     mSubscriptionId, serviceClassList);
-            if (returnCode != MbmsException.SUCCESS) {
+            if (returnCode != MbmsErrors.SUCCESS) {
                 sendErrorToApp(returnCode, null);
             }
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Remote process died");
             mService.set(null);
             sIsInitialized.set(false);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
         }
     }
 
@@ -224,8 +224,8 @@
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      *
      * Asynchronous errors through the callback include any of the errors in
-     * {@link android.telephony.mbms.MbmsException.GeneralErrors} or
-     * {@link android.telephony.mbms.MbmsException.StreamingErrors}.
+     * {@link MbmsErrors.GeneralErrors} or
+     * {@link MbmsErrors.StreamingErrors}.
      *
      * @param serviceInfo The information about the service to stream.
      * @param callback A callback that'll be called when something about the stream changes.
@@ -250,7 +250,7 @@
         try {
             int returnCode = streamingService.startStreaming(
                     mSubscriptionId, serviceInfo.getServiceId(), serviceCallback);
-            if (returnCode != MbmsException.SUCCESS) {
+            if (returnCode != MbmsErrors.SUCCESS) {
                 sendErrorToApp(returnCode, null);
                 return null;
             }
@@ -258,7 +258,7 @@
             Log.w(LOG_TAG, "Remote process died");
             mService.set(null);
             sIsInitialized.set(false);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return null;
         }
 
@@ -284,19 +284,19 @@
                         } catch (RemoteException e) {
                             Log.e(LOG_TAG, "Service died before initialization");
                             sendErrorToApp(
-                                    MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
                                     e.toString());
                             sIsInitialized.set(false);
                             return;
                         } catch (RuntimeException e) {
                             Log.e(LOG_TAG, "Runtime exception during initialization");
                             sendErrorToApp(
-                                    MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+                                    MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
                                     e.toString());
                             sIsInitialized.set(false);
                             return;
                         }
-                        if (result != MbmsException.SUCCESS) {
+                        if (result != MbmsErrors.SUCCESS) {
                             sendErrorToApp(result, "Error returned during initialization");
                             sIsInitialized.set(false);
                             return;
@@ -304,7 +304,7 @@
                         try {
                             streamingService.asBinder().linkToDeath(mDeathRecipient, 0);
                         } catch (RemoteException e) {
-                            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST,
+                            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
                                     "Middleware lost during initialization");
                             sIsInitialized.set(false);
                             return;
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index 268e1da..5a57f32 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -55,12 +55,10 @@
 
     /** @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;
+        public OpaqueDataContainer(String appIntent, int version) {
             this.appIntent = appIntent;
             this.version = version;
         }
@@ -69,7 +67,6 @@
     public static class Builder {
         private String fileServiceId;
         private Uri source;
-        private Uri dest;
         private int subscriptionId;
         private String appIntent;
         private int version = CURRENT_VERSION;
@@ -104,21 +101,6 @@
         }
 
         /**
-         * Sets the destination URI for the download request to be built. The middleware should
-         * not set this directly.
-         * @param dest A URI obtained from {@link Uri#fromFile(File)}, denoting the requested
-         *             final destination of the download.
-         */
-        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;
-        }
-
-        /**
          * Set the subscription ID on which the file(s) should be downloaded.
          * @param subscriptionId
          */
@@ -159,7 +141,6 @@
                 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");
@@ -172,24 +153,21 @@
         }
 
         public DownloadRequest build() {
-            return new DownloadRequest(fileServiceId, source, dest,
-                    subscriptionId, appIntent, version);
+            return new DownloadRequest(fileServiceId, source, subscriptionId, appIntent, version);
         }
     }
 
     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(String fileServiceId,
-            Uri source, Uri dest,
-            int sub, String appIntent, int version) {
+            Uri source, int sub,
+            String appIntent, int version) {
         this.fileServiceId = fileServiceId;
         sourceUri = source;
-        destinationUri = dest;
         subscriptionId = sub;
         serializedResultIntentForApp = appIntent;
         this.version = version;
@@ -202,7 +180,6 @@
     private DownloadRequest(DownloadRequest dr) {
         fileServiceId = dr.fileServiceId;
         sourceUri = dr.sourceUri;
-        destinationUri = dr.destinationUri;
         subscriptionId = dr.subscriptionId;
         serializedResultIntentForApp = dr.serializedResultIntentForApp;
         version = dr.version;
@@ -211,7 +188,6 @@
     private DownloadRequest(Parcel in) {
         fileServiceId = in.readString();
         sourceUri = in.readParcelable(getClass().getClassLoader());
-        destinationUri = in.readParcelable(getClass().getClassLoader());
         subscriptionId = in.readInt();
         serializedResultIntentForApp = in.readString();
         version = in.readInt();
@@ -224,7 +200,6 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(fileServiceId);
         out.writeParcelable(sourceUri, flags);
-        out.writeParcelable(destinationUri, flags);
         out.writeInt(subscriptionId);
         out.writeString(serializedResultIntentForApp);
         out.writeInt(version);
@@ -245,14 +220,6 @@
     }
 
     /**
-     * For use by the client app only.
-     * @return The URI of the final destination of the download.
-     */
-    public Uri getDestinationUri() {
-        return destinationUri;
-    }
-
-    /**
      * @return The subscription ID on which to perform MBMS operations.
      */
     public int getSubscriptionId() {
@@ -285,7 +252,7 @@
             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             ObjectOutputStream stream = new ObjectOutputStream(byteArrayOutputStream);
             OpaqueDataContainer container = new OpaqueDataContainer(
-                    destinationUri.toString(), serializedResultIntentForApp, version);
+                    serializedResultIntentForApp, version);
             stream.writeObject(container);
             stream.flush();
             return byteArrayOutputStream.toByteArray();
@@ -351,7 +318,6 @@
         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
@@ -372,13 +338,12 @@
                 version == request.version &&
                 Objects.equals(fileServiceId, request.fileServiceId) &&
                 Objects.equals(sourceUri, request.sourceUri) &&
-                Objects.equals(destinationUri, request.destinationUri) &&
                 Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fileServiceId, sourceUri, destinationUri,
+        return Objects.hash(fileServiceId, sourceUri,
                 subscriptionId, serializedResultIntentForApp, version);
     }
 }
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index 0a71921..61415b5 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -36,8 +36,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
@@ -114,8 +116,19 @@
     @SystemApi
     public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5;
 
+    /**
+     * Indicates that the manager was unable to notify the app of the completed download.
+     * This is a fatal result code and no result extras should be expected.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_APP_NOTIFICATION_ERROR = 6;
+
+
     private static final String LOG_TAG = "MbmsDownloadReceiver";
     private static final String TEMP_FILE_SUFFIX = ".embms.temp";
+    private static final String TEMP_FILE_STAGING_LOCATION = "staged_completed_files";
+
     private static final int MAX_TEMP_FILE_RETRIES = 5;
 
     private String mFileProviderAuthorityCache = null;
@@ -152,7 +165,7 @@
                 Log.w(LOG_TAG, "Download result did not include a result code. Ignoring.");
                 return false;
             }
-            if (!intent.hasExtra(VendorUtils.EXTRA_REQUEST)) {
+            if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)) {
                 Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring.");
                 return false;
             }
@@ -170,7 +183,8 @@
                         "temp file. Ignoring.");
                 return false;
             }
-            DownloadRequest request = intent.getParcelableExtra(VendorUtils.EXTRA_REQUEST);
+            DownloadRequest request = intent.getParcelableExtra(
+                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
             String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
             File expectedTokenFile = new File(
                     MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()),
@@ -210,8 +224,14 @@
     }
 
     private void moveDownloadedFile(Context context, Intent intent) {
-        DownloadRequest request = intent.getParcelableExtra(VendorUtils.EXTRA_REQUEST);
+        DownloadRequest request = intent.getParcelableExtra(
+                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
         Intent intentForApp = request.getIntentForApp();
+        if (intentForApp == null) {
+            Log.i(LOG_TAG, "Malformed app notification intent");
+            setResultCode(RESULT_APP_NOTIFICATION_ERROR);
+            return;
+        }
 
         int result = intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
                 MbmsDownloadSession.RESULT_CANCELLED);
@@ -223,7 +243,6 @@
             return;
         }
 
-        Uri destinationUri = request.getDestinationUri();
         Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI);
         if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) {
             Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
@@ -233,23 +252,30 @@
 
         FileInfo completedFileInfo =
                 (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
-        String relativePath = calculateDestinationFileRelativePath(request, completedFileInfo);
+        Path stagingDirectory = FileSystems.getDefault().getPath(
+                MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath(),
+                TEMP_FILE_STAGING_LOCATION);
 
-        Uri finalFileLocation = moveTempFile(finalTempFile, destinationUri, relativePath);
-        if (finalFileLocation == null) {
+        Uri stagedFileLocation;
+        try {
+            stagedFileLocation = stageTempFile(finalTempFile, stagingDirectory);
+        } catch (IOException e) {
             Log.w(LOG_TAG, "Failed to move temp file to final destination");
             setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
             return;
         }
-        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI, finalFileLocation);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI,
+                stagedFileLocation);
         intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, completedFileInfo);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
 
         context.sendBroadcast(intentForApp);
         setResultCode(RESULT_OK);
     }
 
     private void cleanupPostMove(Context context, Intent intent) {
-        DownloadRequest request = intent.getParcelableExtra(VendorUtils.EXTRA_REQUEST);
+        DownloadRequest request = intent.getParcelableExtra(
+                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
         if (request == null) {
             Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring.");
             return;
@@ -403,63 +429,22 @@
         }
     }
 
-    private static String calculateDestinationFileRelativePath(DownloadRequest request,
-            FileInfo info) {
-        List<String> filePathComponents = info.getUri().getPathSegments();
-        List<String> requestPathComponents = request.getSourceUri().getPathSegments();
-        Iterator<String> filePathIter = filePathComponents.iterator();
-        Iterator<String> requestPathIter = requestPathComponents.iterator();
-
-        StringBuilder pathBuilder = new StringBuilder();
-        // Iterate through the segments of the carrier's URI to the file, along with the segments
-        // of the source URI specified in the download request. The relative path is calculated
-        // as the tail of the file's URI that does not match the path segments in the source URI.
-        while (filePathIter.hasNext()) {
-            String currFilePathComponent = filePathIter.next();
-            if (requestPathIter.hasNext()) {
-                String requestFilePathComponent = requestPathIter.next();
-                if (requestFilePathComponent.equals(currFilePathComponent)) {
-                    continue;
-                }
-            }
-            pathBuilder.append(currFilePathComponent);
-            pathBuilder.append('/');
-        }
-        // remove the trailing slash
-        if (pathBuilder.length() > 0) {
-            pathBuilder.deleteCharAt(pathBuilder.length() - 1);
-        }
-        return pathBuilder.toString();
-    }
-
     /*
-     * Moves a tempfile located at fromPath to a new location at toPath. If
-     * toPath is a directory, the destination file will be located at  relativePath
-     * underneath toPath.
+     * Moves a tempfile located at fromPath to a new location in the staging directory.
      */
-    private static Uri moveTempFile(Uri fromPath, Uri toPath, String relativePath) {
+    private static Uri stageTempFile(Uri fromPath, Path stagingDirectory) throws IOException {
         if (!ContentResolver.SCHEME_FILE.equals(fromPath.getScheme())) {
             Log.w(LOG_TAG, "Moving source uri " + fromPath+ " does not have a file scheme");
             return null;
         }
-        if (!ContentResolver.SCHEME_FILE.equals(toPath.getScheme())) {
-            Log.w(LOG_TAG, "Moving destination uri " + toPath + " does not have a file scheme");
-            return null;
-        }
 
-        File fromFile = new File(fromPath.getSchemeSpecificPart());
-        File toFile = new File(toPath.getSchemeSpecificPart());
-        if (toFile.isDirectory()) {
-            toFile = new File(toFile, relativePath);
+        Path fromFile = FileSystems.getDefault().getPath(fromPath.getPath());
+        if (!Files.isDirectory(stagingDirectory)) {
+            Files.createDirectory(stagingDirectory);
         }
-        toFile.getParentFile().mkdirs();
+        Path result = Files.move(fromFile, stagingDirectory.resolve(fromFile.getFileName()));
 
-        if (fromFile.renameTo(toFile)) {
-            return Uri.fromFile(toFile);
-        } else if (manualMove(fromFile, toFile)) {
-            return Uri.fromFile(toFile);
-        }
-        return null;
+        return Uri.fromFile(result.toFile());
     }
 
     private static boolean verifyTempFilePath(Context context, String serviceId,
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java
index f845132..77dea6f 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadSessionCallback.java
@@ -28,7 +28,7 @@
 
     /**
      * Indicates that the middleware has encountered an asynchronous error.
-     * @param errorCode Any error code listed in {@link MbmsException}
+     * @param errorCode Any error code listed in {@link MbmsErrors}
      * @param message A message, intended for debugging purposes, describing the error in further
      *                detail.
      */
@@ -42,7 +42,8 @@
      * This will only be called after the application has requested a list of file services and
      * specified a service class list of interest via
      * {@link MbmsDownloadSession#requestUpdateFileServices(List)}. If there are subsequent calls to
-     * {@link MbmsDownloadSession#requestUpdateFileServices(List)}, this method may not be called again if
+     * {@link MbmsDownloadSession#requestUpdateFileServices(List)},
+     * this method may not be called again if
      * the list of service classes would remain the same.
      *
      * @param services The most recently updated list of available file services.
@@ -55,9 +56,9 @@
      * Called to indicate that the middleware has been initialized and is ready.
      *
      * Before this method is called, calling any method on an instance of
-     * {@link MbmsDownloadSession} will result in an {@link MbmsException}
-     * being thrown with error code {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
-     * or {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
+     * {@link MbmsDownloadSession} will result in an {@link IllegalStateException}
+     * being thrown or {@link #onError(int, String)} being called with error code
+     * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
      */
     public void onMiddlewareReady() {
         // default implementation empty
diff --git a/telephony/java/android/telephony/mbms/MbmsException.java b/telephony/java/android/telephony/mbms/MbmsErrors.java
similarity index 95%
rename from telephony/java/android/telephony/mbms/MbmsException.java
rename to telephony/java/android/telephony/mbms/MbmsErrors.java
index e05bd42..af0af24 100644
--- a/telephony/java/android/telephony/mbms/MbmsException.java
+++ b/telephony/java/android/telephony/mbms/MbmsErrors.java
@@ -18,7 +18,7 @@
 
 import android.telephony.MbmsStreamingSession;
 
-public class MbmsException extends Exception {
+public class MbmsErrors {
     /** Indicates that the operation was successful. */
     public static final int SUCCESS = 0;
 
@@ -130,15 +130,5 @@
         public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402;
     }
 
-    private final int mErrorCode;
-
-    /** @hide */
-    public MbmsException(int errorCode) {
-        super();
-        mErrorCode = errorCode;
-    }
-
-    public int getErrorCode() {
-        return mErrorCode;
-    }
+    private MbmsErrors() {}
 }
diff --git a/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
index 4a70c00..5c130a0 100644
--- a/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
@@ -31,7 +31,7 @@
 public class MbmsStreamingSessionCallback {
     /**
      * Called by the middleware when it has detected an error condition. The possible error codes
-     * are listed in {@link MbmsException}.
+     * are listed in {@link MbmsErrors}.
      * @param errorCode The error code.
      * @param message A human-readable message generated by the middleware for debugging purposes.
      */
@@ -60,7 +60,7 @@
      * Before this method is called, calling any method on an instance of
      * {@link MbmsStreamingSession} will result in an {@link IllegalStateException} or an error
      * delivered via {@link #onError(int, String)} with error code
-     * {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}.
+     * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}.
      */
     public void onMiddlewareReady() {
         // default implementation empty
diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java
index 8652b3e..d38d8a7 100644
--- a/telephony/java/android/telephony/mbms/MbmsUtils.java
+++ b/telephony/java/android/telephony/mbms/MbmsUtils.java
@@ -75,13 +75,13 @@
                 MbmsUtils.getMiddlewareServiceInfo(context, serviceAction);
 
         if (mbmsServiceInfo == null) {
-            return MbmsException.ERROR_NO_UNIQUE_MIDDLEWARE;
+            return MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE;
         }
 
         bindIntent.setComponent(MbmsUtils.toComponentName(mbmsServiceInfo));
 
         context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
-        return MbmsException.SUCCESS;
+        return MbmsErrors.SUCCESS;
     }
 
     /**
diff --git a/telephony/java/android/telephony/mbms/ServiceInfo.java b/telephony/java/android/telephony/mbms/ServiceInfo.java
index 351147a6..9a01ed0 100644
--- a/telephony/java/android/telephony/mbms/ServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/ServiceInfo.java
@@ -28,6 +28,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
 
@@ -127,13 +128,13 @@
      * provided {@link Locale}.
      * @param locale The {@link Locale} in which you want the name of the service. This must be a
      *               value from the list returned by {@link #getLocales()} -- an
-     *               {@link IllegalArgumentException} may be thrown otherwise.
+     *               {@link java.util.NoSuchElementException} may be thrown otherwise.
      * @return The {@link CharSequence} providing the name of the service in the given
      *         {@link Locale}
      */
     public @NonNull CharSequence getNameForLocale(@NonNull Locale locale) {
         if (!names.containsKey(locale)) {
-            throw new IllegalArgumentException("Locale not supported");
+            throw new NoSuchElementException("Locale not supported");
         }
         return names.get(locale);
     }
diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java
index 1a36fc1..ec9134a 100644
--- a/telephony/java/android/telephony/mbms/StreamingService.java
+++ b/telephony/java/android/telephony/mbms/StreamingService.java
@@ -143,7 +143,7 @@
             Log.w(LOG_TAG, "Remote process died");
             mService = null;
             mParentSession.onStreamingServiceStopped(this);
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
             return null;
         }
     }
@@ -171,7 +171,7 @@
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Remote process died");
             mService = null;
-            sendErrorToApp(MbmsException.ERROR_MIDDLEWARE_LOST, null);
+            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
         } finally {
             mParentSession.onStreamingServiceStopped(this);
         }
diff --git a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
index a50a469..0903824 100644
--- a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
+++ b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
@@ -35,7 +35,7 @@
 
     /**
      * Called by the middleware when it has detected an error condition in this stream. The
-     * possible error codes are listed in {@link MbmsException}.
+     * possible error codes are listed in {@link MbmsErrors}.
      * @param errorCode The error code.
      * @param message A human-readable message generated by the middleware for debugging purposes.
      */
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
index a3c8426..d845a57 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
@@ -30,7 +30,7 @@
 import android.telephony.mbms.IDownloadStateCallback;
 import android.telephony.mbms.IMbmsDownloadSessionCallback;
 import android.telephony.mbms.MbmsDownloadSessionCallback;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsErrors;
 
 import java.util.HashMap;
 import java.util.List;
@@ -51,10 +51,10 @@
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}, which
      * will be intercepted and passed to the app as
-     * {@link android.telephony.mbms.MbmsException.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
+     * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
      *
-     * May return any value from {@link android.telephony.mbms.MbmsException.InitializationErrors}
-     * or {@link MbmsException#SUCCESS}. Non-successful error codes will be passed to the app via
+     * May return any value from {@link MbmsErrors.InitializationErrors}
+     * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via
      * {@link IMbmsDownloadSessionCallback#onError(int, String)}.
      *
      * @param callback The callback to use to communicate with the app.
@@ -124,8 +124,8 @@
      * @param serviceClasses The service classes that the app wishes to get info on. The strings
      *                       may contain arbitrary data as negotiated between the app and the
      *                       carrier.
-     * @return One of {@link MbmsException#SUCCESS} or
-     *         {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY},
+     * @return One of {@link MbmsErrors#SUCCESS} or
+     *         {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY},
      */
     @Override
     public int requestUpdateFileServices(int subscriptionId, List<String> serviceClasses)
@@ -140,13 +140,13 @@
      *
      * If the calling app (as identified by the calling UID) currently has any pending download
      * requests that have not been canceled, the middleware must return
-     * {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} here.
+     * {@link MbmsErrors.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT} here.
      *
      * @param subscriptionId The subscription id the download is operating under.
      * @param rootDirectoryPath The path to the app's temp file root directory.
-     * @return {@link MbmsException#SUCCESS},
-     *         {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY} or
-     *         {@link MbmsException.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT}
+     * @return {@link MbmsErrors#SUCCESS},
+     *         {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY} or
+     *         {@link MbmsErrors.DownloadErrors#ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT}
      */
     @Override
     public int setTempFileRootDirectory(int subscriptionId,
@@ -162,8 +162,8 @@
      * this is not the case, an {@link IllegalStateException} may be thrown.
      *
      * @param downloadRequest An object describing the set of files to be downloaded.
-     * @return Any error from {@link android.telephony.mbms.MbmsException.GeneralErrors}
-     *         or {@link MbmsException#SUCCESS}
+     * @return Any error from {@link MbmsErrors.GeneralErrors}
+     *         or {@link MbmsErrors#SUCCESS}
      */
     @Override
     public int download(DownloadRequest downloadRequest) throws RemoteException {
@@ -179,7 +179,7 @@
      * If the middleware is not aware of a download having been requested with the provided
      *
      * {@link DownloadRequest} in the past,
-     * {@link android.telephony.mbms.MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}
+     * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}
      * must be returned.
      *
      * @param downloadRequest The {@link DownloadRequest} that was used to initiate the download
@@ -249,7 +249,7 @@
      *
      * If the middleware is not aware of a download having been requested with the provided
      * {@link DownloadRequest} in the past,
-     * {@link android.telephony.mbms.MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}
+     * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}
      * must be returned.
      *
      * @param downloadRequest The {@link DownloadRequest} that was used to register the callback
@@ -306,13 +306,13 @@
      * Issues a request to cancel the specified download request.
      *
      * If the middleware is unable to cancel the request for whatever reason, it should return
-     * synchronously with an error. If this method returns {@link MbmsException#SUCCESS}, the app
+     * synchronously with an error. If this method returns {@link MbmsErrors#SUCCESS}, the app
      * will no longer be expecting any more file-completed intents from the middleware for this
      * {@link DownloadRequest}.
      * @param downloadRequest The request to cancel
-     * @return {@link MbmsException#SUCCESS},
-     *         {@link MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST},
-     *         {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
+     * @return {@link MbmsErrors#SUCCESS},
+     *         {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST},
+     *         {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}
      */
     @Override
     public int cancelDownload(DownloadRequest downloadRequest) throws RemoteException {
@@ -344,7 +344,7 @@
      * In addition, current in-progress downloads must not be interrupted.
      *
      * If the middleware is not aware of the specified download request, return
-     * {@link MbmsException.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
+     * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
      *
      * @param downloadRequest The request to re-download files for.
      */
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
index 7f57dde..f8f370a 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
@@ -24,7 +24,7 @@
 import android.os.RemoteException;
 import android.telephony.mbms.IMbmsStreamingSessionCallback;
 import android.telephony.mbms.IStreamingServiceCallback;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsErrors;
 import android.telephony.mbms.MbmsStreamingSessionCallback;
 import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceCallback;
@@ -44,10 +44,10 @@
      *
      * May throw an {@link IllegalArgumentException} or a {@link SecurityException}, which
      * will be intercepted and passed to the app as
-     * {@link android.telephony.mbms.MbmsException.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
+     * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
      *
-     * May return any value from {@link android.telephony.mbms.MbmsException.InitializationErrors}
-     * or {@link MbmsException#SUCCESS}. Non-successful error codes will be passed to the app via
+     * May return any value from {@link MbmsErrors.InitializationErrors}
+     * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via
      * {@link IMbmsStreamingSessionCallback#onError(int, String)}.
      *
      * @param callback The callback to use to communicate with the app.
@@ -118,8 +118,8 @@
      * @param serviceClasses The service classes that the app wishes to get info on. The strings
      *                       may contain arbitrary data as negotiated between the app and the
      *                       carrier.
-     * @return {@link MbmsException#SUCCESS} or any of the errors in
-     * {@link android.telephony.mbms.MbmsException.GeneralErrors}
+     * @return {@link MbmsErrors#SUCCESS} or any of the errors in
+     * {@link MbmsErrors.GeneralErrors}
      */
     @Override
     public int requestUpdateStreamingServices(int subscriptionId,
@@ -137,7 +137,7 @@
      * @param subscriptionId The subscription id to use.
      * @param serviceId The ID of the streaming service that the app has requested.
      * @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 MbmsErrors.GeneralErrors}
      */
     public int startStreaming(int subscriptionId, String serviceId,
             StreamingServiceCallback callback) throws RemoteException {
diff --git a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
index 923ea15..8fb27b2 100644
--- a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
+++ b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
@@ -23,7 +23,6 @@
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.telephony.MbmsDownloadSession;
-import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.MbmsDownloadReceiver;
 
 import java.io.File;
@@ -42,7 +41,7 @@
      * failed. Mandatory extras are
      * {@link MbmsDownloadSession#EXTRA_MBMS_DOWNLOAD_RESULT}
      * {@link MbmsDownloadSession#EXTRA_MBMS_FILE_INFO}
-     * {@link #EXTRA_REQUEST}
+     * {@link MbmsDownloadSession#EXTRA_MBMS_DOWNLOAD_REQUEST}
      * {@link #EXTRA_TEMP_LIST}
      * {@link #EXTRA_FINAL_URI}
      */
@@ -122,12 +121,6 @@
             "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.
      */