Merge "Add TD-SCDMA related network mode options"
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index 1386e19..acb41f6 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -161,14 +161,20 @@
 
         // Set the conference as conferenceable with all of the connections that are not in the
         // conference.
-        if (mTelephonyConference != null && !isFullConference(mTelephonyConference)) {
-            List<Connection> nonConferencedConnections = mTelephonyConnections
-                    .stream()
-                    // Only retrieve Connections that are not in a conference (but support
-                    // conferences).
-                    .filter(c -> c.isConferenceSupported() && c.getConference() == null)
-                    .collect(Collectors.toList());
-            mTelephonyConference.setConferenceableConnections(nonConferencedConnections);
+        if (mTelephonyConference != null) {
+            if (!isFullConference(mTelephonyConference)) {
+                List<Connection> nonConferencedConnections = mTelephonyConnections
+                        .stream()
+                        // Only retrieve Connections that are not in a conference (but support
+                        // conferences).
+                        .filter(c -> c.isConferenceSupported() && c.getConference() == null)
+                        .collect(Collectors.toList());
+                mTelephonyConference.setConferenceableConnections(nonConferencedConnections);
+            } else {
+                Log.d(this, "cannot merge anymore due it is full");
+                mTelephonyConference
+                        .setConferenceableConnections(Collections.<Connection>emptyList());
+            }
         }
         // TODO: Do not allow conferencing of already conferenced connections.
     }
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsSampleDownloadService.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsSampleDownloadService.java
index f1060e3..dcb7320 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsSampleDownloadService.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsSampleDownloadService.java
@@ -30,19 +30,16 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.telephony.MbmsDownloadManager;
-import android.telephony.mbms.DownloadProgressListener;
+import android.telephony.MbmsDownloadSession;
 import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.FileInfo;
 import android.telephony.mbms.FileServiceInfo;
-import android.telephony.mbms.IDownloadProgressListener;
-import android.telephony.mbms.IMbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsDownloadSessionCallback;
+import android.telephony.mbms.MbmsErrors;
 import android.telephony.mbms.UriPathPair;
 import android.telephony.mbms.vendor.IMbmsDownloadService;
 import android.telephony.mbms.vendor.MbmsDownloadServiceBase;
-import android.telephony.mbms.vendor.VendorIntents;
+import android.telephony.mbms.vendor.VendorUtils;
 import android.util.Log;
 
 import java.io.IOException;
