Loading telephony/java/android/telephony/MbmsDownloadManager.java +5 −5 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.telephony.mbms.DownloadCallback; import android.telephony.mbms.DownloadRequest; import android.telephony.mbms.DownloadStatus; import android.telephony.mbms.IMbmsDownloadManagerCallback; import android.telephony.mbms.MbmsInitializationException; import android.telephony.mbms.MbmsException; import android.telephony.mbms.vendor.IMbmsDownloadService; import android.util.Log; Loading Loading @@ -172,7 +172,7 @@ public class MbmsDownloadManager { */ public static MbmsDownloadManager createManager(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName) throws MbmsInitializationException{ throws MbmsException { MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName, SubscriptionManager.getDefaultSubscriptionId()); mdm.bindAndInitialize(); Loading @@ -190,19 +190,19 @@ public class MbmsDownloadManager { public static MbmsDownloadManager createManager(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName, int subId) throws MbmsInitializationException { throws MbmsException { MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName, subId); mdm.bindAndInitialize(); return mdm; } private void bindAndInitialize() throws MbmsInitializationException { private void bindAndInitialize() throws MbmsException { // TODO: bind try { mService.initialize(mDownloadAppName, mSubId, mCallback); } catch (RemoteException e) { throw new MbmsInitializationException(0); // TODO: proper error code throw new MbmsException(0); // TODO: proper error code } } Loading telephony/java/android/telephony/MbmsStreamingManager.java +129 −23 Original line number Diff line number Diff line Loading @@ -16,25 +16,68 @@ package android.telephony; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.DeadObjectException; import android.os.IBinder; import android.os.RemoteException; import android.telephony.mbms.IMbmsStreamingManagerCallback; import android.telephony.mbms.IStreamingServiceCallback; import android.telephony.mbms.MbmsInitializationException; import android.telephony.mbms.MbmsException; import android.telephony.mbms.StreamingService; import android.telephony.mbms.StreamingServiceInfo; import android.telephony.mbms.vendor.IMbmsStreamingService; import android.util.Log; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; /** @hide */ public class MbmsStreamingManager { private interface ServiceListener { void onServiceConnected(); void onServiceDisconnected(); } private static final String LOG_TAG = "MbmsStreamingManager"; public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; private static final boolean DEBUG = true; private static final int BIND_TIMEOUT_MS = 3000; private IMbmsStreamingService mService; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { if (service != null) { Log.i(LOG_TAG, String.format("Connected to service %s", name)); synchronized (MbmsStreamingManager.this) { mService = IMbmsStreamingService.Stub.asInterface(service); mServiceListeners.forEach(ServiceListener::onServiceConnected); } } } @Override public void onServiceDisconnected(ComponentName name) { Log.i(LOG_TAG, String.format("Disconnected from service %s", name)); synchronized (MbmsStreamingManager.this) { mService = null; mServiceListeners.forEach(ServiceListener::onServiceDisconnected); } } }; private List<ServiceListener> mServiceListeners = new LinkedList<>(); private IMbmsStreamingManagerCallback mCallbackToApp; private final String mAppName; Loading @@ -54,9 +97,8 @@ public class MbmsStreamingManager { * Create a new MbmsStreamingManager using the given subscription ID. * * Note that this call will bind a remote service and that may take a bit. This * may throw an IllegalArgumentException or RemoteException. * TODO: document this and add exceptions that can be thrown for synchronous * initialization/bind errors * may throw an {@link MbmsException}, indicating errors that may happen during * the initialization or binding process. * * @param context * @param listener Loading @@ -66,7 +108,7 @@ public class MbmsStreamingManager { */ public static MbmsStreamingManager create(Context context, IMbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId) throws MbmsInitializationException { throws MbmsException { MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, streamingAppName, subscriptionId); manager.bindAndInitialize(); Loading @@ -81,9 +123,8 @@ public class MbmsStreamingManager { */ public static MbmsStreamingManager create(Context context, IMbmsStreamingManagerCallback listener, String streamingAppName) throws MbmsInitializationException { // TODO: get default sub id int subId = INVALID_SUBSCRIPTION_ID; throws MbmsException { int subId = SubscriptionManager.getDefaultSubscriptionId(); MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, streamingAppName, subId); manager.bindAndInitialize(); Loading @@ -94,8 +135,17 @@ public class MbmsStreamingManager { * Terminates this instance, ending calls to the registered listener. Also terminates * any streaming services spawned from this instance. */ public void dispose() { // service.dispose(streamingAppName); public synchronized void dispose() { if (mService == null) { // Ignore and return, assume already disposed. return; } try { mService.dispose(mAppName, mSubscriptionId); } catch (RemoteException e) { // Ignore for now } mService = null; } /** Loading Loading @@ -155,23 +205,79 @@ public class MbmsStreamingManager { return 0; } private void logd(String str) { Log.d(LOG_TAG, str); private void bindAndInitialize() throws MbmsException { // Query for the proper service PackageManager packageManager = mContext.getPackageManager(); Intent queryIntent = new Intent(); queryIntent.setAction(MBMS_STREAMING_SERVICE_ACTION); List<ResolveInfo> streamingServices = packageManager.queryIntentServices(queryIntent, PackageManager.MATCH_SYSTEM_ONLY); if (streamingServices == null || streamingServices.size() == 0) { throw new MbmsException( MbmsException.ERROR_NO_SERVICE_INSTALLED); } if (streamingServices.size() > 1) { throw new MbmsException( MbmsException.ERROR_MULTIPLE_SERVICES_INSTALLED); } private boolean isServiceConnected() { return mService != null; // Kick off the binding, and synchronously wait until binding is complete final CountDownLatch latch = new CountDownLatch(1); ServiceListener bindListener = new ServiceListener() { @Override public void onServiceConnected() { latch.countDown(); } @Override public void onServiceDisconnected() { } }; synchronized (this) { mServiceListeners.add(bindListener); } Intent bindIntent = new Intent(); bindIntent.setComponent(streamingServices.get(0).getComponentInfo().getComponentName()); mContext.bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE); waitOnLatchWithTimeout(latch, BIND_TIMEOUT_MS); // Remove the listener and call the initialization method through the interface. synchronized (this) { mServiceListeners.remove(bindListener); if (mService == null) { throw new MbmsException(MbmsException.ERROR_BIND_TIMEOUT_OR_FAILURE); } private void bindAndInitialize() throws MbmsInitializationException { // TODO: bind to the service try { int returnCode = mService.initialize(mCallbackToApp, mAppName, mSubscriptionId); if (returnCode != 0) { throw new MbmsInitializationException(returnCode); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } } catch (RemoteException e) { throw new MbmsInitializationException(/* some error */ 0); mService = null; Log.e(LOG_TAG, "Service died before initialization"); throw new MbmsException(MbmsException.ERROR_INITIALIZATION_REMOTE_EXCEPTION); } } } private static void waitOnLatchWithTimeout(CountDownLatch l, long timeoutMs) { long endTime = System.currentTimeMillis() + timeoutMs; while (System.currentTimeMillis() < endTime) { try { l.await(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // keep waiting } if (l.getCount() <= 0) { return; } } } } telephony/java/android/telephony/mbms/MbmsInitializationException.java→telephony/java/android/telephony/mbms/MbmsException.java +14 −3 Original line number Diff line number Diff line Loading @@ -16,12 +16,23 @@ package android.telephony.mbms; import android.os.RemoteException; /** @hide */ public class MbmsInitializationException extends Exception { public class MbmsException extends RemoteException { public static final int SUCCESS = 0; public static final int ERROR_NO_SERVICE_INSTALLED = 1; public static final int ERROR_MULTIPLE_SERVICES_INSTALLED = 2; public static final int ERROR_BIND_TIMEOUT_OR_FAILURE = 3; public static final int ERROR_INITIALIZATION_REMOTE_EXCEPTION = 4; public static final int ERROR_ALREADY_INITIALIZED = 5; private final int mErrorCode; /** @hide */ public MbmsInitializationException(int errorCode) { /** @hide * TODO: future systemapi * */ public MbmsException(int errorCode) { super(); mErrorCode = errorCode; } Loading Loading
telephony/java/android/telephony/MbmsDownloadManager.java +5 −5 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.telephony.mbms.DownloadCallback; import android.telephony.mbms.DownloadRequest; import android.telephony.mbms.DownloadStatus; import android.telephony.mbms.IMbmsDownloadManagerCallback; import android.telephony.mbms.MbmsInitializationException; import android.telephony.mbms.MbmsException; import android.telephony.mbms.vendor.IMbmsDownloadService; import android.util.Log; Loading Loading @@ -172,7 +172,7 @@ public class MbmsDownloadManager { */ public static MbmsDownloadManager createManager(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName) throws MbmsInitializationException{ throws MbmsException { MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName, SubscriptionManager.getDefaultSubscriptionId()); mdm.bindAndInitialize(); Loading @@ -190,19 +190,19 @@ public class MbmsDownloadManager { public static MbmsDownloadManager createManager(Context context, IMbmsDownloadManagerCallback listener, String downloadAppName, int subId) throws MbmsInitializationException { throws MbmsException { MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName, subId); mdm.bindAndInitialize(); return mdm; } private void bindAndInitialize() throws MbmsInitializationException { private void bindAndInitialize() throws MbmsException { // TODO: bind try { mService.initialize(mDownloadAppName, mSubId, mCallback); } catch (RemoteException e) { throw new MbmsInitializationException(0); // TODO: proper error code throw new MbmsException(0); // TODO: proper error code } } Loading
telephony/java/android/telephony/MbmsStreamingManager.java +129 −23 Original line number Diff line number Diff line Loading @@ -16,25 +16,68 @@ package android.telephony; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.DeadObjectException; import android.os.IBinder; import android.os.RemoteException; import android.telephony.mbms.IMbmsStreamingManagerCallback; import android.telephony.mbms.IStreamingServiceCallback; import android.telephony.mbms.MbmsInitializationException; import android.telephony.mbms.MbmsException; import android.telephony.mbms.StreamingService; import android.telephony.mbms.StreamingServiceInfo; import android.telephony.mbms.vendor.IMbmsStreamingService; import android.util.Log; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; /** @hide */ public class MbmsStreamingManager { private interface ServiceListener { void onServiceConnected(); void onServiceDisconnected(); } private static final String LOG_TAG = "MbmsStreamingManager"; public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; private static final boolean DEBUG = true; private static final int BIND_TIMEOUT_MS = 3000; private IMbmsStreamingService mService; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { if (service != null) { Log.i(LOG_TAG, String.format("Connected to service %s", name)); synchronized (MbmsStreamingManager.this) { mService = IMbmsStreamingService.Stub.asInterface(service); mServiceListeners.forEach(ServiceListener::onServiceConnected); } } } @Override public void onServiceDisconnected(ComponentName name) { Log.i(LOG_TAG, String.format("Disconnected from service %s", name)); synchronized (MbmsStreamingManager.this) { mService = null; mServiceListeners.forEach(ServiceListener::onServiceDisconnected); } } }; private List<ServiceListener> mServiceListeners = new LinkedList<>(); private IMbmsStreamingManagerCallback mCallbackToApp; private final String mAppName; Loading @@ -54,9 +97,8 @@ public class MbmsStreamingManager { * Create a new MbmsStreamingManager using the given subscription ID. * * Note that this call will bind a remote service and that may take a bit. This * may throw an IllegalArgumentException or RemoteException. * TODO: document this and add exceptions that can be thrown for synchronous * initialization/bind errors * may throw an {@link MbmsException}, indicating errors that may happen during * the initialization or binding process. * * @param context * @param listener Loading @@ -66,7 +108,7 @@ public class MbmsStreamingManager { */ public static MbmsStreamingManager create(Context context, IMbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId) throws MbmsInitializationException { throws MbmsException { MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, streamingAppName, subscriptionId); manager.bindAndInitialize(); Loading @@ -81,9 +123,8 @@ public class MbmsStreamingManager { */ public static MbmsStreamingManager create(Context context, IMbmsStreamingManagerCallback listener, String streamingAppName) throws MbmsInitializationException { // TODO: get default sub id int subId = INVALID_SUBSCRIPTION_ID; throws MbmsException { int subId = SubscriptionManager.getDefaultSubscriptionId(); MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, streamingAppName, subId); manager.bindAndInitialize(); Loading @@ -94,8 +135,17 @@ public class MbmsStreamingManager { * Terminates this instance, ending calls to the registered listener. Also terminates * any streaming services spawned from this instance. */ public void dispose() { // service.dispose(streamingAppName); public synchronized void dispose() { if (mService == null) { // Ignore and return, assume already disposed. return; } try { mService.dispose(mAppName, mSubscriptionId); } catch (RemoteException e) { // Ignore for now } mService = null; } /** Loading Loading @@ -155,23 +205,79 @@ public class MbmsStreamingManager { return 0; } private void logd(String str) { Log.d(LOG_TAG, str); private void bindAndInitialize() throws MbmsException { // Query for the proper service PackageManager packageManager = mContext.getPackageManager(); Intent queryIntent = new Intent(); queryIntent.setAction(MBMS_STREAMING_SERVICE_ACTION); List<ResolveInfo> streamingServices = packageManager.queryIntentServices(queryIntent, PackageManager.MATCH_SYSTEM_ONLY); if (streamingServices == null || streamingServices.size() == 0) { throw new MbmsException( MbmsException.ERROR_NO_SERVICE_INSTALLED); } if (streamingServices.size() > 1) { throw new MbmsException( MbmsException.ERROR_MULTIPLE_SERVICES_INSTALLED); } private boolean isServiceConnected() { return mService != null; // Kick off the binding, and synchronously wait until binding is complete final CountDownLatch latch = new CountDownLatch(1); ServiceListener bindListener = new ServiceListener() { @Override public void onServiceConnected() { latch.countDown(); } @Override public void onServiceDisconnected() { } }; synchronized (this) { mServiceListeners.add(bindListener); } Intent bindIntent = new Intent(); bindIntent.setComponent(streamingServices.get(0).getComponentInfo().getComponentName()); mContext.bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE); waitOnLatchWithTimeout(latch, BIND_TIMEOUT_MS); // Remove the listener and call the initialization method through the interface. synchronized (this) { mServiceListeners.remove(bindListener); if (mService == null) { throw new MbmsException(MbmsException.ERROR_BIND_TIMEOUT_OR_FAILURE); } private void bindAndInitialize() throws MbmsInitializationException { // TODO: bind to the service try { int returnCode = mService.initialize(mCallbackToApp, mAppName, mSubscriptionId); if (returnCode != 0) { throw new MbmsInitializationException(returnCode); if (returnCode != MbmsException.SUCCESS) { throw new MbmsException(returnCode); } } catch (RemoteException e) { throw new MbmsInitializationException(/* some error */ 0); mService = null; Log.e(LOG_TAG, "Service died before initialization"); throw new MbmsException(MbmsException.ERROR_INITIALIZATION_REMOTE_EXCEPTION); } } } private static void waitOnLatchWithTimeout(CountDownLatch l, long timeoutMs) { long endTime = System.currentTimeMillis() + timeoutMs; while (System.currentTimeMillis() < endTime) { try { l.await(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // keep waiting } if (l.getCount() <= 0) { return; } } } }
telephony/java/android/telephony/mbms/MbmsInitializationException.java→telephony/java/android/telephony/mbms/MbmsException.java +14 −3 Original line number Diff line number Diff line Loading @@ -16,12 +16,23 @@ package android.telephony.mbms; import android.os.RemoteException; /** @hide */ public class MbmsInitializationException extends Exception { public class MbmsException extends RemoteException { public static final int SUCCESS = 0; public static final int ERROR_NO_SERVICE_INSTALLED = 1; public static final int ERROR_MULTIPLE_SERVICES_INSTALLED = 2; public static final int ERROR_BIND_TIMEOUT_OR_FAILURE = 3; public static final int ERROR_INITIALIZATION_REMOTE_EXCEPTION = 4; public static final int ERROR_ALREADY_INITIALIZED = 5; private final int mErrorCode; /** @hide */ public MbmsInitializationException(int errorCode) { /** @hide * TODO: future systemapi * */ public MbmsException(int errorCode) { super(); mErrorCode = errorCode; } Loading