Add nullability support for CarrierConfigLoader class
Follow the Android API guideline at
go/android-api-guidelines#nullability to annotate all non-primitive Java
arguments and return types with nullability.
Bug: 185129900
Test: atest CarrierConfigLoaderTest
Change-Id: Ia366727690ae451e4c8936b5907213f651aecd36
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 4f4b2a7..2ec491b 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -88,42 +88,46 @@
private static final String LOG_TAG = "CarrierConfigLoader";
// Package name for platform carrier config app, bundled with system image.
- private final String mPlatformCarrierConfigPackage;
+ @NonNull private final String mPlatformCarrierConfigPackage;
/** The singleton instance. */
- private static CarrierConfigLoader sInstance;
+ @Nullable private static CarrierConfigLoader sInstance;
// The context for phone app, passed from PhoneGlobals.
- private Context mContext;
+ @NonNull private Context mContext;
+
+ // All the states below (array indexed by phoneId) are non-null. But the member of the array
+ // is nullable, when e.g. the config for the phone is not loaded yet
// Carrier configs from default app, indexed by phoneID.
- private PersistableBundle[] mConfigFromDefaultApp;
+ @NonNull private PersistableBundle[] mConfigFromDefaultApp;
// Carrier configs from privileged carrier config app, indexed by phoneID.
- private PersistableBundle[] mConfigFromCarrierApp;
+ @NonNull private PersistableBundle[] mConfigFromCarrierApp;
// Persistent Carrier configs that are provided via the override test API, indexed by phone ID.
- private PersistableBundle[] mPersistentOverrideConfigs;
+ @NonNull private PersistableBundle[] mPersistentOverrideConfigs;
// Carrier configs that are provided via the override test API, indexed by phone ID.
- private PersistableBundle[] mOverrideConfigs;
+ @NonNull private PersistableBundle[] mOverrideConfigs;
// Carrier configs to override code default when there is no SIM inserted
- private PersistableBundle mNoSimConfig;
+ @NonNull private PersistableBundle mNoSimConfig;
// Service connection for binding to config app.
- private CarrierServiceConnection[] mServiceConnection;
+ @NonNull private CarrierServiceConnection[] mServiceConnection;
// Service connection for binding to carrier config app for no SIM config.
- private CarrierServiceConnection[] mServiceConnectionForNoSimConfig;
+ @NonNull private CarrierServiceConnection[] mServiceConnectionForNoSimConfig;
// Whether we are bound to a service for each phone
- private boolean[] mServiceBound;
+ @NonNull private boolean[] mServiceBound;
// Whether we are bound to a service for no SIM config
- private boolean[] mServiceBoundForNoSimConfig;
+ @NonNull private boolean[] mServiceBoundForNoSimConfig;
// Whether we have sent config change broadcast for each phone id.
- private boolean[] mHasSentConfigChange;
+ @NonNull private boolean[] mHasSentConfigChange;
// Whether the broadcast was sent from EVENT_SYSTEM_UNLOCKED, to track rebroadcasts
- private boolean[] mFromSystemUnlocked;
+ @NonNull private boolean[] mFromSystemUnlocked;
+
// SubscriptionInfoUpdater
- private final SubscriptionInfoUpdater mSubscriptionInfoUpdater;
+ @NonNull private final SubscriptionInfoUpdater mSubscriptionInfoUpdater;
// Broadcast receiver for Boot intents, register intent filter in construtor.
- private final BroadcastReceiver mBootReceiver = new ConfigLoaderBroadcastReceiver();
+ @NonNull private final BroadcastReceiver mBootReceiver = new ConfigLoaderBroadcastReceiver();
// Broadcast receiver for SIM and pkg intents, register intent filter in constructor.
- private final BroadcastReceiver mPackageReceiver = new ConfigLoaderBroadcastReceiver();
- private final LocalLog mCarrierConfigLoadingLog = new LocalLog(100);
+ @NonNull private final BroadcastReceiver mPackageReceiver = new ConfigLoaderBroadcastReceiver();
+ @NonNull private final LocalLog mCarrierConfigLoadingLog = new LocalLog(100);
// Message codes; see mHandler below.
@@ -210,7 +214,7 @@
}
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(@NonNull Message msg) {
final int phoneId = msg.arg1;
logdWithLocalLog("mHandler: " + eventToString(msg.what) + " phoneId: " + phoneId);
if (!SubscriptionManager.isValidPhoneId(phoneId)
@@ -676,15 +680,15 @@
}
}
- private final Handler mHandler;
+ @NonNull private final Handler mHandler;
/**
* Constructs a CarrierConfigLoader, registers it as a service, and registers a broadcast
* receiver for relevant events.
*/
@VisibleForTesting
- /* package */ CarrierConfigLoader(Context context,
- SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper) {
+ /* package */ CarrierConfigLoader(@NonNull Context context,
+ @NonNull SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper) {
mContext = context;
mPlatformCarrierConfigPackage =
mContext.getString(R.string.platform_carrier_config_package);
@@ -725,7 +729,8 @@
*
* This is only done once, at startup, from {@link com.android.phone.PhoneApp#onCreate}.
*/
- /* package */ static CarrierConfigLoader init(Context context) {
+ @NonNull
+ /* package */ static CarrierConfigLoader init(@NonNull Context context) {
synchronized (CarrierConfigLoader.class) {
if (sInstance == null) {
sInstance = new CarrierConfigLoader(context,
@@ -835,7 +840,7 @@
}
/** Binds to the default or carrier config app. */
- private boolean bindToConfigPackage(String pkgName, int phoneId, int eventId) {
+ private boolean bindToConfigPackage(@NonNull String pkgName, int phoneId, int eventId) {
logdWithLocalLog("Binding to " + pkgName + " for phone " + phoneId);
Intent carrierService = new Intent(CarrierService.CARRIER_SERVICE_INTERFACE);
carrierService.setPackage(pkgName);
@@ -864,6 +869,7 @@
}
@VisibleForTesting
+ @NonNull
/* package */ CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) {
String mcc = "";
String mnc = "";
@@ -902,6 +908,7 @@
}
}
+ @Nullable
private String getIccIdForPhoneId(int phoneId) {
if (!SubscriptionManager.isValidPhoneId(phoneId)) {
return null;
@@ -963,8 +970,9 @@
* @param config the bundle to be written. Null will be treated as an empty bundle.
* @param isNoSimConfig whether this is invoked for noSimConfig or not.
*/
- private void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
- CarrierIdentifier carrierId, PersistableBundle config, boolean isNoSimConfig) {
+ private void saveConfigToXml(@Nullable String packageName, @NonNull String extraString,
+ int phoneId, @Nullable CarrierIdentifier carrierId, @NonNull PersistableBundle config,
+ boolean isNoSimConfig) {
if (packageName == null) {
loge("Cannot save config with null packageName");
return;
@@ -981,7 +989,8 @@
}
final String iccid = getIccIdForPhoneId(phoneId);
- final int cid = carrierId.getSpecificCarrierId();
+ final int cid = carrierId != null ? carrierId.getSpecificCarrierId()
+ : TelephonyManager.UNKNOWN_CARRIER_ID;
if (iccid == null) {
loge("Cannot save config with null iccid.");
return;
@@ -1020,13 +1029,14 @@
}
@VisibleForTesting
- /* package */ void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
- CarrierIdentifier carrierId, PersistableBundle config) {
+ /* package */ void saveConfigToXml(@Nullable String packageName, @NonNull String extraString,
+ int phoneId, @NonNull CarrierIdentifier carrierId, @NonNull PersistableBundle config) {
saveConfigToXml(packageName, extraString, phoneId, carrierId, config, false);
}
@VisibleForTesting
- /* package */ void saveNoSimConfigToXml(String packageName, PersistableBundle config) {
+ /* package */ void saveNoSimConfigToXml(@Nullable String packageName,
+ @NonNull PersistableBundle config) {
saveConfigToXml(packageName, "", -1, null, config, true);
}
@@ -1046,8 +1056,9 @@
* @return the bundle from the XML file. Returns null if there is no saved config, the saved
* version does not match, or reading config fails.
*/
- private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString,
- int phoneId, boolean isNoSimConfig) {
+ @Nullable
+ private PersistableBundle restoreConfigFromXml(@Nullable String packageName,
+ @NonNull String extraString, int phoneId, boolean isNoSimConfig) {
if (packageName == null) {
loge("Cannot restore config with null packageName");
}
@@ -1116,7 +1127,8 @@
/**
* This method will mask most part of iccid in the filepath for logging on userbuild
*/
- private String getFilePathForLogging(String filePath, String iccid) {
+ @NonNull
+ private String getFilePathForLogging(@Nullable String filePath, @Nullable String iccid) {
// If loggable then return with actual file path
if (Rlog.isLoggable(LOG_TAG, Log.VERBOSE)) {
return filePath;
@@ -1129,12 +1141,14 @@
return path;
}
- private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString,
- int phoneId) {
+ @Nullable
+ private PersistableBundle restoreConfigFromXml(@Nullable String packageName,
+ @NonNull String extraString, int phoneId) {
return restoreConfigFromXml(packageName, extraString, phoneId, false);
}
- private PersistableBundle restoreNoSimConfigFromXml(String packageName) {
+ @Nullable
+ private PersistableBundle restoreNoSimConfigFromXml(@Nullable String packageName) {
return restoreConfigFromXml(packageName, "", -1, true);
}
@@ -1147,7 +1161,7 @@
* cleared.
* @return true iff one or more files were deleted.
*/
- private boolean clearCachedConfigForPackage(final String packageName) {
+ private boolean clearCachedConfigForPackage(@Nullable final String packageName) {
File dir = mContext.getFilesDir();
File[] packageFiles = dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
@@ -1167,6 +1181,7 @@
}
/** Builds a canonical file name for a config file. */
+ @NonNull
private static String getFilenameForConfig(
@NonNull String packageName, @NonNull String extraString,
@NonNull String iccid, int cid) {
@@ -1178,12 +1193,14 @@
}
/** Builds a canonical file name for no SIM config file. */
+ @NonNull
private String getFilenameForNoSimConfig(@NonNull String packageName) {
return "carrierconfig-" + packageName + "-" + "nosim" + ".xml";
}
/** Return the current version code of a package, or null if the name is not found. */
- private String getPackageVersion(String packageName) {
+ @Nullable
+ private String getPackageVersion(@NonNull String packageName) {
try {
PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName, 0);
return Long.toString(info.getLongVersionCode());
@@ -1212,14 +1229,14 @@
@Override
@NonNull
- public PersistableBundle getConfigForSubId(int subscriptionId, String callingPackage) {
+ public PersistableBundle getConfigForSubId(int subscriptionId, @NonNull String callingPackage) {
return getConfigForSubIdWithFeature(subscriptionId, callingPackage, null);
}
@Override
@NonNull
- public PersistableBundle getConfigForSubIdWithFeature(int subscriptionId, String callingPackage,
- String callingFeatureId) {
+ public PersistableBundle getConfigForSubIdWithFeature(int subscriptionId,
+ @NonNull String callingPackage, @Nullable String callingFeatureId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subscriptionId,
callingPackage, callingFeatureId, "getCarrierConfig")) {
return new PersistableBundle();
@@ -1332,7 +1349,7 @@
}
@Override
- public void updateConfigForPhoneId(int phoneId, String simState) {
+ public void updateConfigForPhoneId(int phoneId, @NonNull String simState) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE, null);
logdWithLocalLog("Update config for phoneId: " + phoneId + " simState: " + simState);
@@ -1356,6 +1373,7 @@
}
@Override
+ @NonNull
public String getDefaultCarrierServicePackageName() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
@@ -1364,31 +1382,36 @@
}
@VisibleForTesting
+ @NonNull
/* package */ Handler getHandler() {
return mHandler;
}
@VisibleForTesting
+ @Nullable
/* package */ PersistableBundle getConfigFromDefaultApp(int phoneId) {
return mConfigFromDefaultApp[phoneId];
}
@VisibleForTesting
+ @Nullable
/* package */ PersistableBundle getConfigFromCarrierApp(int phoneId) {
return mConfigFromCarrierApp[phoneId];
}
@VisibleForTesting
+ @NonNull
/* package */ PersistableBundle getNoSimConfig() {
return mNoSimConfig;
}
@VisibleForTesting
+ @Nullable
/* package */ PersistableBundle getOverrideConfig(int phoneId) {
return mOverrideConfigs[phoneId];
}
- private void unbindIfBound(Context context, CarrierServiceConnection conn,
+ private void unbindIfBound(@NonNull Context context, @NonNull CarrierServiceConnection conn,
int phoneId) {
if (mServiceBound[phoneId]) {
mServiceBound[phoneId] = false;
@@ -1396,8 +1419,8 @@
}
}
- private void unbindIfBoundForNoSimConfig(Context context, CarrierServiceConnection conn,
- int phoneId) {
+ private void unbindIfBoundForNoSimConfig(@NonNull Context context,
+ @NonNull CarrierServiceConnection conn, int phoneId) {
if (mServiceBoundForNoSimConfig[phoneId]) {
mServiceBoundForNoSimConfig[phoneId] = false;
context.unbindService(conn);
@@ -1408,6 +1431,7 @@
* Returns a boxed Integer object for phoneId, services as message token to distinguish messages
* with same code when calling {@link Handler#removeMessages(int, Object)}.
*/
+ @NonNull
private Integer getMessageToken(int phoneId) {
if (phoneId < -128 || phoneId > 127) {
throw new IllegalArgumentException("phoneId should be in range [-128, 127], inclusive");
@@ -1425,7 +1449,7 @@
* too much info, but we still want to let carrier apps include their diagnostics.
*/
@Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
IndentingPrintWriter indentPW = new IndentingPrintWriter(pw, " ");
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -1473,8 +1497,8 @@
}
}
- private void printConfig(PersistableBundle configApp, IndentingPrintWriter indentPW,
- String name) {
+ private void printConfig(@NonNull PersistableBundle configApp,
+ @NonNull IndentingPrintWriter indentPW, @NonNull String name) {
indentPW.increaseIndent();
if (configApp == null) {
indentPW.println(name + " : null ");
@@ -1511,7 +1535,7 @@
*
* @throws SecurityException if none of the above conditions are met.
*/
- private void enforceCallerIsSystemOrRequestingPackage(String requestingPackage)
+ private void enforceCallerIsSystemOrRequestingPackage(@NonNull String requestingPackage)
throws SecurityException {
final int callingUid = Binder.getCallingUid();
if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID
@@ -1539,8 +1563,9 @@
* otherwise, only dump a carrier service if it is {@code
* targetPkgName}
*/
- private void dumpCarrierServiceIfBound(FileDescriptor fd, IndentingPrintWriter indentPW,
- String prefix, String targetPkgName, boolean considerCarrierPrivileges) {
+ private void dumpCarrierServiceIfBound(@NonNull FileDescriptor fd,
+ @NonNull IndentingPrintWriter indentPW, @NonNull String prefix,
+ @NonNull String targetPkgName, boolean considerCarrierPrivileges) {
// Null package is possible if it's early in the boot process, there was a recent crash, we
// loaded the config from XML most recently, or a SIM slot is empty. Carrier apps with
// long-lived bindings should typically get dumped here regardless. Even if an app is being
@@ -1609,7 +1634,7 @@
indentPW.decreaseIndent();
}
- private boolean hasCarrierPrivileges(String pkgName, int phoneId) {
+ private boolean hasCarrierPrivileges(@NonNull String pkgName, int phoneId) {
int[] subIds = SubscriptionManager.getSubId(phoneId);
if (ArrayUtils.isEmpty(subIds)) {
return false;
@@ -1621,37 +1646,37 @@
private class CarrierServiceConnection implements ServiceConnection {
final int phoneId;
- final String pkgName;
+ @NonNull final String pkgName;
final int eventId;
IBinder service;
- CarrierServiceConnection(int phoneId, String pkgName, int eventId) {
+ CarrierServiceConnection(int phoneId, @NonNull String pkgName, int eventId) {
this.phoneId = phoneId;
this.pkgName = pkgName;
this.eventId = eventId;
}
@Override
- public void onServiceConnected(ComponentName name, IBinder service) {
+ public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder service) {
logd("Connected to config app: " + name.flattenToShortString());
this.service = service;
mHandler.sendMessage(mHandler.obtainMessage(eventId, phoneId, -1, this));
}
@Override
- public void onServiceDisconnected(ComponentName name) {
+ public void onServiceDisconnected(@NonNull ComponentName name) {
logd("Disconnected from config app: " + name.flattenToShortString());
this.service = null;
}
@Override
- public void onBindingDied(ComponentName name) {
+ public void onBindingDied(@NonNull ComponentName name) {
logd("Binding died from config app: " + name.flattenToShortString());
this.service = null;
}
@Override
- public void onNullBinding(ComponentName name) {
+ public void onNullBinding(@NonNull ComponentName name) {
logd("Null binding from config app: " + name.flattenToShortString());
this.service = null;
}
@@ -1659,7 +1684,7 @@
private class ConfigLoaderBroadcastReceiver extends BroadcastReceiver {
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
String action = intent.getAction();
boolean replace = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
// If replace is true, only care ACTION_PACKAGE_REPLACED.
@@ -1688,6 +1713,7 @@
}
// Get readable string for the message code supported in this class.
+ @NonNull
private static String eventToString(int code) {
switch (code) {
case EVENT_CLEAR_CONFIG:
@@ -1737,20 +1763,20 @@
}
}
- private void logd(String msg) {
+ private void logd(@NonNull String msg) {
Log.d(LOG_TAG, msg);
}
- private void logd(String msg, Throwable tr) {
+ private void logd(@NonNull String msg, Throwable tr) {
Log.d(LOG_TAG, msg, tr);
}
- private void logdWithLocalLog(String msg) {
+ private void logdWithLocalLog(@NonNull String msg) {
Log.d(LOG_TAG, msg);
mCarrierConfigLoadingLog.log(msg);
}
- private void loge(String msg) {
+ private void loge(@NonNull String msg) {
Log.e(LOG_TAG, msg);
mCarrierConfigLoadingLog.log(msg);
}