@@ -71,15 +68,15 @@
 
     private final IMbmsDownloadService mBinder = new MbmsDownloadServiceBase() {
         @Override
-        public int initialize(int subId, MbmsDownloadManagerCallback callback) {
+        public int initialize(int subId, MbmsDownloadSessionCallback callback) {
             int packageUid = Binder.getCallingUid();
             String[] packageNames = getPackageManager().getPackagesForUid(packageUid);
             if (packageNames == null) {
-                return MbmsException.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
+                return MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
             }
             boolean isUidAllowed = Arrays.stream(packageNames).anyMatch(ALLOWED_PACKAGES::contains);
             if (!isUidAllowed) {
-                return MbmsException.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
+                return MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
             }
 
             // Do initialization with a bit of a delay to simulate work being done.
@@ -87,30 +84,23 @@
                 FrontendAppIdentifier appKey = new FrontendAppIdentifier(packageUid, subId);
                 if (!mAppCallbacks.containsKey(appKey)) {
                     mAppCallbacks.put(appKey, callback);
-                    ComponentName appReceiver = VendorIntents.getAppReceiverFromUid(
-                            EmbmsSampleDownloadService.this, packageUid);
+                    ComponentName appReceiver = VendorUtils.getAppReceiverFromPackageName(
+                            EmbmsSampleDownloadService.this,
+                            getPackageManager().getNameForUid(packageUid));
                     mAppReceivers.put(appKey, appReceiver);
                 } else {
-                    try {
-                        callback.error(
-                                MbmsException.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, "");
-                    } catch (RemoteException e) {
-                        // ignore, it was an error anyway
-                    }
+                    callback.onError(
+                            MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, "");
                     return;
                 }
-                try {
-                    callback.middlewareReady();
-                } catch (RemoteException e) {
-                    // TODO: call dispose
-                }
+                callback.onMiddlewareReady();
             }, INITIALIZATION_DELAY);
 
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
-        public int getFileServices(int subscriptionId,
+        public int requestUpdateFileServices(int subscriptionId,
                 List<String> serviceClasses) throws RemoteException {
             FrontendAppIdentifier appKey =
                     new FrontendAppIdentifier(Binder.getCallingUid(), subscriptionId);
@@ -121,14 +111,10 @@
                     .getFileServicesForClasses(serviceClasses);
 
             mHandler.postDelayed(() -> {
-                try {
-                    IMbmsDownloadManagerCallback appCallback = mAppCallbacks.get(appKey);
-                    appCallback.fileServicesUpdated(serviceInfos);
-                } catch (RemoteException e) {
-                    // TODO: call dispose
-                }
+                MbmsDownloadSessionCallback appCallback = mAppCallbacks.get(appKey);
+                appCallback.onFileServicesUpdated(serviceInfos);
             }, SEND_FILE_SERVICE_INFO_DELAY);
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
@@ -139,20 +125,20 @@
             checkInitialized(appKey);
 
             if (mActiveDownloadRequests.getOrDefault(appKey, Collections.emptySet()).size() > 0) {
-                return MbmsException.DownloadErrors.ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT;
+                return MbmsErrors.DownloadErrors.ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT;
             }
             mAppTempFileRoots.put(appKey, rootDirectoryPath);
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
-        public int download(DownloadRequest downloadRequest, DownloadProgressListener listener) {
+        public int download(DownloadRequest downloadRequest) {
             FrontendAppIdentifier appKey = new FrontendAppIdentifier(
                     Binder.getCallingUid(), downloadRequest.getSubscriptionId());
             checkInitialized(appKey);
 
             mHandler.post(() -> sendFdRequest(downloadRequest, appKey));
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
@@ -162,16 +148,25 @@
             checkInitialized(appKey);
             if (!mActiveDownloadRequests.getOrDefault(
                     appKey, Collections.emptySet()).contains(downloadRequest)) {
-                return MbmsException.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST;
+                return MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST;
             }
             mActiveDownloadRequests.get(appKey).remove(downloadRequest);
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
+        }
+
+        @Override
+        public void onAppCallbackDied(int uid, int subscriptionId) {
+            FrontendAppIdentifier appKey = new FrontendAppIdentifier(uid, subscriptionId);
+
+            Log.i(LOG_TAG, "Disposing app " + appKey + " due to binder death");
+            mAppCallbacks.remove(appKey);
+            // TODO: call dispose
         }
     };
 
     private static EmbmsSampleDownloadService sInstance = null;
 
-    private final Map<FrontendAppIdentifier, IMbmsDownloadManagerCallback> mAppCallbacks =
+    private final Map<FrontendAppIdentifier, MbmsDownloadSessionCallback> mAppCallbacks =
             new HashMap<>();
     private final Map<FrontendAppIdentifier, ComponentName> mAppReceivers = new HashMap<>();
     private final Map<FrontendAppIdentifier, String> mAppTempFileRoots = new HashMap<>();
@@ -204,15 +199,15 @@
         ComponentName appReceiver = mAppReceivers.values().iterator().next();
         for (FileServiceInfo fileServiceInfo :
                 FileServiceRepository.getInstance(this).getAllFileServices()) {
-            Intent cleanupIntent = new Intent(VendorIntents.ACTION_CLEANUP);
+            Intent cleanupIntent = new Intent(VendorUtils.ACTION_CLEANUP);
             cleanupIntent.setComponent(appReceiver);
-            cleanupIntent.putExtra(VendorIntents.EXTRA_SERVICE_INFO, fileServiceInfo);
-            cleanupIntent.putExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT,
+            cleanupIntent.putExtra(VendorUtils.EXTRA_SERVICE_ID, fileServiceInfo.getServiceId());
+            cleanupIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
                     mAppTempFileRoots.get(registeredAppId));
             Set<Uri> tempFilesInUse =
                     mTempFilesInUse.getOrDefault(registeredAppId, Collections.emptyMap())
                             .getOrDefault(fileServiceInfo.getServiceId(), Collections.emptySet());
-            cleanupIntent.putExtra(VendorIntents.EXTRA_TEMP_FILES_IN_USE,
+            cleanupIntent.putExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE,
                     new ArrayList<>(tempFilesInUse));
             sendBroadcast(cleanupIntent);
         }
@@ -222,10 +217,10 @@
         // Assume one app, and do it for the specified service.
         FrontendAppIdentifier registeredAppId = mAppReceivers.keySet().iterator().next();
         ComponentName appReceiver = mAppReceivers.values().iterator().next();
-        Intent fdRequestIntent = new Intent(VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST);
-        fdRequestIntent.putExtra(VendorIntents.EXTRA_SERVICE_INFO, serviceInfo);
-        fdRequestIntent.putExtra(VendorIntents.EXTRA_FD_COUNT, 10);
-        fdRequestIntent.putExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT,
+        Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        fdRequestIntent.putExtra(VendorUtils.EXTRA_SERVICE_ID, serviceInfo.getServiceId());
+        fdRequestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 10);
+        fdRequestIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
                 mAppTempFileRoots.get(registeredAppId));
         fdRequestIntent.setComponent(appReceiver);
 
