aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRambo Wang <rambowang@google.com>2022-06-06 18:51:50 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-06-06 18:51:50 +0000
commit68844b1fede732c1b4be7c24995b379e6d80e493 (patch)
tree1e11b963933d8248b3eaf946cb2014aafeb80c69
parent8c8d6d8258c8717472e8bfce3b415e0fc4198cbf (diff)
parent9e73af69a2b88033f27213c113670139c7718826 (diff)
downloadtelephony-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.java52
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java43
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...)
}