Loading src/java/com/android/internal/telephony/ims/ImsResolver.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -382,9 +382,12 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal maybeRebindService(slotId, packageName); maybeRebindService(slotId, packageName); } else { } else { Log.i(TAG, "overriding device ImsService - packageName=" + packageName); Log.i(TAG, "overriding device ImsService - packageName=" + packageName); if (packageName == null || packageName.isEmpty()) { if (TextUtils.equals(mDeviceService, packageName)) { unbindImsService(getImsServiceInfoFromCache(mDeviceService)); // No change in device service. break; } } // Unbind from the previous ImsService before binding to the new one. unbindImsService(getImsServiceInfoFromCache(mDeviceService)); mDeviceService = packageName; mDeviceService = packageName; ImsServiceInfo deviceInfo = getImsServiceInfoFromCache(mDeviceService); ImsServiceInfo deviceInfo = getImsServiceInfoFromCache(mDeviceService); if (deviceInfo == null) { if (deviceInfo == null) { Loading src/java/com/android/internal/telephony/ims/ImsServiceController.java +9 −42 Original line number Original line Diff line number Diff line Loading @@ -58,32 +58,11 @@ import java.util.concurrent.ConcurrentHashMap; * listener that the ImsService now supports that feature. * listener that the ImsService now supports that feature. * * * When {@link #changeImsServiceFeatures} is called with a set of features that is different from * When {@link #changeImsServiceFeatures} is called with a set of features that is different from * the original set, create and {@link IImsServiceController#removeImsFeature} will be called for * the original set, create*Feature and {@link IImsServiceController#removeImsFeature} will be * each feature that is created/removed. * called for each feature that is created/removed. */ */ public class ImsServiceController { public class ImsServiceController { class ImsDeathRecipient implements IBinder.DeathRecipient { private ComponentName mComponentName; ImsDeathRecipient(ComponentName name) { mComponentName = name; } @Override public void binderDied() { Log.e(LOG_TAG, "ImsService(" + mComponentName + ") died. Restarting..."); synchronized (mLock) { mIsBinding = false; mIsBound = false; } cleanupAllFeatures(); cleanUpService(); startDelayedRebindToService(); } } class ImsServiceConnection implements ServiceConnection { class ImsServiceConnection implements ServiceConnection { @Override @Override Loading @@ -95,10 +74,7 @@ public class ImsServiceController { Log.d(LOG_TAG, "ImsService(" + name + "): onServiceConnected with binder: " Log.d(LOG_TAG, "ImsService(" + name + "): onServiceConnected with binder: " + service); + service); if (service != null) { if (service != null) { mImsDeathRecipient = new ImsDeathRecipient(name); try { try { service.linkToDeath(mImsDeathRecipient, 0); mImsServiceControllerBinder = service; setServiceController(service); setServiceController(service); notifyImsServiceReady(); notifyImsServiceReady(); // create all associated features in the ImsService // create all associated features in the ImsService Loading @@ -109,9 +85,8 @@ public class ImsServiceController { mIsBound = false; mIsBound = false; mIsBinding = false; mIsBinding = false; // Remote exception means that the binder already died. // Remote exception means that the binder already died. if (mImsDeathRecipient != null) { cleanupConnection(); mImsDeathRecipient.binderDied(); startDelayedRebindToService(); } Log.e(LOG_TAG, "ImsService(" + name + ") RemoteException:" Log.e(LOG_TAG, "ImsService(" + name + ") RemoteException:" + e.getMessage()); + e.getMessage()); } } Loading Loading @@ -141,9 +116,6 @@ public class ImsServiceController { } } private void cleanupConnection() { private void cleanupConnection() { if (isServiceControllerAvailable()) { mImsServiceControllerBinder.unlinkToDeath(mImsDeathRecipient, 0); } cleanupAllFeatures(); cleanupAllFeatures(); cleanUpService(); cleanUpService(); } } Loading Loading @@ -215,9 +187,7 @@ public class ImsServiceController { // Binder interfaces to the features set in mImsFeatures; // Binder interfaces to the features set in mImsFeatures; private HashSet<ImsFeatureContainer> mImsFeatureBinders = new HashSet<>(); private HashSet<ImsFeatureContainer> mImsFeatureBinders = new HashSet<>(); private IImsServiceController mIImsServiceController; private IImsServiceController mIImsServiceController; private IBinder mImsServiceControllerBinder; private ImsServiceConnection mImsServiceConnection; private ImsServiceConnection mImsServiceConnection; private ImsDeathRecipient mImsDeathRecipient; private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = ConcurrentHashMap.newKeySet(); private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = ConcurrentHashMap.newKeySet(); // Only added or removed, never accessed on purpose. // Only added or removed, never accessed on purpose. private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>(); private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>(); Loading Loading @@ -406,13 +376,12 @@ public class ImsServiceController { public void unbind() throws RemoteException { public void unbind() throws RemoteException { synchronized (mLock) { synchronized (mLock) { mBackoff.stop(); mBackoff.stop(); if (mImsServiceConnection == null || mImsDeathRecipient == null) { if (mImsServiceConnection == null) { return; return; } } // Clean up all features // Clean up all features changeImsServiceFeatures(new HashSet<>()); changeImsServiceFeatures(new HashSet<>()); removeImsServiceFeatureCallbacks(); removeImsServiceFeatureCallbacks(); mImsServiceControllerBinder.unlinkToDeath(mImsDeathRecipient, 0); Log.i(LOG_TAG, "Unbinding ImsService: " + mComponentName); Log.i(LOG_TAG, "Unbinding ImsService: " + mComponentName); mContext.unbindService(mImsServiceConnection); mContext.unbindService(mImsServiceConnection); cleanUpService(); cleanUpService(); Loading Loading @@ -458,13 +427,13 @@ public class ImsServiceController { } } @VisibleForTesting @VisibleForTesting public IBinder getImsServiceControllerBinder() { public long getRebindDelay() { return mImsServiceControllerBinder; return mBackoff.getCurrentDelay(); } } @VisibleForTesting @VisibleForTesting public long getRebindDelay() { public void stopBackoffTimerForTesting() { return mBackoff.getCurrentDelay(); mBackoff.stop(); } } public ComponentName getComponentName() { public ComponentName getComponentName() { Loading Loading @@ -794,9 +763,7 @@ public class ImsServiceController { private void cleanUpService() { private void cleanUpService() { synchronized (mLock) { synchronized (mLock) { mImsDeathRecipient = null; mImsServiceConnection = null; mImsServiceConnection = null; mImsServiceControllerBinder = null; setServiceController(null); setServiceController(null); } } } } Loading src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -40,9 +40,9 @@ import com.android.ims.internal.IImsServiceController; * ImsService will support. * ImsService will support. * * * Compatibility interface for interacting with older implementations of ImsService. The older * Compatibility interface for interacting with older implementations of ImsService. The older * ImsService implementation is contained within the android.telephony.ims.compat.* namspace. * ImsService implementation is contained within the android.telephony.ims.compat.* namespace. * Newer implementations of ImsService should use the current APIs contained in * Newer implementations of ImsService should use the current APIs contained in * android.telephony.ims.compat.*. * android.telephony.ims.*. */ */ public class ImsServiceControllerCompat extends ImsServiceController { public class ImsServiceControllerCompat extends ImsServiceController { Loading src/java/com/android/internal/telephony/ims/ImsServiceControllerStaticCompat.java +40 −2 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.internal.telephony.ims; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.util.Log; import android.util.Log; Loading @@ -37,7 +39,27 @@ public class ImsServiceControllerStaticCompat extends ImsServiceControllerCompat private static final String IMS_SERVICE_NAME = "ims"; private static final String IMS_SERVICE_NAME = "ims"; private class ImsDeathRecipient implements IBinder.DeathRecipient { private ComponentName mComponentName; private ServiceConnection mServiceConnection; ImsDeathRecipient(ComponentName name, ServiceConnection conn) { mComponentName = name; mServiceConnection = conn; } @Override public void binderDied() { Log.e(TAG, "ImsService(" + mComponentName + ") died. Restarting..."); // This is hacky... ImsServiceController uses the traditional service binding procedure, // so we have to emulate it when using a persistent service. mServiceConnection.onBindingDied(mComponentName); } } private IImsService mImsServiceCompat = null; private IImsService mImsServiceCompat = null; private ImsDeathRecipient mImsDeathRecipient = null; public ImsServiceControllerStaticCompat(Context context, ComponentName componentName, public ImsServiceControllerStaticCompat(Context context, ComponentName componentName, ImsServiceController.ImsServiceControllerCallbacks callbacks) { ImsServiceController.ImsServiceControllerCallbacks callbacks) { Loading @@ -54,13 +76,29 @@ public class ImsServiceControllerStaticCompat extends ImsServiceControllerCompat // This is a little hacky, but we are going to call the onServiceConnected to "pretend" like // This is a little hacky, but we are going to call the onServiceConnected to "pretend" like // bindService has completed here, which will pass the binder to setServiceController and // bindService has completed here, which will pass the binder to setServiceController and // set up all supporting structures. // set up all supporting structures. connection.onServiceConnected(new ComponentName(mContext, ComponentName name = new ComponentName(mContext, ImsServiceControllerStaticCompat.class); ImsServiceControllerStaticCompat.class), binder); connection.onServiceConnected(name, binder); try { mImsDeathRecipient = new ImsDeathRecipient(name, connection); binder.linkToDeath(mImsDeathRecipient, 0); } catch (RemoteException e) { // The binder connection is already dead.. signal to the ImsServiceController to retry. mImsDeathRecipient.binderDied(); mImsDeathRecipient = null; } return true; return true; } } @Override @Override protected void setServiceController(IBinder serviceController) { protected void setServiceController(IBinder serviceController) { if (serviceController == null) { // The service controller has been set to null, meaning it has been unbound or died. // Unlink if needed. if (mImsServiceCompat != null) { mImsServiceCompat.asBinder().unlinkToDeath(mImsDeathRecipient, 0); } mImsDeathRecipient = null; } mImsServiceCompat = IImsService.Stub.asInterface(serviceController); mImsServiceCompat = IImsService.Stub.asInterface(serviceController); } } Loading tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java +55 −77 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/ims/ImsResolver.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -382,9 +382,12 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal maybeRebindService(slotId, packageName); maybeRebindService(slotId, packageName); } else { } else { Log.i(TAG, "overriding device ImsService - packageName=" + packageName); Log.i(TAG, "overriding device ImsService - packageName=" + packageName); if (packageName == null || packageName.isEmpty()) { if (TextUtils.equals(mDeviceService, packageName)) { unbindImsService(getImsServiceInfoFromCache(mDeviceService)); // No change in device service. break; } } // Unbind from the previous ImsService before binding to the new one. unbindImsService(getImsServiceInfoFromCache(mDeviceService)); mDeviceService = packageName; mDeviceService = packageName; ImsServiceInfo deviceInfo = getImsServiceInfoFromCache(mDeviceService); ImsServiceInfo deviceInfo = getImsServiceInfoFromCache(mDeviceService); if (deviceInfo == null) { if (deviceInfo == null) { Loading
src/java/com/android/internal/telephony/ims/ImsServiceController.java +9 −42 Original line number Original line Diff line number Diff line Loading @@ -58,32 +58,11 @@ import java.util.concurrent.ConcurrentHashMap; * listener that the ImsService now supports that feature. * listener that the ImsService now supports that feature. * * * When {@link #changeImsServiceFeatures} is called with a set of features that is different from * When {@link #changeImsServiceFeatures} is called with a set of features that is different from * the original set, create and {@link IImsServiceController#removeImsFeature} will be called for * the original set, create*Feature and {@link IImsServiceController#removeImsFeature} will be * each feature that is created/removed. * called for each feature that is created/removed. */ */ public class ImsServiceController { public class ImsServiceController { class ImsDeathRecipient implements IBinder.DeathRecipient { private ComponentName mComponentName; ImsDeathRecipient(ComponentName name) { mComponentName = name; } @Override public void binderDied() { Log.e(LOG_TAG, "ImsService(" + mComponentName + ") died. Restarting..."); synchronized (mLock) { mIsBinding = false; mIsBound = false; } cleanupAllFeatures(); cleanUpService(); startDelayedRebindToService(); } } class ImsServiceConnection implements ServiceConnection { class ImsServiceConnection implements ServiceConnection { @Override @Override Loading @@ -95,10 +74,7 @@ public class ImsServiceController { Log.d(LOG_TAG, "ImsService(" + name + "): onServiceConnected with binder: " Log.d(LOG_TAG, "ImsService(" + name + "): onServiceConnected with binder: " + service); + service); if (service != null) { if (service != null) { mImsDeathRecipient = new ImsDeathRecipient(name); try { try { service.linkToDeath(mImsDeathRecipient, 0); mImsServiceControllerBinder = service; setServiceController(service); setServiceController(service); notifyImsServiceReady(); notifyImsServiceReady(); // create all associated features in the ImsService // create all associated features in the ImsService Loading @@ -109,9 +85,8 @@ public class ImsServiceController { mIsBound = false; mIsBound = false; mIsBinding = false; mIsBinding = false; // Remote exception means that the binder already died. // Remote exception means that the binder already died. if (mImsDeathRecipient != null) { cleanupConnection(); mImsDeathRecipient.binderDied(); startDelayedRebindToService(); } Log.e(LOG_TAG, "ImsService(" + name + ") RemoteException:" Log.e(LOG_TAG, "ImsService(" + name + ") RemoteException:" + e.getMessage()); + e.getMessage()); } } Loading Loading @@ -141,9 +116,6 @@ public class ImsServiceController { } } private void cleanupConnection() { private void cleanupConnection() { if (isServiceControllerAvailable()) { mImsServiceControllerBinder.unlinkToDeath(mImsDeathRecipient, 0); } cleanupAllFeatures(); cleanupAllFeatures(); cleanUpService(); cleanUpService(); } } Loading Loading @@ -215,9 +187,7 @@ public class ImsServiceController { // Binder interfaces to the features set in mImsFeatures; // Binder interfaces to the features set in mImsFeatures; private HashSet<ImsFeatureContainer> mImsFeatureBinders = new HashSet<>(); private HashSet<ImsFeatureContainer> mImsFeatureBinders = new HashSet<>(); private IImsServiceController mIImsServiceController; private IImsServiceController mIImsServiceController; private IBinder mImsServiceControllerBinder; private ImsServiceConnection mImsServiceConnection; private ImsServiceConnection mImsServiceConnection; private ImsDeathRecipient mImsDeathRecipient; private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = ConcurrentHashMap.newKeySet(); private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = ConcurrentHashMap.newKeySet(); // Only added or removed, never accessed on purpose. // Only added or removed, never accessed on purpose. private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>(); private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>(); Loading Loading @@ -406,13 +376,12 @@ public class ImsServiceController { public void unbind() throws RemoteException { public void unbind() throws RemoteException { synchronized (mLock) { synchronized (mLock) { mBackoff.stop(); mBackoff.stop(); if (mImsServiceConnection == null || mImsDeathRecipient == null) { if (mImsServiceConnection == null) { return; return; } } // Clean up all features // Clean up all features changeImsServiceFeatures(new HashSet<>()); changeImsServiceFeatures(new HashSet<>()); removeImsServiceFeatureCallbacks(); removeImsServiceFeatureCallbacks(); mImsServiceControllerBinder.unlinkToDeath(mImsDeathRecipient, 0); Log.i(LOG_TAG, "Unbinding ImsService: " + mComponentName); Log.i(LOG_TAG, "Unbinding ImsService: " + mComponentName); mContext.unbindService(mImsServiceConnection); mContext.unbindService(mImsServiceConnection); cleanUpService(); cleanUpService(); Loading Loading @@ -458,13 +427,13 @@ public class ImsServiceController { } } @VisibleForTesting @VisibleForTesting public IBinder getImsServiceControllerBinder() { public long getRebindDelay() { return mImsServiceControllerBinder; return mBackoff.getCurrentDelay(); } } @VisibleForTesting @VisibleForTesting public long getRebindDelay() { public void stopBackoffTimerForTesting() { return mBackoff.getCurrentDelay(); mBackoff.stop(); } } public ComponentName getComponentName() { public ComponentName getComponentName() { Loading Loading @@ -794,9 +763,7 @@ public class ImsServiceController { private void cleanUpService() { private void cleanUpService() { synchronized (mLock) { synchronized (mLock) { mImsDeathRecipient = null; mImsServiceConnection = null; mImsServiceConnection = null; mImsServiceControllerBinder = null; setServiceController(null); setServiceController(null); } } } } Loading
src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -40,9 +40,9 @@ import com.android.ims.internal.IImsServiceController; * ImsService will support. * ImsService will support. * * * Compatibility interface for interacting with older implementations of ImsService. The older * Compatibility interface for interacting with older implementations of ImsService. The older * ImsService implementation is contained within the android.telephony.ims.compat.* namspace. * ImsService implementation is contained within the android.telephony.ims.compat.* namespace. * Newer implementations of ImsService should use the current APIs contained in * Newer implementations of ImsService should use the current APIs contained in * android.telephony.ims.compat.*. * android.telephony.ims.*. */ */ public class ImsServiceControllerCompat extends ImsServiceController { public class ImsServiceControllerCompat extends ImsServiceController { Loading
src/java/com/android/internal/telephony/ims/ImsServiceControllerStaticCompat.java +40 −2 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.internal.telephony.ims; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.util.Log; import android.util.Log; Loading @@ -37,7 +39,27 @@ public class ImsServiceControllerStaticCompat extends ImsServiceControllerCompat private static final String IMS_SERVICE_NAME = "ims"; private static final String IMS_SERVICE_NAME = "ims"; private class ImsDeathRecipient implements IBinder.DeathRecipient { private ComponentName mComponentName; private ServiceConnection mServiceConnection; ImsDeathRecipient(ComponentName name, ServiceConnection conn) { mComponentName = name; mServiceConnection = conn; } @Override public void binderDied() { Log.e(TAG, "ImsService(" + mComponentName + ") died. Restarting..."); // This is hacky... ImsServiceController uses the traditional service binding procedure, // so we have to emulate it when using a persistent service. mServiceConnection.onBindingDied(mComponentName); } } private IImsService mImsServiceCompat = null; private IImsService mImsServiceCompat = null; private ImsDeathRecipient mImsDeathRecipient = null; public ImsServiceControllerStaticCompat(Context context, ComponentName componentName, public ImsServiceControllerStaticCompat(Context context, ComponentName componentName, ImsServiceController.ImsServiceControllerCallbacks callbacks) { ImsServiceController.ImsServiceControllerCallbacks callbacks) { Loading @@ -54,13 +76,29 @@ public class ImsServiceControllerStaticCompat extends ImsServiceControllerCompat // This is a little hacky, but we are going to call the onServiceConnected to "pretend" like // This is a little hacky, but we are going to call the onServiceConnected to "pretend" like // bindService has completed here, which will pass the binder to setServiceController and // bindService has completed here, which will pass the binder to setServiceController and // set up all supporting structures. // set up all supporting structures. connection.onServiceConnected(new ComponentName(mContext, ComponentName name = new ComponentName(mContext, ImsServiceControllerStaticCompat.class); ImsServiceControllerStaticCompat.class), binder); connection.onServiceConnected(name, binder); try { mImsDeathRecipient = new ImsDeathRecipient(name, connection); binder.linkToDeath(mImsDeathRecipient, 0); } catch (RemoteException e) { // The binder connection is already dead.. signal to the ImsServiceController to retry. mImsDeathRecipient.binderDied(); mImsDeathRecipient = null; } return true; return true; } } @Override @Override protected void setServiceController(IBinder serviceController) { protected void setServiceController(IBinder serviceController) { if (serviceController == null) { // The service controller has been set to null, meaning it has been unbound or died. // Unlink if needed. if (mImsServiceCompat != null) { mImsServiceCompat.asBinder().unlinkToDeath(mImsDeathRecipient, 0); } mImsDeathRecipient = null; } mImsServiceCompat = IImsService.Stub.asInterface(serviceController); mImsServiceCompat = IImsService.Stub.asInterface(serviceController); } } Loading
tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java +55 −77 File changed.Preview size limit exceeded, changes collapsed. Show changes