@@ -240,7 +235,7 @@
                         if (extras != null) {
                             Log.i(LOG_TAG, "Got "
                                     + extras.getParcelableArrayList(
-                                    VendorIntents.EXTRA_FREE_URI_LIST).size()
+                                    VendorUtils.EXTRA_FREE_URI_LIST).size()
                                     + " fds");
                         }
                     }
@@ -258,12 +253,10 @@
     private void sendFdRequest(DownloadRequest request, FrontendAppIdentifier appKey) {
         int numFds = getNumFdsNeededForRequest(request);
         // Compose the FILE_DESCRIPTOR_REQUEST_INTENT
-        Intent requestIntent = new Intent(VendorIntents.ACTION_FILE_DESCRIPTOR_REQUEST);
-        requestIntent.putExtra(VendorIntents.EXTRA_SERVICE_INFO,
-                FileServiceRepository.getInstance(this)
-                        .getFileServiceInfoForId(request.getFileServiceId()));
-        requestIntent.putExtra(VendorIntents.EXTRA_FD_COUNT, numFds);
-        requestIntent.putExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT,
+        Intent requestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        requestIntent.putExtra(VendorUtils.EXTRA_SERVICE_ID, request.getFileServiceId());
+        requestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, numFds);
+        requestIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
                 mAppTempFileRoots.get(appKey));
         requestIntent.setComponent(mAppReceivers.get(appKey));
 
@@ -291,7 +284,7 @@
     private void performDownload(DownloadRequest request, FrontendAppIdentifier appKey,
             Bundle extras) {
         List<UriPathPair> tempFiles = extras.getParcelableArrayList(
-                VendorIntents.EXTRA_FREE_URI_LIST);
+                VendorUtils.EXTRA_FREE_URI_LIST);
         List<FileInfo> filesToDownload = FileServiceRepository.getInstance(this)
                 .getFileServiceInfoForId(request.getFileServiceId())
                 .getFiles();
