Loading src/java/com/android/internal/telephony/ims/ImsServiceController.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,9 @@ import java.util.stream.Collectors; public class ImsServiceController { public class ImsServiceController { class ImsServiceConnection implements ServiceConnection { class ImsServiceConnection implements ServiceConnection { // Track the status of whether or not the Service has died in case we need to permanently // unbind (see onNullBinding below). private boolean mIsServiceConnectionDead = false; @Override @Override public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) { Loading Loading @@ -114,6 +117,7 @@ public class ImsServiceController { @Override @Override public void onBindingDied(ComponentName name) { public void onBindingDied(ComponentName name) { mIsServiceConnectionDead = true; synchronized (mLock) { synchronized (mLock) { mIsBinding = false; mIsBinding = false; mIsBound = false; mIsBound = false; Loading @@ -128,8 +132,12 @@ public class ImsServiceController { @Override @Override public void onNullBinding(ComponentName name) { public void onNullBinding(ComponentName name) { Log.w(LOG_TAG, "ImsService(" + name + "): onNullBinding. Removing."); Log.w(LOG_TAG, "ImsService(" + name + "): onNullBinding. Is service dead = " mLocalLog.log("onNullBinding"); + mIsServiceConnectionDead); mLocalLog.log("onNullBinding, is service dead = " + mIsServiceConnectionDead); // onNullBinding will happen after onBindingDied. In this case, we should not // permanently unbind and instead let the automatic rebind occur. if (mIsServiceConnectionDead) return; synchronized (mLock) { synchronized (mLock) { mIsBinding = false; mIsBinding = false; // Service connection exists, so we are bound but the binder is null. Wait for // Service connection exists, so we are bound but the binder is null. Wait for Loading tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java +24 −0 Original line number Original line Diff line number Diff line Loading @@ -600,6 +600,30 @@ public class ImsServiceControllerTest extends ImsTestBase { verify(mMockContext, times(2)).bindService(any(), any(), anyInt()); verify(mMockContext, times(2)).bindService(any(), any(), anyInt()); } } /** * Due to a bug in ServiceConnection, we will sometimes receive a null binding after the binding * dies. Ignore null binding in this case. */ @SmallTest @Test public void testAutoBindAfterBinderDiedIgnoreNullBinding() throws RemoteException { HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>(); testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0, ImsFeature.FEATURE_MMTEL)); testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0, ImsFeature.FEATURE_RCS)); ServiceConnection conn = bindAndConnectService(testFeatures); conn.onBindingDied(null); // null binding should be ignored in this case. conn.onNullBinding(null); long delay = mTestImsServiceController.getRebindDelay(); waitForHandlerActionDelayed(mHandler, delay, 2 * delay); // The service should autobind after rebind event occurs verify(mMockContext, times(2)).bindService(any(), any(), anyInt()); } /** /** * Ensure that bindService has only been called once before automatic rebind occurs. * Ensure that bindService has only been called once before automatic rebind occurs. */ */ Loading Loading
src/java/com/android/internal/telephony/ims/ImsServiceController.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,9 @@ import java.util.stream.Collectors; public class ImsServiceController { public class ImsServiceController { class ImsServiceConnection implements ServiceConnection { class ImsServiceConnection implements ServiceConnection { // Track the status of whether or not the Service has died in case we need to permanently // unbind (see onNullBinding below). private boolean mIsServiceConnectionDead = false; @Override @Override public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) { Loading Loading @@ -114,6 +117,7 @@ public class ImsServiceController { @Override @Override public void onBindingDied(ComponentName name) { public void onBindingDied(ComponentName name) { mIsServiceConnectionDead = true; synchronized (mLock) { synchronized (mLock) { mIsBinding = false; mIsBinding = false; mIsBound = false; mIsBound = false; Loading @@ -128,8 +132,12 @@ public class ImsServiceController { @Override @Override public void onNullBinding(ComponentName name) { public void onNullBinding(ComponentName name) { Log.w(LOG_TAG, "ImsService(" + name + "): onNullBinding. Removing."); Log.w(LOG_TAG, "ImsService(" + name + "): onNullBinding. Is service dead = " mLocalLog.log("onNullBinding"); + mIsServiceConnectionDead); mLocalLog.log("onNullBinding, is service dead = " + mIsServiceConnectionDead); // onNullBinding will happen after onBindingDied. In this case, we should not // permanently unbind and instead let the automatic rebind occur. if (mIsServiceConnectionDead) return; synchronized (mLock) { synchronized (mLock) { mIsBinding = false; mIsBinding = false; // Service connection exists, so we are bound but the binder is null. Wait for // Service connection exists, so we are bound but the binder is null. Wait for Loading
tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java +24 −0 Original line number Original line Diff line number Diff line Loading @@ -600,6 +600,30 @@ public class ImsServiceControllerTest extends ImsTestBase { verify(mMockContext, times(2)).bindService(any(), any(), anyInt()); verify(mMockContext, times(2)).bindService(any(), any(), anyInt()); } } /** * Due to a bug in ServiceConnection, we will sometimes receive a null binding after the binding * dies. Ignore null binding in this case. */ @SmallTest @Test public void testAutoBindAfterBinderDiedIgnoreNullBinding() throws RemoteException { HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>(); testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0, ImsFeature.FEATURE_MMTEL)); testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0, ImsFeature.FEATURE_RCS)); ServiceConnection conn = bindAndConnectService(testFeatures); conn.onBindingDied(null); // null binding should be ignored in this case. conn.onNullBinding(null); long delay = mTestImsServiceController.getRebindDelay(); waitForHandlerActionDelayed(mHandler, delay, 2 * delay); // The service should autobind after rebind event occurs verify(mMockContext, times(2)).bindService(any(), any(), anyInt()); } /** /** * Ensure that bindService has only been called once before automatic rebind occurs. * Ensure that bindService has only been called once before automatic rebind occurs. */ */ Loading