Async Initialize CarrierPrivilegesTracker
Create a separate HandlerThread to offload the heavyweight
initialization required for CarrierPrivilegesTracker. Push
all async events to that thread until the init is done, then
process the events in-order and turn down the thread so that
there isn't another unnecessary thread hanging around once
the heavy work is done.
Bug: 357096337
Test: atest CarrierPrivilegesTrackerTest
Flag: async_init_carrier_privileges_tracker
Change-Id: Idba6bc2191183568ad5fb3fd96e4219ea5ddfd99
diff --git a/flags/Android.bp b/flags/Android.bp
index 1885032..edcfc3f 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -33,6 +33,7 @@
"subscription.aconfig",
"uicc.aconfig",
"satellite.aconfig",
- "iwlan.aconfig"
+ "iwlan.aconfig",
+ "carrier.aconfig",
],
}
diff --git a/flags/carrier.aconfig b/flags/carrier.aconfig
new file mode 100644
index 0000000..dca2ad3
--- /dev/null
+++ b/flags/carrier.aconfig
@@ -0,0 +1,11 @@
+package: "com.android.internal.telephony.flags"
+container: "system"
+
+# OWNER=nharold TARGET=24Q4
+flag {
+ name: "async_init_carrier_privileges_tracker"
+ is_exported: true
+ namespace: "telephony"
+ description: "Offload the heavyweight initialization of CarrierPrivilegesTracker to a worker thread"
+ bug:"357096337"
+}
diff --git a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
index e6bfb9b..6326d6c 100644
--- a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
@@ -46,6 +46,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
@@ -177,6 +178,8 @@
private static final int ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE = 11;
private final Context mContext;
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
private final Phone mPhone;
private final PackageManager mPackageManager;
private final UserManager mUserManager;
@@ -224,8 +227,7 @@
"mPrivilegedPackageInfoLock.writeLock()"})
private boolean mSimIsReadyButNotLoaded = false;
- @NonNull
- private final FeatureFlags mFeatureFlags;
+ private volatile Handler mCurrentHandler;
/** Small snapshot to hold package names and UIDs of privileged packages. */
private static final class PrivilegedPackageInfo {
@@ -301,7 +303,9 @@
return;
}
- sendMessage(obtainMessage(ACTION_SIM_STATE_UPDATED, slotId, simState));
+ mCurrentHandler.sendMessage(
+ mCurrentHandler.obtainMessage(
+ ACTION_SIM_STATE_UPDATED, slotId, simState));
break;
}
case Intent.ACTION_PACKAGE_ADDED: // fall through
@@ -333,19 +337,21 @@
? ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER
: ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED;
- sendMessage(obtainMessage(what, pkgName));
+ mCurrentHandler.sendMessage(
+ mCurrentHandler.obtainMessage(what, pkgName));
break;
}
}
}
};
- public CarrierPrivilegesTracker(@NonNull Looper looper, @NonNull Phone phone,
- @NonNull Context context, @NonNull FeatureFlags flags) {
+ public CarrierPrivilegesTracker(
+ @NonNull Looper looper, @NonNull Phone phone,
+ @NonNull Context context, @NonNull FeatureFlags featureFlags) {
super(looper);
- mContext = context;
- mFeatureFlags = flags;
mPhone = phone;
+ mContext = context;
+ mFeatureFlags = featureFlags;
mPackageManager = mContext.getPackageManager();
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mCarrierConfigManager =
@@ -361,6 +367,56 @@
(TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (mFeatureFlags.asyncInitCarrierPrivilegesTracker()) {
+ final Object localLock = new Object();
+ HandlerThread initializerThread =
+ new HandlerThread("CarrierPrivilegesTracker Initializer") {
+ @Override
+ protected void onLooperPrepared() {
+ synchronized (localLock) {
+ localLock.notifyAll();
+ }
+ }
+ };
+ synchronized (localLock) {
+ initializerThread.start();
+ while (true) {
+ try {
+ localLock.wait();
+ break;
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ mCurrentHandler = new Handler(initializerThread.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case ACTION_INITIALIZE_TRACKER:
+ handleInitializeTracker();
+ if (!hasMessagesOrCallbacks()) {
+ mCurrentHandler = CarrierPrivilegesTracker.this;
+ initializerThread.quitSafely();
+ }
+ break;
+ default:
+ Message m = CarrierPrivilegesTracker.this.obtainMessage();
+ m.copyFrom(msg);
+ m.sendToTarget();
+ if (!hasMessagesOrCallbacks()) {
+ mCurrentHandler = CarrierPrivilegesTracker.this;
+ initializerThread.quitSafely();
+ }
+ break;
+ }
+ }
+ };
+ } else {
+ mCurrentHandler = this;
+ }
+
+ mCurrentHandler.sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
+
IntentFilter certFilter = new IntentFilter();
certFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
certFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
@@ -389,7 +445,6 @@
mContext.registerReceiver(mIntentReceiver, packageFilter);
}
- sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
}
@Override
@@ -497,7 +552,7 @@
&& mClearUiccRulesUptimeMillis == CLEAR_UICC_RULE_NOT_SCHEDULED) {
mClearUiccRulesUptimeMillis =
SystemClock.uptimeMillis() + CLEAR_UICC_RULES_DELAY_MILLIS;
- sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
+ mCurrentHandler.sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
mClearUiccRulesUptimeMillis);
mLocalLog.log("SIM is gone, simState=" + TelephonyManager.simStateToString(simState)
+ ". Delay " + TimeUnit.MILLISECONDS.toSeconds(
@@ -920,7 +975,8 @@
* @see TelephonyManager#setCarrierTestOverride
*/
public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) {
- sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
+ mCurrentHandler.sendMessage(
+ obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
}
/**
@@ -936,7 +992,7 @@
* @see TelephonyManager#setCarrierServicePackageOverride
*/
public void setTestOverrideCarrierServicePackage(@Nullable String carrierServicePackage) {
- sendMessage(obtainMessage(
+ mCurrentHandler.sendMessage(obtainMessage(
ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE, carrierServicePackage));
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 5d59327..2e1a89f 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -391,8 +391,8 @@
mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
.makeCarrierResolver(this, featureFlags);
- mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(Looper.myLooper(), this, context,
- featureFlags);
+ mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(
+ Looper.myLooper(), this, context, featureFlags);
getCarrierActionAgent().registerForCarrierAction(
CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
index a860dff..1c58ef2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
@@ -220,8 +220,9 @@
// Capture CarrierConfigChangeListener to emulate the carrier config change notification
ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
- CarrierPrivilegesTracker cpt = new CarrierPrivilegesTracker(mTestableLooper.getLooper(),
- mPhone, mContext, mFeatureFlags);
+ CarrierPrivilegesTracker cpt =
+ new CarrierPrivilegesTracker(
+ mTestableLooper.getLooper(), mPhone, mContext, mFeatureFlags);
verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
listenerArgumentCaptor.capture());
mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);