@@ -329,7 +322,7 @@
 
     private void downloadSingleFile(FrontendAppIdentifier appKey, DownloadRequest request,
             UriPathPair tempFile, FileInfo fileToDownload) {
-        int result = MbmsDownloadManager.RESULT_SUCCESSFUL;
+        int result = MbmsDownloadSession.RESULT_SUCCESSFUL;
         try {
             // Get the ParcelFileDescriptor for the single temp file we requested
             ParcelFileDescriptor tempFileFd = getContentResolver().openFileDescriptor(
@@ -351,7 +344,7 @@
             destinationStream.write(imageBuffer);
             destinationStream.flush();
         } catch (IOException e) {
-            result = MbmsDownloadManager.RESULT_CANCELLED;
+            result = MbmsDownloadSession.RESULT_CANCELLED;
         }
 
         // Take a round-trip through the download request serialization to exercise it
@@ -363,18 +356,18 @@
                 .build();
 
         Intent downloadResultIntent =
-                new Intent(VendorIntents.ACTION_DOWNLOAD_RESULT_INTERNAL);
-        downloadResultIntent.putExtra(VendorIntents.EXTRA_REQUEST, request1);
-        downloadResultIntent.putExtra(VendorIntents.EXTRA_FINAL_URI,
+                new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+        downloadResultIntent.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request1);
+        downloadResultIntent.putExtra(VendorUtils.EXTRA_FINAL_URI,
                 tempFile.getFilePathUri());
-        downloadResultIntent.putExtra(MbmsDownloadManager.EXTRA_FILE_INFO, fileToDownload);
-        downloadResultIntent.putExtra(VendorIntents.EXTRA_TEMP_FILE_ROOT,
+        downloadResultIntent.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, fileToDownload);
+        downloadResultIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
                 mAppTempFileRoots.get(appKey));
         ArrayList<Uri> tempFileList = new ArrayList<>(1);
         tempFileList.add(tempFile.getFilePathUri());
         downloadResultIntent.getExtras().putParcelableArrayList(
-                VendorIntents.EXTRA_TEMP_LIST, tempFileList);
-        downloadResultIntent.putExtra(MbmsDownloadManager.EXTRA_RESULT, result);
+                VendorUtils.EXTRA_TEMP_LIST, tempFileList);
+        downloadResultIntent.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, result);
         downloadResultIntent.setComponent(mAppReceivers.get(appKey));
 
         sendOrderedBroadcast(downloadResultIntent,
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java
index 3428e38..f50536c 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java
@@ -23,14 +23,11 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.RemoteException;
-import android.telephony.mbms.IMbmsStreamingManagerCallback;
-import android.telephony.mbms.MbmsException;
-import android.telephony.mbms.MbmsStreamingManagerCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsStreamingSessionCallback;
 import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceCallback;
 import android.telephony.mbms.StreamingServiceInfo;
-import android.telephony.mbms.vendor.IMbmsStreamingService;
 import android.telephony.mbms.vendor.MbmsStreamingServiceBase;
 import android.util.Log;
 
@@ -56,7 +53,7 @@
 
     private static final int SEND_STREAMING_SERVICES_LIST = 1;
 
-    private final Map<FrontendAppIdentifier, MbmsStreamingManagerCallback> mAppCallbacks =
+    private final Map<FrontendAppIdentifier, MbmsStreamingSessionCallback> mAppCallbacks =
             new HashMap<>();
 
     private HandlerThread mHandlerThread;
@@ -67,7 +64,7 @@
                 SomeArgs args = (SomeArgs) msg.obj;
                 FrontendAppIdentifier appKey = (FrontendAppIdentifier) args.arg1;
                 List<StreamingServiceInfo> services = (List) args.arg2;
-                MbmsStreamingManagerCallback appCallback = mAppCallbacks.get(appKey);
+                MbmsStreamingSessionCallback appCallback = mAppCallbacks.get(appKey);
                 if (appCallback != null) {
                     appCallback.onStreamingServicesUpdated(services);
                 }
@@ -78,15 +75,15 @@
 
     private final MbmsStreamingServiceBase mBinder = new MbmsStreamingServiceBase() {
         @Override
-        public int initialize(MbmsStreamingManagerCallback callback, int subId) {
+        public int initialize(MbmsStreamingSessionCallback callback, int subId) {
             int packageUid = Binder.getCallingUid();
             String[] packageNames = getPackageManager().getPackagesForUid(packageUid);
             if (packageNames == null) {
-                return MbmsException.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
+                return MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
             }
             boolean isUidAllowed = Arrays.stream(packageNames).anyMatch(ALLOWED_PACKAGES::contains);
             if (!isUidAllowed) {
-                return MbmsException.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
+                return MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
             }
 
             mHandler.postDelayed(() -> {
@@ -95,16 +92,16 @@
                     mAppCallbacks.put(appKey, callback);
                 } else {
                     callback.onError(
-                            MbmsException.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, "");
+                            MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, "");
                     return;
                 }
                 callback.onMiddlewareReady();
             }, INITIALIZATION_DELAY);
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
-        public int getStreamingServices(int subscriptionId, List<String> serviceClasses) {
+        public int requestUpdateStreamingServices(int subscriptionId, List<String> serviceClasses) {
             FrontendAppIdentifier appKey =
                     new FrontendAppIdentifier(Binder.getCallingUid(), subscriptionId);
             checkInitialized(appKey);
@@ -120,7 +117,7 @@
             mHandler.sendMessageDelayed(
                     mHandler.obtainMessage(SEND_STREAMING_SERVICES_LIST, args),
                     SEND_SERVICE_LIST_DELAY);
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
@@ -133,14 +130,14 @@
 
             if (StreamStateTracker.getStreamingState(appKey, serviceId) ==
                     StreamingService.STATE_STARTED) {
-                return MbmsException.StreamingErrors.ERROR_DUPLICATE_START_STREAM;
+                return MbmsErrors.StreamingErrors.ERROR_DUPLICATE_START_STREAM;
             }
 
             mHandler.postDelayed(
                     () -> StreamStateTracker.startStreaming(appKey, serviceId, callback,
                             StreamingService.REASON_BY_USER_REQUEST),
                     START_STREAMING_DELAY);
-            return MbmsException.SUCCESS;
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
@@ -166,16 +163,6 @@
 
             mHandler.post(() -> StreamStateTracker.stopStreaming(appKey, serviceId,
                     StreamingService.REASON_BY_USER_REQUEST));
-        }
-
-        @Override
-        public void disposeStream(int subscriptionId, String serviceId) {
-            FrontendAppIdentifier appKey =
-                    new FrontendAppIdentifier(Binder.getCallingUid(), subscriptionId);
-            checkInitialized(appKey);
-            checkServiceExists(serviceId);
-
-            Log.i(TAG, "Disposing of stream " + serviceId);
             StreamStateTracker.dispose(appKey, serviceId);
         }
 
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/FileServiceRepository.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/FileServiceRepository.java
index 7b8cbd5..27911f6 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/FileServiceRepository.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/FileServiceRepository.java
@@ -21,13 +21,8 @@
 import android.telephony.mbms.FileInfo;
 import android.telephony.mbms.FileServiceInfo;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -67,7 +62,7 @@
     public List<FileServiceInfo> getFileServicesForClasses(
             List<String> serviceClasses) {
         return mIdToServiceInfo.values().stream()
-                .filter((info) -> serviceClasses.contains(info.getClassName()))
+                .filter((info) -> serviceClasses.contains(info.getServiceClassName()))
                 .collect(Collectors.toList());
     }
 
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamingServiceRepository.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamingServiceRepository.java
index 677f39b..e1a12e3 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamingServiceRepository.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamingServiceRepository.java
@@ -43,7 +43,7 @@
     public static List<StreamingServiceInfo> getStreamingServicesForClasses(
             List<String> serviceClasses) {
         return sIdToServiceInfo.values().stream()
-                .filter((info) -> serviceClasses.contains(info.getClassName()))
+                .filter((info) -> serviceClasses.contains(info.getServiceClassName()))
                 .collect(Collectors.toList());
     }
 
diff --git a/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/DownloadCompletionReceiver.java b/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/DownloadCompletionReceiver.java
index ef9e672..3c94b76 100644
--- a/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/DownloadCompletionReceiver.java
+++ b/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/DownloadCompletionReceiver.java
@@ -20,20 +20,68 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
-import android.telephony.MbmsDownloadManager;
+import android.telephony.MbmsDownloadSession;
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.FileInfo;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 
 public class DownloadCompletionReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         if (EmbmsTestDownloadApp.DOWNLOAD_DONE_ACTION.equals(intent.getAction())) {
-            int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT,
-                    MbmsDownloadManager.RESULT_CANCELLED);
-            if (result != MbmsDownloadManager.RESULT_SUCCESSFUL) {
+            int result = intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
+                    MbmsDownloadSession.RESULT_CANCELLED);
+            if (result != MbmsDownloadSession.RESULT_SUCCESSFUL) {
                 EmbmsTestDownloadApp.getInstance().onDownloadFailed(result);
             }
             Uri completedFile = intent.getParcelableExtra(
-                    MbmsDownloadManager.EXTRA_COMPLETED_FILE_URI);
-            EmbmsTestDownloadApp.getInstance().onDownloadDone(completedFile);
+                    MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI);
+            FileInfo completedFileInfo = intent.getParcelableExtra(
+                    MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
+            DownloadRequest request = intent.getParcelableExtra(
+                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+
+            Path destinationFile = getDestinationFile(context,
+                    request.getFileServiceId(), completedFileInfo);
+            Path sourceFile = FileSystems.getDefault().getPath(completedFile.getPath());
+            try {
+                Files.move(sourceFile, destinationFile, StandardCopyOption.REPLACE_EXISTING);
+            } catch (IOException e) {
+                return;
+            }
+
+            EmbmsTestDownloadApp.getInstance().onDownloadDone(
+                    Uri.fromFile(destinationFile.toFile()));
+        }
+    }
+
+    private Path getDestinationFile(Context context, String serviceId, FileInfo info) {
+        try {
+            if (serviceId.contains("2")) {
+                String fileName = info.getUri().getLastPathSegment();
+                Path destination = FileSystems.getDefault()
+                        .getPath(context.getFilesDir().getPath(), "images/animals/", fileName)
+                        .normalize();
+                if (!Files.isDirectory(destination.getParent())) {
+                    Files.createDirectory(destination.getParent());
+                }
+                return destination;
+            } else {
+                Path destination = FileSystems.getDefault()
+                        .getPath(context.getFilesDir().getPath(), "images/image.png")
+                        .normalize();
+                if (!Files.isDirectory(destination.getParent())) {
+                    Files.createDirectory(destination.getParent());
+                }
+                return destination;
+            }
+        } catch (IOException e) {
+            return null;
         }
     }
 }
diff --git a/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/EmbmsTestDownloadApp.java b/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/EmbmsTestDownloadApp.java
index 80045ce..23f2cc5 100644
--- a/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/EmbmsTestDownloadApp.java
+++ b/testapps/EmbmsTestDownloadApp/src/com/android/phone/testapps/embmsdownload/EmbmsTestDownloadApp.java
@@ -25,12 +25,11 @@
 import android.os.HandlerThread;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
-import android.telephony.MbmsDownloadManager;
+import android.telephony.MbmsDownloadSession;
 import android.telephony.SubscriptionManager;
 import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.FileServiceInfo;
-import android.telephony.mbms.MbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsDownloadSessionCallback;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -43,7 +42,6 @@
 import android.widget.Toast;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -108,7 +106,7 @@
         public View getView(int position, View convertView, ViewGroup parent) {
             FileServiceInfo info = getItem(position);
             TextView result = new TextView(EmbmsTestDownloadApp.this);
-            result.setText(info.getNames().get(info.getLocales().get(0)));
+            result.setText(info.getNameForLocale(info.getLocales().get(0)));
             return result;
         }
 
@@ -117,7 +115,7 @@
             FileServiceInfo info = getItem(position);
             TextView result = new TextView(EmbmsTestDownloadApp.this);
             String text = "name="
-                    + info.getNames().get(info.getLocales().get(0))
+                    + info.getNameForLocale(info.getLocales().get(0))
                     + ", "
                     + "numFiles="
                     + info.getFiles().size();
@@ -153,15 +151,15 @@
     }
 
 
