diff options
author | Rambo Wang <rambowang@google.com> | 2022-06-06 18:51:50 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-06-06 18:51:50 +0000 |
commit | 68844b1fede732c1b4be7c24995b379e6d80e493 (patch) | |
tree | 1e11b963933d8248b3eaf946cb2014aafeb80c69 | |
parent | 8c8d6d8258c8717472e8bfce3b415e0fc4198cbf (diff) | |
parent | 9e73af69a2b88033f27213c113670139c7718826 (diff) | |
download | telephony-68844b1fede732c1b4be7c24995b379e6d80e493.tar.gz |
Make carrier service persistent binding more robust am: 9e73af69a2
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/18700477
Change-Id: I42ca12b07f1639afa09ac3f2e1e2af823026b1f8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | src/java/com/android/internal/telephony/CarrierServiceBindHelper.java | 52 | ||||
-rw-r--r-- | tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java | 43 |
2 files changed, 95 insertions, 0 deletions
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java index 16d0dd9d29..dfa53b3958 100644 --- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java +++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java @@ -29,6 +29,7 @@ import android.content.pm.ResolveInfo; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Message; import android.os.Process; @@ -47,6 +48,8 @@ import com.android.internal.telephony.util.TelephonyUtils; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Set; /** * Manages long-lived bindings to carrier services @@ -71,6 +74,8 @@ public class CarrierServiceBindHelper { public SparseArray<AppBinding> mBindings = new SparseArray(); @VisibleForTesting public SparseArray<String> mLastSimState = new SparseArray<>(); + // TODO(b/201423849): Clean up PackageChangeReceiver/UserUnlockedReceiver/SIM State change if + // CarrierServiceChangeCallback can cover the cases private final PackageChangeReceiver mPackageMonitor = new CarrierServicePackageMonitor(); private final LocalLog mLocalLog = new LocalLog(100); @@ -90,6 +95,30 @@ public class CarrierServiceBindHelper { } }; + private class CarrierServiceChangeCallback implements + TelephonyManager.CarrierPrivilegesCallback { + final int mPhoneId; + + CarrierServiceChangeCallback(int phoneId) { + this.mPhoneId = phoneId; + } + + @Override + public void onCarrierPrivilegesChanged(Set<String> privilegedPackageNames, + Set<Integer> privilegedUids) { + // Ignored, not interested here + } + + @Override + public void onCarrierServiceChanged(String carrierServicePackageName, + int carrierServiceUid) { + logdWithLocalLog("onCarrierServiceChanged, carrierServicePackageName=" + + carrierServicePackageName + ", carrierServiceUid=" + carrierServiceUid + + ", mPhoneId=" + mPhoneId); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REBIND, mPhoneId)); + } + } + private static final int EVENT_REBIND = 0; @VisibleForTesting public static final int EVENT_PERFORM_IMMEDIATE_UNBIND = 1; @@ -123,6 +152,8 @@ public class CarrierServiceBindHelper { case EVENT_MULTI_SIM_CONFIG_CHANGED: updateBindingsAndSimStates(); break; + default: + Log.e(LOG_TAG, "Unsupported event received: " + msg.what); } } }; @@ -162,6 +193,7 @@ public class CarrierServiceBindHelper { // If prevLen > newLen, dispose AppBinding and simState objects. for (int phoneId = newLen; phoneId < prevLen; phoneId++) { + mBindings.get(phoneId).tearDown(); mBindings.get(phoneId).unbind(true); mBindings.delete(phoneId); mLastSimState.delete(phoneId); @@ -193,9 +225,23 @@ public class CarrierServiceBindHelper { private String carrierPackage; private String carrierServiceClass; private long mUnbindScheduledUptimeMillis = -1; + private final CarrierServiceChangeCallback mCarrierServiceChangeCallback; public AppBinding(int phoneId) { this.phoneId = phoneId; + this.mCarrierServiceChangeCallback = new CarrierServiceChangeCallback(phoneId); + TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); + if (tm != null) { + tm.registerCarrierPrivilegesCallback(phoneId, new HandlerExecutor(mHandler), + mCarrierServiceChangeCallback); + } + } + + public void tearDown() { + TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); + if (tm != null && mCarrierServiceChangeCallback != null) { + tm.unregisterCarrierPrivilegesCallback(mCarrierServiceChangeCallback); + } } public int getPhoneId() { @@ -365,6 +411,7 @@ public class CarrierServiceBindHelper { pw.println(" unbindCount: " + unbindCount); pw.println(" lastUnbindMillis: " + lastUnbindMillis); pw.println(" mUnbindScheduledUptimeMillis: " + mUnbindScheduledUptimeMillis); + pw.println(" mCarrierServiceChangeCallback: " + mCarrierServiceChangeCallback); pw.println(); } } @@ -405,27 +452,32 @@ public class CarrierServiceBindHelper { private class CarrierServicePackageMonitor extends PackageChangeReceiver { @Override public void onPackageAdded(String packageName) { + logdWithLocalLog("onPackageAdded: " + packageName); evaluateBinding(packageName, true /* forceUnbind */); } @Override public void onPackageRemoved(String packageName) { + logdWithLocalLog("onPackageRemoved: " + packageName); evaluateBinding(packageName, true /* forceUnbind */); } @Override public void onPackageUpdateFinished(String packageName) { + logdWithLocalLog("onPackageUpdateFinished: " + packageName); evaluateBinding(packageName, true /* forceUnbind */); } @Override public void onPackageModified(String packageName) { + logdWithLocalLog("onPackageModified: " + packageName); evaluateBinding(packageName, false /* forceUnbind */); } @Override public void onHandleForceStop(String[] packages, boolean doit) { if (doit) { + logdWithLocalLog("onHandleForceStop: " + Arrays.toString(packages)); for (String packageName : packages) { evaluateBinding(packageName, true /* forceUnbind */); } diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java index acae8592f3..8ce11aef7a 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java @@ -18,10 +18,15 @@ package com.android.internal.telephony; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import android.os.Message; +import android.telephony.TelephonyManager.CarrierPrivilegesCallback; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -30,10 +35,14 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class CarrierServiceBindHelperTest extends TelephonyTest { + private static final int PHONE_ID_0 = 0; + private static final int PHONE_ID_1 = 1; + CarrierServiceBindHelper mCarrierServiceBindHelper; @Before public void setUp() throws Exception { @@ -90,4 +99,38 @@ public class CarrierServiceBindHelperTest extends TelephonyTest { CarrierServiceBindHelper.EVENT_PERFORM_IMMEDIATE_UNBIND, new Integer(0))); } + + @Test + public void testCarrierPrivilegesCallbackRegistration() { + // Device starts with DSDS mode + doReturn(2).when(mTelephonyManager).getActiveModemCount(); + mCarrierServiceBindHelper = new CarrierServiceBindHelper(mContext); + processAllMessages(); + + // Verify that CarrierPrivilegesCallbacks are registered on both phones. + // Capture the callbacks for further verification + ArgumentCaptor<CarrierPrivilegesCallback> phone0CallbackCaptor = ArgumentCaptor.forClass( + CarrierPrivilegesCallback.class); + verify(mTelephonyManager).registerCarrierPrivilegesCallback(eq(PHONE_ID_0), any(), + phone0CallbackCaptor.capture()); + CarrierPrivilegesCallback phone0Callback = phone0CallbackCaptor.getAllValues().get(0); + assertNotNull(phone0Callback); + + ArgumentCaptor<CarrierPrivilegesCallback> phone1CallbackCaptor = ArgumentCaptor.forClass( + CarrierPrivilegesCallback.class); + verify(mTelephonyManager).registerCarrierPrivilegesCallback(eq(PHONE_ID_1), any(), + phone1CallbackCaptor.capture()); + CarrierPrivilegesCallback phone1Callback = phone1CallbackCaptor.getAllValues().get(0); + assertNotNull(phone1Callback); + + // Switch back to single SIM. + doReturn(1).when(mTelephonyManager).getActiveModemCount(); + PhoneConfigurationManager.notifyMultiSimConfigChange(1); + processAllMessages(); + + // Verify the callback for phone1 had been unregistered while phone0 didn't. + verify(mTelephonyManager).unregisterCarrierPrivilegesCallback(eq(phone1Callback)); + verify(mTelephonyManager, never()).unregisterCarrierPrivilegesCallback(eq(phone0Callback)); + } + // TODO (b/232461097): Add UT cases to cover more scenarios (user unlock, SIM state change...) } |