Add unit test for CarrierConfigLoader
Change CarrierConfigLoader a bit to make it more testable:
1. Inject SubscriptionInfoUpdater into CarrierConfigLoader to make
it both mockable and verifible.
2. Inject Looper into CarrirConfigLoader to take advantage of
TestableLooper in UT.
3. User PersistableBundle.EMPTY instead of creating new empty
instance to make it value comparable since the class does not
override equals method.
4. Make configs readable to test case to verify the values
(intead of verifying the behavior).
Bug: 182922049
Test: atest com.android.phone.CarrierConfigLoaderTest
Change-Id: Ia29f6daef606e13578311bfccd350cc1d891fca0
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 4ff7316..e729d28 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -36,6 +36,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.Process;
@@ -55,6 +56,7 @@
import android.util.LocalLog;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.ICarrierConfigLoader;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.Phone;
@@ -201,6 +203,10 @@
// 3. clearing config (e.g. due to sim removal)
// 4. encountering bind or IPC error
private class ConfigHandler extends Handler {
+ ConfigHandler(@NonNull Looper looper) {
+ super(looper);
+ }
+
@Override
public void handleMessage(Message msg) {
final int phoneId = msg.arg1;
@@ -287,7 +293,7 @@
} else {
// Put a stub bundle in place so that the rest of the logic continues
// smoothly.
- mConfigFromDefaultApp[phoneId] = new PersistableBundle();
+ mConfigFromDefaultApp[phoneId] = PersistableBundle.EMPTY;
// Send broadcast if bind fails.
notifySubscriptionInfoUpdater(phoneId);
// TODO: We *must* call unbindService even if bindService returns false.
@@ -372,7 +378,7 @@
broadcastConfigChangedIntent(phoneId);
}
// Put a stub bundle in place so that the rest of the logic continues smoothly.
- mConfigFromDefaultApp[phoneId] = new PersistableBundle();
+ mConfigFromDefaultApp[phoneId] = PersistableBundle.EMPTY;
notifySubscriptionInfoUpdater(phoneId);
break;
}
@@ -419,7 +425,7 @@
} else {
// Put a stub bundle in place so that the rest of the logic continues
// smoothly.
- mConfigFromCarrierApp[phoneId] = new PersistableBundle();
+ mConfigFromCarrierApp[phoneId] = PersistableBundle.EMPTY;
// Send broadcast if bind fails.
broadcastConfigChangedIntent(phoneId);
loge("Bind to carrier app: " + carrierPackageName + " fails");
@@ -504,7 +510,7 @@
broadcastConfigChangedIntent(phoneId);
}
// Put a stub bundle in place so that the rest of the logic continues smoothly.
- mConfigFromCarrierApp[phoneId] = new PersistableBundle();
+ mConfigFromCarrierApp[phoneId] = PersistableBundle.EMPTY;
notifySubscriptionInfoUpdater(phoneId);
break;
}
@@ -666,11 +672,13 @@
* Constructs a CarrierConfigLoader, registers it as a service, and registers a broadcast
* receiver for relevant events.
*/
- private CarrierConfigLoader(Context context) {
+ @VisibleForTesting
+ /* package */ CarrierConfigLoader(Context context,
+ SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper) {
mContext = context;
mPlatformCarrierConfigPackage =
mContext.getString(R.string.platform_carrier_config_package);
- mHandler = new ConfigHandler();
+ mHandler = new ConfigHandler(looper);
IntentFilter bootFilter = new IntentFilter();
bootFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
@@ -690,7 +698,7 @@
mConfigFromCarrierApp = new PersistableBundle[numPhones];
mPersistentOverrideConfigs = new PersistableBundle[numPhones];
mOverrideConfigs = new PersistableBundle[numPhones];
- mNoSimConfig = new PersistableBundle();
+ mNoSimConfig = PersistableBundle.EMPTY;
mServiceConnection = new CarrierServiceConnection[numPhones];
mServiceBound = new boolean[numPhones];
mHasSentConfigChange = new boolean[numPhones];
@@ -701,7 +709,7 @@
TelephonyFrameworkInitializer
.getTelephonyServiceManager().getCarrierConfigServiceRegisterer().register(this);
logd("CarrierConfigLoader has started");
- mSubscriptionInfoUpdater = PhoneFactory.getSubscriptionInfoUpdater();
+ mSubscriptionInfoUpdater = subscriptionInfoUpdater;
mHandler.sendEmptyMessage(EVENT_CHECK_SYSTEM_UPDATE);
}
@@ -710,11 +718,11 @@
*
* This is only done once, at startup, from {@link com.android.phone.PhoneApp#onCreate}.
*/
- /* package */
- static CarrierConfigLoader init(Context context) {
+ /* package */ static CarrierConfigLoader init(Context context) {
synchronized (CarrierConfigLoader.class) {
if (sInstance == null) {
- sInstance = new CarrierConfigLoader(context);
+ sInstance = new CarrierConfigLoader(context,
+ PhoneFactory.getSubscriptionInfoUpdater(), Looper.myLooper());
} else {
Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -722,7 +730,8 @@
}
}
- private void clearConfigForPhone(int phoneId, boolean fetchNoSimConfig) {
+ @VisibleForTesting
+ /* package */ void clearConfigForPhone(int phoneId, boolean fetchNoSimConfig) {
/* Ignore clear configuration request if device is being shutdown. */
Phone phone = PhoneFactory.getPhone(phoneId);
if (phone != null) {
@@ -759,7 +768,7 @@
}
if (configToSend == null) {
- configToSend = new PersistableBundle();
+ configToSend = PersistableBundle.EMPTY;
}
// mOverrideConfigs is for testing. And it will override current configs.
@@ -844,7 +853,8 @@
}
}
- private CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) {
+ @VisibleForTesting
+ /* package */ CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) {
String mcc = "";
String mnc = "";
String imsi = "";
@@ -1000,12 +1010,14 @@
}
}
- private void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
+ @VisibleForTesting
+ /* package */ void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
CarrierIdentifier carrierId, PersistableBundle config) {
saveConfigToXml(packageName, extraString, phoneId, carrierId, config, false);
}
- private void saveNoSimConfigToXml(String packageName, PersistableBundle config) {
+ @VisibleForTesting
+ /* package */ void saveNoSimConfigToXml(String packageName, PersistableBundle config) {
saveConfigToXml(packageName, "", -1, null, config, true);
}
@@ -1176,7 +1188,7 @@
String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
callingFeatureId, "getCarrierConfig")) {
- return new PersistableBundle();
+ return PersistableBundle.EMPTY;
}
int phoneId = SubscriptionManager.getPhoneId(subId);
@@ -1253,7 +1265,7 @@
private void overrideConfig(@NonNull PersistableBundle[] currentOverrides, int phoneId,
@Nullable PersistableBundle overrides) {
if (overrides == null) {
- currentOverrides[phoneId] = new PersistableBundle();
+ currentOverrides[phoneId] = PersistableBundle.EMPTY;
} else if (currentOverrides[phoneId] == null) {
currentOverrides[phoneId] = overrides;
} else {
@@ -1315,6 +1327,31 @@
return mPlatformCarrierConfigPackage;
}
+ @VisibleForTesting
+ /* package */ Handler getHandler() {
+ return mHandler;
+ }
+
+ @VisibleForTesting
+ /* package */ PersistableBundle getConfigFromDefaultApp(int phoneId) {
+ return mConfigFromDefaultApp[phoneId];
+ }
+
+ @VisibleForTesting
+ /* package */ PersistableBundle getConfigFromCarrierApp(int phoneId) {
+ return mConfigFromCarrierApp[phoneId];
+ }
+
+ @VisibleForTesting
+ /* package */ PersistableBundle getNoSimConfig() {
+ return mNoSimConfig;
+ }
+
+ @VisibleForTesting
+ /* package */ PersistableBundle getOverrideConfig(int phoneId) {
+ return mOverrideConfigs[phoneId];
+ }
+
private void unbindIfBound(Context context, CarrierServiceConnection conn,
int phoneId) {
if (mServiceBound[phoneId]) {