-    private MbmsDownloadManagerCallback mCallback = new MbmsDownloadManagerCallback() {
+    private MbmsDownloadSessionCallback mCallback = new MbmsDownloadSessionCallback() {
         @Override
-        public void error(int errorCode, String message) {
+        public void onError(int errorCode, String message) {
             runOnUiThread(() -> Toast.makeText(EmbmsTestDownloadApp.this,
                     "Error " + errorCode + ": " + message, Toast.LENGTH_SHORT).show());
         }
 
         @Override
-        public void fileServicesUpdated(List<FileServiceInfo> services) {
+        public void onFileServicesUpdated(List<FileServiceInfo> services) {
             EmbmsTestDownloadApp.this.runOnUiThread(() ->
                     Toast.makeText(EmbmsTestDownloadApp.this,
                             "Got services length " + services.size(),
@@ -170,13 +168,13 @@
         }
 
         @Override
-        public void middlewareReady() {
+        public void onMiddlewareReady() {
             runOnUiThread(() -> Toast.makeText(EmbmsTestDownloadApp.this,
                     "Initialization done", Toast.LENGTH_SHORT).show());
         }
     };
 
-    private MbmsDownloadManager mDownloadManager;
+    private MbmsDownloadSession mDownloadManager;
     private Handler mHandler;
     private HandlerThread mHandlerThread;
     private FileServiceInfoAdapter mFileServiceInfoAdapter;
@@ -203,12 +201,7 @@
 
         Button bindButton = (Button) findViewById(R.id.bind_button);
         bindButton.setOnClickListener((view) -> {
-            try {
-                mDownloadManager = MbmsDownloadManager.create(this, mCallback);
-            } catch (MbmsException e) {
-                Toast.makeText(EmbmsTestDownloadApp.this,
-                        "caught MbmsException: " + e.getErrorCode(), Toast.LENGTH_SHORT).show();
-            }
+            mDownloadManager = MbmsDownloadSession.create(this, mCallback, mHandler);
         });
 
         Button setTempFileRootButton = (Button) findViewById(R.id.set_temp_root_button);
@@ -216,24 +209,14 @@
             File downloadDir = new File(EmbmsTestDownloadApp.this.getFilesDir(),
                     CUSTOM_EMBMS_TEMP_FILE_LOCATION);
             downloadDir.mkdirs();
-            try {
-                mDownloadManager.setTempFileRootDirectory(downloadDir);
-                Toast.makeText(EmbmsTestDownloadApp.this,
-                        "temp file root set to " + downloadDir, Toast.LENGTH_SHORT).show();
-            } catch (MbmsException e) {
-                Toast.makeText(EmbmsTestDownloadApp.this,
-                        "caught MbmsException: " + e.getErrorCode(), Toast.LENGTH_SHORT).show();
-            }
+            mDownloadManager.setTempFileRootDirectory(downloadDir);
+            Toast.makeText(EmbmsTestDownloadApp.this,
+                    "temp file root set to " + downloadDir, Toast.LENGTH_SHORT).show();
         });
 
         Button getFileServicesButton = (Button) findViewById(R.id.get_file_services_button);
         getFileServicesButton.setOnClickListener((view) -> mHandler.post(() -> {
-            try {
-                mDownloadManager.getFileServices(Collections.singletonList("Class1"));
-            } catch (MbmsException e) {
-                runOnUiThread(() -> Toast.makeText(EmbmsTestDownloadApp.this,
-                        "caught MbmsException: " + e.getErrorCode(), Toast.LENGTH_SHORT).show());
-            }
+            mDownloadManager.requestUpdateFileServices(Collections.singletonList("Class1"));
         }));
 
         final Spinner serviceSelector = (Spinner) findViewById(R.id.available_file_services);
@@ -286,15 +269,10 @@
                         "No download service bound", Toast.LENGTH_SHORT).show();
                 return;
             }
-            try {
-                DownloadRequest request =
-                        (DownloadRequest) downloadRequestSpinner.getSelectedItem();
-                mDownloadManager.cancelDownload(request);
-                mDownloadRequestAdapter.remove(request);
-            } catch (MbmsException e) {
-                runOnUiThread(() -> Toast.makeText(EmbmsTestDownloadApp.this,
-                        "caught MbmsException: " + e.getErrorCode(), Toast.LENGTH_SHORT).show());
-            }
+            DownloadRequest request =
+                    (DownloadRequest) downloadRequestSpinner.getSelectedItem();
+            mDownloadManager.cancelDownload(request);
+            mDownloadRequestAdapter.remove(request);
         });
     }
 
@@ -331,23 +309,13 @@
     }
 
     private void performDownload(FileServiceInfo info) {
-        File destination = null;
         Uri.Builder sourceUriBuilder = new Uri.Builder()
                 .scheme(FILE_DOWNLOAD_SCHEME)
                 .authority(FILE_AUTHORITY);
-        try {
-            if (info.getFiles().size() > 1) {
-                destination = new File(getFilesDir(), "images/animals/").getCanonicalFile();
-                destination.mkdirs();
-                clearDirectory(destination);
-                sourceUriBuilder.path("/*");
-            } else {
-                destination = new File(getFilesDir(), "images/image.png").getCanonicalFile();
-                destination.delete();
-                sourceUriBuilder.path("/image.png");
-            }
-        } catch (IOException e) {
-            // ignore
+        if (info.getServiceId().contains("2")) {
+            sourceUriBuilder.path("/*");
+        } else {
+            sourceUriBuilder.path("/image.png");
         }
 
         Intent completionIntent = new Intent(DOWNLOAD_DONE_ACTION);
@@ -356,26 +324,11 @@
         DownloadRequest request = new DownloadRequest.Builder()
                 .setServiceInfo(info)
                 .setSource(sourceUriBuilder.build())
-                .setDest(Uri.fromFile(destination))
                 .setAppIntent(completionIntent)
                 .setSubscriptionId(SubscriptionManager.getDefaultSubscriptionId())
                 .build();
 
-        try {
-            mDownloadManager.download(request, null);
-            mDownloadRequestAdapter.add(request);
-        } catch (MbmsException e) {
-            Toast.makeText(EmbmsTestDownloadApp.this,
-                    "caught MbmsException: " + e.getErrorCode(), Toast.LENGTH_SHORT).show();
-        }
-    }
-
-    private static void clearDirectory(File directory) {
-        for (File file: directory.listFiles()) {
-            if (file.isDirectory()) {
-                clearDirectory(file);
-            }
-            file.delete();
-        }
+        mDownloadManager.download(request);
+        mDownloadRequestAdapter.add(request);
     }
 }
diff --git a/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml b/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml
index b75a157..d28ede2 100644
--- a/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml
+++ b/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml
@@ -96,13 +96,6 @@
             android:layout_column="1"
             android:text="@string/stop_streaming_button" />
         <Button
-            android:id="@+id/dispose_stream_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_row="2"
-            android:layout_column="0"
-            android:text="@string/dispose_stream_button" />
-        <Button
             android:id="@+id/dispose_manager_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java
index 1505846..0546c9d 100644
--- a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java
+++ b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java
@@ -22,9 +22,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.telephony.MbmsStreamingManager;
-import android.telephony.mbms.MbmsException;
-import android.telephony.mbms.MbmsStreamingManagerCallback;
+import android.telephony.MbmsStreamingSession;
+import android.telephony.mbms.MbmsStreamingSessionCallback;
 import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceInfo;
 import android.view.View;
@@ -41,9 +40,10 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.NoSuchElementException;
 
 public class EmbmsTestStreamingApp extends Activity {
-    private MbmsStreamingManagerCallback mStreamingListener = new MbmsStreamingManagerCallback() {
+    private MbmsStreamingSessionCallback mStreamingListener = new MbmsStreamingSessionCallback() {
         @Override
         public void onStreamingServicesUpdated(List<StreamingServiceInfo> services) {
             EmbmsTestStreamingApp.this.runOnUiThread(() ->
@@ -67,16 +67,13 @@
         }
 
         private String getName(StreamingServiceInfo info) {
-            Map<Locale, String> names = info.getNames();
-            String name = "<No Name>";
-            if (!names.isEmpty()) {
-                Locale locale = Locale.getDefault();
-                if (!names.containsKey(locale)) {
-                    locale = names.keySet().iterator().next();
-                }
-                name = names.get(locale);
+            Locale locale = Locale.getDefault();
+            try {
+                return info.getNameForLocale(locale).toString();
+            } catch (NoSuchElementException e) {
+                locale = info.getLocales().iterator().next();
+                return info.getNameForLocale(locale).toString();
             }
-            return name;
         }
 
         @Override
@@ -131,7 +128,7 @@
         }
     }
 
-    private MbmsStreamingManager mStreamingManager = null;
+    private MbmsStreamingSession mStreamingManager = null;
 
     private Handler mHandler;
     private HandlerThread mHandlerThread;
@@ -156,14 +153,8 @@
 
         Button bindButton = (Button) findViewById(R.id.bind_button);
         bindButton.setOnClickListener((view) -> {
-            try {
-                mStreamingManager = MbmsStreamingManager.create(
-                        EmbmsTestStreamingApp.this, mStreamingListener, mHandler);
-            } catch (MbmsException e) {
-                Toast.makeText(EmbmsTestStreamingApp.this,
-                        "Init error: " + e.getErrorCode(), Toast.LENGTH_SHORT).show();
-                return;
-            }
+            mStreamingManager = MbmsStreamingSession.create(
+                    EmbmsTestStreamingApp.this, mStreamingListener, mHandler);
         });
 
         Button getStreamingServicesButton = (Button)
@@ -174,13 +165,7 @@
                         "No streaming service bound", Toast.LENGTH_SHORT).show();
                 return;
             }
-            try {
-                mStreamingManager.getStreamingServices(Collections.singletonList("Class1"));
-            } catch (MbmsException e) {
-                Toast.makeText(EmbmsTestStreamingApp.this,
-                        "Error getting streaming services" + e.getErrorCode(),
-                        Toast.LENGTH_SHORT).show();
-            }
+            mStreamingManager.requestUpdateStreamingServices(Collections.singletonList("Class1"));
         });
 
         final Spinner serviceSelector = (Spinner) findViewById(R.id.available_streaming_services);
@@ -241,27 +226,13 @@
             stream.stopStreaming();
         });
 
-        Button disposeStreamButton = (Button) findViewById(R.id.dispose_stream_button);
-        disposeStreamButton.setOnClickListener((view) -> {
-            if (getSelectedTrackedStream() == null) {
-                Toast.makeText(EmbmsTestStreamingApp.this,
-                        "No streams selected", Toast.LENGTH_SHORT).show();
-                return;
-            }
-            clearStateAndUriDisplay();
-            StreamingServiceTracker stream = getSelectedTrackedStream();
-            mTrackedStreamingServiceAdapter.remove(stream.getServiceId());
-            mStreamingServiceTrackerById.remove(stream.getServiceId());
-            stream.dispose();
-        });
-
         Button disposeManagerButton = (Button) findViewById(R.id.dispose_manager_button);
         disposeManagerButton.setOnClickListener((view) -> {
             clearStateAndUriDisplay();
             mTrackedStreamingServiceAdapter.clear();
             mStreamingServicesDisplayAdapter.update(Collections.emptyList());
             mStreamingServiceTrackerById.clear();
-            mStreamingManager.dispose();
+            mStreamingManager.close();
         });
     }
 
diff --git a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java
index 4821bee..5244d30 100644
--- a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java
+++ b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java
@@ -17,8 +17,7 @@
 package com.android.phone.testapps.embmsfrontend;
 
 import android.net.Uri;
-import android.telephony.MbmsStreamingManager;
-import android.telephony.mbms.MbmsException;
+import android.telephony.MbmsStreamingSession;
 import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceCallback;
 import android.telephony.mbms.StreamingServiceInfo;
@@ -57,37 +56,17 @@
         mStreamingServiceInfo = info;
     }
 
-    public boolean startStreaming(MbmsStreamingManager streamingManager) {
-        try {
-            mStreamingService =
-                    streamingManager.startStreaming(mStreamingServiceInfo, new Callback(), null);
-            return true;
-        } catch (MbmsException e) {
-            Toast.makeText(mActivity,
-                    "Error starting streaming: " + e.getErrorCode(),
-                    Toast.LENGTH_SHORT).show();
-        }
-        return false;
+    /**
+     * Start streaming using the provided streaming session
+     */
+    public boolean startStreaming(MbmsStreamingSession streamingManager) {
+        mStreamingService =
+                streamingManager.startStreaming(mStreamingServiceInfo, new Callback(), null);
+        return true;
     }
 
     public void stopStreaming() {
-        try {
-            mStreamingService.stopStreaming();
-        } catch (MbmsException e) {
-            Toast.makeText(mActivity,
-                    "Error stopping streaming: " + e.getErrorCode(),
-                    Toast.LENGTH_SHORT).show();
-        }
-    }
-
-    public void dispose() {
-        try {
-            mStreamingService.dispose();
-        } catch (MbmsException e) {
-            Toast.makeText(mActivity,
-                    "Error disposing stream" + e.getErrorCode(),
-                    Toast.LENGTH_SHORT).show();
-        }
+        mStreamingService.stopStreaming();
     }
 
     public String getServiceId() {
@@ -108,14 +87,8 @@
 
     private void onStreamStateUpdated(int state, int reason) {
         if (state == StreamingService.STATE_STARTED && mState != StreamingService.STATE_STARTED) {
-            try {
-                mStreamingUri = mStreamingService.getPlaybackUri();
-                mActivity.updateUri();
-            } catch (MbmsException e) {
-                String errorToast = "Got error " + e.getErrorCode() + " while getting uri";
-                mActivity.runOnUiThread(() ->
-                        Toast.makeText(mActivity, errorToast, Toast.LENGTH_SHORT).show());
-            }
+            mStreamingUri = mStreamingService.getPlaybackUri();
+            mActivity.updateUri();
         }
         mState = state;
         mActivity.updateStreamingState();