diff --git a/res/xml/conversation_notification_settings.xml b/res/xml/conversation_notification_settings.xml index 9078e2d0905..89812a774ae 100644 --- a/res/xml/conversation_notification_settings.xml +++ b/res/xml/conversation_notification_settings.xml @@ -96,4 +96,11 @@ android:summary="@string/demote_conversation_summary" settings:allowDividerAbove="true"/> + + + diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index ed45c2be31e..e771ff47761 100644 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -437,7 +437,8 @@ public class AppInfoDashboardFragment extends DashboardFragment } } - private static void showLockScreen(Context context, Runnable successRunnable) { + /** Shows the lock screen if the keyguard is secured. */ + public static void showLockScreen(Context context, Runnable successRunnable) { final KeyguardManager keyguardManager = context.getSystemService( KeyguardManager.class); diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java index 8621e6f5f95..e16d0d8c576 100644 --- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java +++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java @@ -207,7 +207,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } // Build the pref and add it to the output & group. - SwitchPreference pref = addProviderPreference(context, title, icon, packageName); + SwitchPreference pref = addProviderPreference(context, title, icon, packageName, firstInfo.getSettingsSubtitle()); output.put(packageName, pref); group.addPreference(pref); } @@ -223,7 +223,8 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl context, label == null ? "" : label, service.getServiceIcon(mContext), - service.getServiceInfo().packageName); + service.getServiceInfo().packageName, + service.getSettingsSubtitle()); } /** @@ -281,7 +282,8 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl @NonNull Context prefContext, @NonNull CharSequence title, @Nullable Drawable icon, - @NonNull String packageName) { + @NonNull String packageName, + @Nullable CharSequence subtitle) { final SwitchPreference pref = new SwitchPreference(prefContext); pref.setTitle(title); pref.setChecked(mEnabledPackageNames.contains(packageName)); @@ -290,6 +292,10 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl pref.setIcon(Utils.getSafeIcon(icon)); } + if (subtitle != null) { + pref.setSummary(subtitle); + } + pref.setOnPreferenceClickListener( p -> { boolean isChecked = pref.isChecked(); diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java index 4105db1037e..e82d54163fb 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogFragment.java @@ -20,6 +20,7 @@ import android.app.Dialog; import android.app.settings.SettingsEnums; import android.os.Bundle; import android.text.TextUtils; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; @@ -106,6 +107,10 @@ public class SimStatusDialogFragment extends InstrumentedDialogFragment { .sorted().toArray(); public void setText(int viewId, CharSequence text) { + if (!isAdded()) { + Log.d(TAG, "Fragment not attached yet."); + return; + } setText(viewId, text, true); } diff --git a/src/com/android/settings/fuelgauge/InactiveApps.java b/src/com/android/settings/fuelgauge/InactiveApps.java index 0d87ae73fe6..284e5be6c1f 100644 --- a/src/com/android/settings/fuelgauge/InactiveApps.java +++ b/src/com/android/settings/fuelgauge/InactiveApps.java @@ -32,7 +32,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.os.Bundle; -import android.provider.Settings; import android.text.TextUtils; import androidx.preference.ListPreference; @@ -51,9 +50,6 @@ public class InactiveApps extends SettingsPreferenceFragment private static final CharSequence[] FULL_SETTABLE_BUCKETS_NAMES = {"ACTIVE", "WORKING_SET", "FREQUENT", "RARE", "RESTRICTED"}; - private static final CharSequence[] REDUCED_SETTABLE_BUCKETS_NAMES = - Arrays.copyOfRange(FULL_SETTABLE_BUCKETS_NAMES, 0, 4); - private static final CharSequence[] FULL_SETTABLE_BUCKETS_VALUES = { Integer.toString(STANDBY_BUCKET_ACTIVE), Integer.toString(STANDBY_BUCKET_WORKING_SET), @@ -62,9 +58,6 @@ public class InactiveApps extends SettingsPreferenceFragment Integer.toString(STANDBY_BUCKET_RESTRICTED) }; - private static final CharSequence[] REDUCED_SETTABLE_BUCKETS_VALUES = - Arrays.copyOfRange(FULL_SETTABLE_BUCKETS_VALUES, 0, 4); - private UsageStatsManager mUsageStats; @Override @@ -94,13 +87,8 @@ public class InactiveApps extends SettingsPreferenceFragment final Context context = getActivity(); final PackageManager pm = context.getPackageManager(); final String settingsPackage = context.getPackageName(); - final boolean allowRestrictedBucket = Settings.Global.getInt(getContentResolver(), - Settings.Global.ENABLE_RESTRICTED_BUCKET, - Settings.Global.DEFAULT_ENABLE_RESTRICTED_BUCKET) == 1; - final CharSequence[] bucketNames = allowRestrictedBucket - ? FULL_SETTABLE_BUCKETS_NAMES : REDUCED_SETTABLE_BUCKETS_NAMES; - final CharSequence[] bucketValues = allowRestrictedBucket - ? FULL_SETTABLE_BUCKETS_VALUES : REDUCED_SETTABLE_BUCKETS_VALUES; + final CharSequence[] bucketNames = FULL_SETTABLE_BUCKETS_NAMES; + final CharSequence[] bucketValues = FULL_SETTABLE_BUCKETS_VALUES; Intent launcherIntent = new Intent(Intent.ACTION_MAIN); launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER); diff --git a/src/com/android/settings/network/InternetPreferenceController.java b/src/com/android/settings/network/InternetPreferenceController.java index ad1a5f04d56..898585c1b21 100644 --- a/src/com/android/settings/network/InternetPreferenceController.java +++ b/src/com/android/settings/network/InternetPreferenceController.java @@ -101,7 +101,7 @@ public class InternetPreferenceController extends AbstractPreferenceController i mInternetUpdater = new InternetUpdater(context, lifecycle, this); mInternetType = mInternetUpdater.getInternetType(); mLifecycleOwner = lifecycleOwner; - mMobileNetworkRepository = MobileNetworkRepository.create(context, this); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); lifecycle.addObserver(this); } @@ -156,14 +156,16 @@ public class InternetPreferenceController extends AbstractPreferenceController i /** @OnLifecycleEvent(ON_RESUME) */ @OnLifecycleEvent(ON_RESUME) public void onResume() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + mMobileNetworkRepository.updateEntity(); mSummaryHelper.register(true); } /** @OnLifecycleEvent(ON_PAUSE) */ @OnLifecycleEvent(ON_PAUSE) public void onPause() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); mSummaryHelper.register(false); } diff --git a/src/com/android/settings/network/MobileNetworkRepository.java b/src/com/android/settings/network/MobileNetworkRepository.java index f07a3b73779..1e57c4846bf 100644 --- a/src/com/android/settings/network/MobileNetworkRepository.java +++ b/src/com/android/settings/network/MobileNetworkRepository.java @@ -20,6 +20,7 @@ import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT; import static com.android.internal.telephony.TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED; +import android.annotation.NonNull; import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; import android.content.Context; @@ -56,10 +57,12 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; +import androidx.annotation.GuardedBy; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; @@ -72,14 +75,17 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static ExecutorService sExecutor = Executors.newSingleThreadExecutor(); - private static Map sCacheSubscriptionInfoEntityMap = + private static Map sCacheSubscriptionInfoEntityMap = new ArrayMap<>(); - private static Map sCacheMobileNetworkInfoEntityMap = + private static Map sCacheMobileNetworkInfoEntityMap = new ArrayMap<>(); - private static Map sCacheUiccInfoEntityMap = new ArrayMap<>(); + private static Map sCacheUiccInfoEntityMap = new ArrayMap<>(); + private static Collection sCallbacks = new CopyOnWriteArrayList<>(); + private static final Object sInstanceLock = new Object(); + @GuardedBy("sInstanceLock") + private static MobileNetworkRepository sInstance; private SubscriptionManager mSubscriptionManager; - private TelephonyManager mTelephonyManager; private MobileNetworkDatabase mMobileNetworkDatabase; private SubscriptionInfoDao mSubscriptionInfoDao; private UiccInfoDao mUiccInfoDao; @@ -88,7 +94,6 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions private List mActiveSubInfoEntityList = new ArrayList<>(); private List mUiccInfoEntityList = new ArrayList<>(); private List mMobileNetworkInfoEntityList = new ArrayList<>(); - private MobileNetworkCallback mCallback; private Context mContext; private AirplaneModeObserver mAirplaneModeObserver; private Uri mAirplaneModeSettingUri; @@ -100,35 +105,34 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions private int mCardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT; private int mPortIndex = TelephonyManager.INVALID_PORT_INDEX; private int mCardId = TelephonyManager.UNINITIALIZED_CARD_ID; - private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private boolean mIsEuicc = false; private boolean mIsRemovable = false; private boolean mIsActive = false; private Map mSubscriptionInfoMap = new ArrayMap<>(); private Map mTelephonyManagerMap = new HashMap<>(); private Map mTelephonyCallbackMap = new HashMap<>(); + private BroadcastReceiver mDataSubscriptionChangedReceiver = null; - public static MobileNetworkRepository create(Context context, - MobileNetworkCallback mobileNetworkCallback) { - return new MobileNetworkRepository(context, mobileNetworkCallback, - SubscriptionManager.INVALID_SUBSCRIPTION_ID); + @NonNull + public static MobileNetworkRepository getInstance(Context context) { + synchronized (sInstanceLock) { + if (sInstance != null) { + return sInstance; + } + if (DEBUG) { + Log.d(TAG, "Init the instance."); + } + sInstance = new MobileNetworkRepository(context); + return sInstance; + } } - public static MobileNetworkRepository createBySubId(Context context, - MobileNetworkCallback mobileNetworkCallback, int subId) { - return new MobileNetworkRepository(context, mobileNetworkCallback, subId); - } - - private MobileNetworkRepository(Context context, MobileNetworkCallback mobileNetworkCallback, - int subId) { - mSubId = subId; + private MobileNetworkRepository(Context context) { mContext = context; mMobileNetworkDatabase = MobileNetworkDatabase.getInstance(context); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); - mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED, - subId); + mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED); mSubscriptionManager = context.getSystemService(SubscriptionManager.class); - mCallback = mobileNetworkCallback; mSubscriptionInfoDao = mMobileNetworkDatabase.mSubscriptionInfoDao(); mUiccInfoDao = mMobileNetworkDatabase.mUiccInfoDao(); mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao(); @@ -138,6 +142,8 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED); mFilter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED); mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED); + mDataSubscriptionChangedReceiver = new DataSubscriptionChangedReceiver(); + mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter); } private class AirplaneModeObserver extends ContentObserver { @@ -157,56 +163,98 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions @Override public void onChange(boolean selfChange, Uri uri) { if (uri.equals(mAirplaneModeSettingUri)) { - mCallback.onAirplaneModeChanged(isAirplaneModeOn()); + boolean isAirplaneModeOn = isAirplaneModeOn(); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onAirplaneModeChanged(isAirplaneModeOn); + } } } } - private final BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() { + private class DataSubscriptionChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { onSubscriptionsChanged(); } - }; + } - public void addRegister(LifecycleOwner lifecycleOwner) { + /** + * Register all callbacks and listener. + * + * @param lifecycleOwner The lifecycle owner. + * @param mobileNetworkCallback A callback to receive all MobileNetwork's changes. + * @param subId The subscription ID to register relevant changes and listener for specific + * subscription. + */ + public void addRegister(LifecycleOwner lifecycleOwner, + MobileNetworkCallback mobileNetworkCallback, int subId) { + sCallbacks.add(mobileNetworkCallback); mSubscriptionManager.addOnSubscriptionsChangedListener(mContext.getMainExecutor(), this); mAirplaneModeObserver.register(mContext); - mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter); observeAllSubInfo(lifecycleOwner); observeAllUiccInfo(lifecycleOwner); observeAllMobileNetworkInfo(lifecycleOwner); + if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + addRegisterBySubId(subId); + createTelephonyManagerBySubId(subId); + } } private void addRegisterBySubId(int subId) { - if (!mTelephonyCallbackMap.containsKey(subId) || !mTelephonyManagerMap.containsKey(subId)) { - PhoneCallStateTelephonyCallback - telephonyCallback = new PhoneCallStateTelephonyCallback(); - mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), - telephonyCallback); - mTelephonyCallbackMap.put(subId, telephonyCallback); - mTelephonyManagerMap.put(subId, mTelephonyManager); - } - if (!mDataContentObserverMap.containsKey(subId)) { - MobileDataContentObserver dataContentObserver = new MobileDataContentObserver( - new Handler(Looper.getMainLooper())); - dataContentObserver.register(mContext, subId); - dataContentObserver.setOnMobileDataChangedListener(() -> { - sExecutor.execute(() -> { - insertMobileNetworkInfo(mContext, String.valueOf(subId)); - }); + MobileDataContentObserver dataContentObserver = new MobileDataContentObserver( + new Handler(Looper.getMainLooper())); + dataContentObserver.setOnMobileDataChangedListener(() -> { + sExecutor.execute(() -> { + insertMobileNetworkInfo(mContext, subId, + getTelephonyManagerBySubId(mContext, subId)); }); - mDataContentObserverMap.put(subId, dataContentObserver); + }); + dataContentObserver.register(mContext, subId); + mDataContentObserverMap.put(subId, dataContentObserver); + } + + private void createTelephonyManagerBySubId(int subId) { + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + return; } + PhoneCallStateTelephonyCallback + telephonyCallback = new PhoneCallStateTelephonyCallback(); + TelephonyManager telephonyManager = mContext.getSystemService( + TelephonyManager.class).createForSubscriptionId(subId); + telephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), + telephonyCallback); + mTelephonyCallbackMap.put(subId, telephonyCallback); + mTelephonyManagerMap.put(subId, telephonyManager); + } + + private TelephonyManager getTelephonyManagerBySubId(Context context, int subId) { + TelephonyManager telephonyManager = mTelephonyManagerMap.get(subId); + if (telephonyManager != null) { + return telephonyManager; + } + + if (context != null) { + telephonyManager = context.getSystemService(TelephonyManager.class); + if (telephonyManager != null) { + telephonyManager = telephonyManager.createForSubscriptionId(subId); + } else if (DEBUG) { + Log.d(TAG, "Can not get TelephonyManager for subId " + subId); + } + } + + return telephonyManager; + } private void removerRegisterBySubId(int subId) { if (mTelephonyCallbackMap.containsKey(subId)) { - TelephonyManager tm = mTelephonyManagerMap.get(subId); - PhoneCallStateTelephonyCallback callback = mTelephonyCallbackMap.get(subId); - if (callback != null) { - tm.unregisterTelephonyCallback(callback); - mTelephonyCallbackMap.remove(subId); + TelephonyManager telephonyManager = getTelephonyManagerBySubId(mContext, subId); + if (telephonyManager != null) { + PhoneCallStateTelephonyCallback callback = mTelephonyCallbackMap.get(subId); + if (callback != null) { + telephonyManager.unregisterTelephonyCallback(callback); + mTelephonyCallbackMap.remove(subId); + } } } if (mDataContentObserverMap.containsKey(subId)) { @@ -215,25 +263,43 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions } } - public void removeRegister() { - mSubscriptionManager.removeOnSubscriptionsChangedListener(this); - mAirplaneModeObserver.unRegister(mContext); - if (mDataSubscriptionChangedReceiver != null) { - mContext.unregisterReceiver(mDataSubscriptionChangedReceiver); - } - mDataContentObserverMap.forEach((id, observer) -> { - observer.unRegister(mContext); - }); - mDataContentObserverMap.clear(); - - mTelephonyManagerMap.forEach((id, manager) -> { - TelephonyCallback callback = mTelephonyCallbackMap.get(manager.getSubscriptionId()); - if (callback != null) { - manager.unregisterTelephonyCallback(callback); + public void removeRegister(MobileNetworkCallback mobileNetworkCallback) { + sCallbacks.remove(mobileNetworkCallback); + if (sCallbacks.isEmpty()) { + mSubscriptionManager.removeOnSubscriptionsChangedListener(this); + mAirplaneModeObserver.unRegister(mContext); + if (mDataSubscriptionChangedReceiver != null) { + mContext.unregisterReceiver(mDataSubscriptionChangedReceiver); + mDataSubscriptionChangedReceiver = null; } - }); - mTelephonyCallbackMap.clear(); - mTelephonyManagerMap.clear(); + mDataContentObserverMap.forEach((id, observer) -> { + observer.unRegister(mContext); + }); + mDataContentObserverMap.clear(); + + mTelephonyManagerMap.forEach((id, manager) -> { + TelephonyCallback callback = mTelephonyCallbackMap.get(id); + if (callback != null) { + manager.unregisterTelephonyCallback(callback); + } + }); + mTelephonyCallbackMap.clear(); + mTelephonyManagerMap.clear(); + } + } + + public void updateEntity() { + // Check the latest state after back to the UI. + if (sCacheSubscriptionInfoEntityMap != null || !sCacheSubscriptionInfoEntityMap.isEmpty()) { + sExecutor.execute(() -> { + onSubscriptionsChanged(); + }); + } + + boolean isAirplaneModeOn = isAirplaneModeOn(); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onAirplaneModeChanged(isAirplaneModeOn); + } } private void observeAllSubInfo(LifecycleOwner lifecycleOwner) { @@ -284,18 +350,6 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions return mMobileNetworkInfoDao.queryMobileNetworkInfoBySubId(subId); } - public int getSubInfosCount() { - return mSubscriptionInfoDao.count(); - } - - public int getUiccInfosCount() { - return mUiccInfoDao.count(); - } - - public int getMobileNetworkInfosCount() { - return mMobileNetworkInfoDao.count(); - } - private void getUiccInfoBySubscriptionInfo(UiccSlotInfo[] uiccSlotInfos, SubscriptionInfo subInfo) { for (int i = 0; i < uiccSlotInfos.length; i++) { @@ -317,7 +371,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions mPortIndex = portInfo.getPortIndex(); } else if (DEBUG) { Log.d(TAG, "Can not get port index and physicalSlotIndex for subId " - + mSubId); + + subInfo.getSubscriptionId()); } }); if (mPhysicalSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { @@ -334,70 +388,82 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions private void onAvailableSubInfoChanged( List availableSubInfoEntityList) { - mAvailableSubInfoEntityList = availableSubInfoEntityList; - mActiveSubInfoEntityList = mAvailableSubInfoEntityList.stream() - .filter(SubscriptionInfoEntity::isActiveSubscription) - .filter(SubscriptionInfoEntity::isSubscriptionVisible) - .collect(Collectors.toList()); + mAvailableSubInfoEntityList = new ArrayList<>(availableSubInfoEntityList); if (DEBUG) { Log.d(TAG, "onAvailableSubInfoChanged, availableSubInfoEntityList = " + availableSubInfoEntityList); } - mCallback.onAvailableSubInfoChanged(availableSubInfoEntityList); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onAvailableSubInfoChanged(availableSubInfoEntityList); + } mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_SUB_INFO_IS_CHANGED, 0); - setActiveSubInfoList(mActiveSubInfoEntityList); + onActiveSubInfoListChanged(mAvailableSubInfoEntityList); } - private void setActiveSubInfoList(List activeSubInfoEntityList) { + private void onActiveSubInfoListChanged( + List availableSubInfoEntityList) { + mActiveSubInfoEntityList = availableSubInfoEntityList.stream() + .filter(SubscriptionInfoEntity::isActiveSubscription) + .filter(SubscriptionInfoEntity::isSubscriptionVisible) + .collect(Collectors.toList()); if (DEBUG) { - Log.d(TAG, - "onActiveSubInfoChanged, activeSubInfoEntityList = " + activeSubInfoEntityList); + Log.d(TAG, "onActiveSubInfoChanged, activeSubInfoEntityList = " + + mActiveSubInfoEntityList); + } + List activeSubInfoEntityList = new ArrayList<>( + mActiveSubInfoEntityList); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onActiveSubInfoChanged(activeSubInfoEntityList); } - mCallback.onActiveSubInfoChanged(mActiveSubInfoEntityList); } private void onAllUiccInfoChanged(List uiccInfoEntityList) { - mUiccInfoEntityList = uiccInfoEntityList; - mCallback.onAllUiccInfoChanged(uiccInfoEntityList); + mUiccInfoEntityList = new ArrayList<>(uiccInfoEntityList); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onAllUiccInfoChanged(uiccInfoEntityList); + } mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_UICC_INFO_IS_CHANGED, 0); } private void onAllMobileNetworkInfoChanged( List mobileNetworkInfoEntityList) { - mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList; - mCallback.onAllMobileNetworkInfoChanged(mobileNetworkInfoEntityList); + mMobileNetworkInfoEntityList = new ArrayList<>(mobileNetworkInfoEntityList); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onAllMobileNetworkInfoChanged(mobileNetworkInfoEntityList); + } mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_MOBILE_NETWORK_INFO_IS_CHANGED, 0); } - public void insertSubInfo(Context context, SubscriptionInfo info) { + private void insertSubInfo(Context context, SubscriptionInfo info) { + int subId = info.getSubscriptionId(); + createTelephonyManagerBySubId(subId); + TelephonyManager telephonyManager = getTelephonyManagerBySubId(context, subId); SubscriptionInfoEntity subInfoEntity = - convertToSubscriptionInfoEntity(context, info); - String subId = String.valueOf(mSubId); + convertToSubscriptionInfoEntity(context, info, telephonyManager); if (subInfoEntity != null) { if (!sCacheSubscriptionInfoEntityMap.containsKey(subId) || (sCacheSubscriptionInfoEntityMap.get(subId) != null && !sCacheSubscriptionInfoEntityMap.get(subId).equals(subInfoEntity))) { sCacheSubscriptionInfoEntityMap.put(subId, subInfoEntity); if (DEBUG) { - Log.d(TAG, "convert subId " + subId + "to SubscriptionInfoEntity: " + Log.d(TAG, "Convert subId " + subId + " to SubscriptionInfoEntity: " + subInfoEntity); } mMobileNetworkDatabase.insertSubsInfo(subInfoEntity); - addRegisterBySubId(mSubId); - insertUiccInfo(subId); - insertMobileNetworkInfo(context, subId); mMetricsFeatureProvider.action(mContext, - SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, mSubId); - } else if (DEBUG) { - Log.d(TAG, "Can not insert subInfo, the entity is null"); + SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, subId); + insertUiccInfo(subId, telephonyManager); + insertMobileNetworkInfo(context, subId, telephonyManager); } + } else if (DEBUG) { + Log.d(TAG, "Can not insert subInfo, the entity is null"); } } - public void deleteAllInfoBySubId(String subId) { + private void deleteAllInfoBySubId(String subId) { if (DEBUG) { Log.d(TAG, "deleteAllInfoBySubId, subId = " + subId); } @@ -412,20 +478,23 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions removerRegisterBySubId(id); mSubscriptionInfoMap.remove(id); mTelephonyManagerMap.remove(id); - sCacheSubscriptionInfoEntityMap.remove(subId); - sCacheUiccInfoEntityMap.remove(subId); - sCacheMobileNetworkInfoEntityMap.remove(subId); + sCacheSubscriptionInfoEntityMap.remove(id); + sCacheUiccInfoEntityMap.remove(id); + sCacheMobileNetworkInfoEntityMap.remove(id); mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_DELETE_DATA, id); } - public SubscriptionInfoEntity convertToSubscriptionInfoEntity(Context context, - SubscriptionInfo subInfo) { - mSubId = subInfo.getSubscriptionId(); - mTelephonyManager = context.getSystemService( - TelephonyManager.class).createForSubscriptionId(mSubId); - - UiccSlotInfo[] uiccSlotInfos = mTelephonyManager.getUiccSlotsInfo(); + private SubscriptionInfoEntity convertToSubscriptionInfoEntity(Context context, + SubscriptionInfo subInfo, TelephonyManager telephonyManager) { + int subId = subInfo.getSubscriptionId(); + if (telephonyManager == null) { + if (DEBUG) { + Log.d(TAG, "Can not get TelephonyManager for subId " + subId); + } + return null; + } + UiccSlotInfo[] uiccSlotInfos = telephonyManager.getUiccSlotsInfo(); if (uiccSlotInfos == null || uiccSlotInfos.length == 0) { if (DEBUG) { Log.d(TAG, "uiccSlotInfos = null or empty"); @@ -435,10 +504,10 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions getUiccInfoBySubscriptionInfo(uiccSlotInfos, subInfo); SubscriptionInfo firstRemovableSubInfo = SubscriptionUtil.getFirstRemovableSubscription( context); - if(DEBUG){ - Log.d(TAG, "convert subscriptionInfo to entity for subId = " + mSubId); + if (DEBUG) { + Log.d(TAG, "convert subscriptionInfo to entity for subId = " + subId); } - return new SubscriptionInfoEntity(String.valueOf(mSubId), + return new SubscriptionInfoEntity(String.valueOf(subId), subInfo.getSimSlotIndex(), subInfo.getCarrierId(), subInfo.getDisplayName().toString(), subInfo.getCarrierName() != null ? subInfo.getCarrierName().toString() : "", @@ -451,23 +520,23 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions SubscriptionUtil.isSubscriptionVisible(mSubscriptionManager, context, subInfo), SubscriptionUtil.getFormattedPhoneNumber(context, subInfo), firstRemovableSubInfo == null ? false - : firstRemovableSubInfo.getSubscriptionId() == mSubId, - String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, mSubId)), - SubscriptionUtil.isDefaultSubscription(context, mSubId), - mSubscriptionManager.isValidSubscriptionId(mSubId), - mSubscriptionManager.isUsableSubscriptionId(mSubId), - mSubscriptionManager.isActiveSubscriptionId(mSubId), + : firstRemovableSubInfo.getSubscriptionId() == subId, + String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, subId)), + SubscriptionUtil.isDefaultSubscription(context, subId), + mSubscriptionManager.isValidSubscriptionId(subId), + mSubscriptionManager.isUsableSubscriptionId(subId), + mSubscriptionManager.isActiveSubscriptionId(subId), true /*availableSubInfo*/, - mSubscriptionManager.getDefaultVoiceSubscriptionId() == mSubId, - mSubscriptionManager.getDefaultSmsSubscriptionId() == mSubId, - mSubscriptionManager.getDefaultDataSubscriptionId() == mSubId, - mSubscriptionManager.getDefaultSubscriptionId() == mSubId, - mSubscriptionManager.getActiveDataSubscriptionId() == mSubId); + mSubscriptionManager.getDefaultVoiceSubscriptionId() == subId, + mSubscriptionManager.getDefaultSmsSubscriptionId() == subId, + mSubscriptionManager.getDefaultDataSubscriptionId() == subId, + mSubscriptionManager.getDefaultSubscriptionId() == subId, + mSubscriptionManager.getActiveDataSubscriptionId() == subId); } } - public void insertUiccInfo(String subId) { - UiccInfoEntity uiccInfoEntity = convertToUiccInfoEntity(); + private void insertUiccInfo(int subId, TelephonyManager telephonyManager) { + UiccInfoEntity uiccInfoEntity = convertToUiccInfoEntity(subId, telephonyManager); if (DEBUG) { Log.d(TAG, "uiccInfoEntity = " + uiccInfoEntity); } @@ -476,51 +545,76 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions sCacheUiccInfoEntityMap.put(subId, uiccInfoEntity); mMobileNetworkDatabase.insertUiccInfo(uiccInfoEntity); mMetricsFeatureProvider.action(mContext, - SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_UICC_INFO, - Integer.parseInt(subId)); + SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_UICC_INFO, subId); } } - public void insertMobileNetworkInfo(Context context, String subId) { - MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context); + private void insertMobileNetworkInfo(Context context, int subId, + TelephonyManager telephonyManager) { + MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context, + subId, telephonyManager); + if (DEBUG) { - Log.d(TAG, "mobileNetworkInfoEntity = " + mobileNetworkInfoEntity); + Log.d(TAG, "insertMobileNetworkInfo, mobileNetworkInfoEntity = " + + mobileNetworkInfoEntity); } + + if (mobileNetworkInfoEntity == null) { + return; + } + if (!sCacheMobileNetworkInfoEntityMap.containsKey(subId) || !sCacheMobileNetworkInfoEntityMap.get(subId).equals(mobileNetworkInfoEntity)) { sCacheMobileNetworkInfoEntityMap.put(subId, mobileNetworkInfoEntity); mMobileNetworkDatabase.insertMobileNetworkInfo(mobileNetworkInfoEntity); mMetricsFeatureProvider.action(mContext, - SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_MOBILE_NETWORK_INFO, - Integer.parseInt(subId)); + SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_MOBILE_NETWORK_INFO, subId); } } - public MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context) { - return new MobileNetworkInfoEntity(String.valueOf(mSubId), - MobileNetworkUtils.isContactDiscoveryEnabled(context, mSubId), - MobileNetworkUtils.isContactDiscoveryVisible(context, mSubId), - mTelephonyManager.isDataEnabled(), - MobileNetworkUtils.isCdmaOptions(context, mSubId), - MobileNetworkUtils.isGsmOptions(context, mSubId), - MobileNetworkUtils.isWorldMode(context, mSubId), - MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, mSubId), - MobileNetworkUtils.isTdscdmaSupported(context, mSubId), + private MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context, int subId, + TelephonyManager telephonyManager) { + boolean isDataEnabled = false; + boolean isDataRoamingEnabled = false; + if (telephonyManager != null) { + isDataEnabled = telephonyManager.isDataEnabled(); + isDataRoamingEnabled = telephonyManager.isDataRoamingEnabled(); + } else if (DEBUG) { + Log.d(TAG, "TelephonyManager is null, subId = " + subId); + } + + return new MobileNetworkInfoEntity(String.valueOf(subId), + MobileNetworkUtils.isContactDiscoveryEnabled(context, subId), + MobileNetworkUtils.isContactDiscoveryVisible(context, subId), + isDataEnabled, + MobileNetworkUtils.isCdmaOptions(context, subId), + MobileNetworkUtils.isGsmOptions(context, subId), + MobileNetworkUtils.isWorldMode(context, subId), + MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, subId), + MobileNetworkUtils.isTdscdmaSupported(context, subId), MobileNetworkUtils.activeNetworkIsCellular(context), SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager), - mTelephonyManager.isDataRoamingEnabled() + isDataRoamingEnabled ); } - private UiccInfoEntity convertToUiccInfoEntity() { - return new UiccInfoEntity(String.valueOf(mSubId), String.valueOf(mPhysicalSlotIndex), - mLogicalSlotIndex, mCardId, mIsEuicc, isMultipleEnabledProfilesSupported(), - mCardState, mIsRemovable, mIsActive, mPortIndex + private UiccInfoEntity convertToUiccInfoEntity(int subId, TelephonyManager telephonyManager) { + return new UiccInfoEntity(String.valueOf(subId), String.valueOf(mPhysicalSlotIndex), + mLogicalSlotIndex, mCardId, mIsEuicc, + isMultipleEnabledProfilesSupported(telephonyManager), mCardState, mIsRemovable, + mIsActive, mPortIndex ); } - private boolean isMultipleEnabledProfilesSupported() { - List cardInfos = mTelephonyManager.getUiccCardsInfo(); + private boolean isMultipleEnabledProfilesSupported(TelephonyManager telephonyManager) { + if (telephonyManager == null) { + if (DEBUG) { + Log.d(TAG, "TelephonyManager is null"); + } + return false; + } + + List cardInfos = telephonyManager.getUiccCardsInfo(); if (cardInfos == null) { if (DEBUG) { Log.d(TAG, "UICC card info list is empty."); @@ -574,7 +668,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions // the database, if the subInfo is not existed in the new list, delete it // from the database. for (SubscriptionInfoEntity info : availableInfoArray) { - if (sCacheSubscriptionInfoEntityMap.containsKey(info.subId)) { + if (sCacheSubscriptionInfoEntityMap.containsKey(info.getSubId())) { deleteAllInfoBySubId(info.subId); } } @@ -593,7 +687,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions } continue; } - mSubscriptionInfoMap.put(mSubId, subInfo); + mSubscriptionInfoMap.put(subInfo.getSubscriptionId(), subInfo); insertSubInfo(mContext, subInfo); } } @@ -610,7 +704,9 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions @Override public void onCallStateChanged(int state) { - mCallback.onCallStateChanged(state); + for (MobileNetworkCallback callback : sCallbacks) { + callback.onCallStateChanged(state); + } } } diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java index 449323dd4cb..99a2731e916 100644 --- a/src/com/android/settings/network/MobileNetworkSummaryController.java +++ b/src/com/android/settings/network/MobileNetworkSummaryController.java @@ -22,6 +22,7 @@ import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; import android.content.Context; import android.content.Intent; import android.os.UserManager; +import android.telephony.SubscriptionManager; import android.telephony.euicc.EuiccManager; import android.util.Log; @@ -87,7 +88,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController mMetricsFeatureProvider = FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(); mUserManager = context.getSystemService(UserManager.class); mLifecycleOwner = lifecycleOwner; - mMobileNetworkRepository = MobileNetworkRepository.create(context, this); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); mIsAirplaneModeOn = mMobileNetworkRepository.isAirplaneModeOn(); if (lifecycle != null) { lifecycle.addObserver(this); @@ -96,13 +97,14 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController @OnLifecycleEvent(ON_RESUME) public void onResume() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); - update(); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + mMobileNetworkRepository.updateEntity(); } @OnLifecycleEvent(ON_PAUSE) public void onPause() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @Override diff --git a/src/com/android/settings/network/NetworkProviderCallsSmsController.java b/src/com/android/settings/network/NetworkProviderCallsSmsController.java index ced2b8acfe5..0c71aa71595 100644 --- a/src/com/android/settings/network/NetworkProviderCallsSmsController.java +++ b/src/com/android/settings/network/NetworkProviderCallsSmsController.java @@ -21,6 +21,7 @@ import static androidx.lifecycle.Lifecycle.Event; import android.content.Context; import android.os.UserManager; import android.telephony.ServiceState; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; import android.view.View; @@ -71,7 +72,7 @@ public class NetworkProviderCallsSmsController extends AbstractPreferenceControl mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; mLifecycleOwner = lifecycleOwner; - mMobileNetworkRepository = MobileNetworkRepository.create(context, this); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); if (lifecycle != null) { lifecycle.addObserver(this); } @@ -79,13 +80,14 @@ public class NetworkProviderCallsSmsController extends AbstractPreferenceControl @OnLifecycleEvent(Event.ON_RESUME) public void onResume() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); - update(); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + mMobileNetworkRepository.updateEntity(); } @OnLifecycleEvent(Event.ON_PAUSE) public void onPause() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @Override diff --git a/src/com/android/settings/network/NetworkProviderSimListController.java b/src/com/android/settings/network/NetworkProviderSimListController.java index 46249abaf08..db27291bc76 100644 --- a/src/com/android/settings/network/NetworkProviderSimListController.java +++ b/src/com/android/settings/network/NetworkProviderSimListController.java @@ -65,19 +65,20 @@ public class NetworkProviderSimListController extends AbstractPreferenceControll mSubscriptionManager = context.getSystemService(SubscriptionManager.class); mPreferences = new ArrayMap<>(); mLifecycleOwner = lifecycleOwner; - mMobileNetworkRepository = MobileNetworkRepository.create(context, this); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); lifecycle.addObserver(this); } @OnLifecycleEvent(ON_RESUME) public void onResume() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); - update(); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + mMobileNetworkRepository.updateEntity(); } @OnLifecycleEvent(ON_PAUSE) public void onPause() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @Override diff --git a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java index 46ec61d9f60..b4e768c8f9d 100644 --- a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java +++ b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java @@ -52,7 +52,7 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo LifecycleOwner lifecycleOwner, int subId) { super(context, key); mSubId = subId; - mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); mLifecycleOwner = lifecycleOwner; if (lifecycle != null) { lifecycle.addObserver(this); @@ -66,12 +66,13 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo @OnLifecycleEvent(ON_START) public void onStart() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId); + mMobileNetworkRepository.updateEntity(); } @OnLifecycleEvent(ON_STOP) public void onStop() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @Override diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java index 106929b2928..01ec5df549f 100644 --- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java +++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java @@ -75,7 +75,7 @@ public abstract class DefaultSubscriptionController extends TelephonyBasePrefere mManager = context.getSystemService(SubscriptionManager.class); mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; - mMobileNetworkRepository = MobileNetworkRepository.create(context, this); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); mLifecycleOwner = lifecycleOwner; if (lifecycle != null) { lifecycle.addObserver(this); @@ -104,13 +104,13 @@ public abstract class DefaultSubscriptionController extends TelephonyBasePrefere @OnLifecycleEvent(ON_RESUME) public void onResume() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); - updateEntries(); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, getDefaultSubscriptionId()); + mMobileNetworkRepository.updateEntity(); } @OnLifecycleEvent(ON_PAUSE) public void onPause() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @Override @@ -303,6 +303,4 @@ public abstract class DefaultSubscriptionController extends TelephonyBasePrefere updateEntries(); refreshSummary(mPreference); } - - } diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java index 971bb498ba9..cf78942972c 100644 --- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java +++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java @@ -58,7 +58,6 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon private SwitchPreference mPreference; private TelephonyManager mTelephonyManager; private SubscriptionManager mSubscriptionManager; - private MobileDataContentObserver mDataContentObserver; private FragmentManager mFragmentManager; @VisibleForTesting int mDialogType; @@ -79,9 +78,7 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon super(context, key); mSubId = subId; mSubscriptionManager = context.getSystemService(SubscriptionManager.class); - mDataContentObserver = new MobileDataContentObserver(new Handler(Looper.getMainLooper())); - mDataContentObserver.setOnMobileDataChangedListener(() -> updateState(mPreference)); - mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); mLifecycleOwner = lifecycleOwner; if (lifecycle != null) { lifecycle.addObserver(this); @@ -103,12 +100,13 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon @OnLifecycleEvent(ON_START) public void onStart() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId); + mMobileNetworkRepository.updateEntity(); } @OnLifecycleEvent(ON_STOP) public void onStop() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @Override diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index a9c92186611..0f2d02bfabf 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -158,7 +158,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme MobileNetworkUtils.getSearchableSubscriptionId(context)); Log.d(LOG_TAG, "display subId from getArguments(): " + mSubId); } - mMobileNetworkRepository = MobileNetworkRepository.create(context, this); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); mExecutor.execute(() -> { mSubscriptionInfoEntity = mMobileNetworkRepository.getSubInfoById( String.valueOf(mSubId)); @@ -177,6 +177,8 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme new SmsDefaultSubscriptionController(context, KEY_SMS_PREF, getSettingsLifecycle(), this), new MobileDataPreferenceController(context, KEY_MOBILE_DATA_PREF, + getSettingsLifecycle(), this, mSubId), + new ConvertToEsimPreferenceController(context, KEY_CONVERT_TO_ESIM_PREF, getSettingsLifecycle(), this, mSubId)); } @@ -322,7 +324,8 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme @Override public void onResume() { super.onResume(); - mMobileNetworkRepository.addRegister(this); + mMobileNetworkRepository.addRegister(this, this, mSubId); + mMobileNetworkRepository.updateEntity(); // TODO: remove log after fixing b/182326102 Log.d(LOG_TAG, "onResume() subId=" + mSubId); } @@ -350,7 +353,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme @Override public void onDestroy() { super.onDestroy(); - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); } @VisibleForTesting @@ -505,7 +508,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme break; } else if (entity.isDefaultSubscriptionSelection) { mSubscriptionInfoEntity = entity; - Log.d(LOG_TAG, "Set subInfo to the default subInfo."); + Log.d(LOG_TAG, "Set subInfo to default subInfo."); } } onSubscriptionDetailChanged(); diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java index 308da88ed34..265eb167fed 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java +++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java @@ -949,7 +949,12 @@ public class MobileNetworkUtils { boolean isWifiCallingEnabled; if (phoneAccountHandle != null) { final Intent intent = buildPhoneAccountConfigureIntent(context, phoneAccountHandle); - isWifiCallingEnabled = intent != null; + if (intent == null) { + Log.d(TAG, "Can not get phoneAccount configure intent."); + isWifiCallingEnabled = false; + } else { + isWifiCallingEnabled = true; + } } else { if (queryImsState == null) { queryImsState = new WifiCallingQueryImsState(context, subId); @@ -959,7 +964,6 @@ public class MobileNetworkUtils { return isWifiCallingEnabled; } - /** * Returns preferred status of Calls & SMS separately when Provider Model is enabled. */ diff --git a/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java b/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java index 688084f4488..7ad9e03a1a8 100644 --- a/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java +++ b/src/com/android/settings/network/telephony/NetworkProviderWifiCallingGroup.java @@ -314,29 +314,13 @@ public class NetworkProviderWifiCallingGroup extends @VisibleForTesting protected boolean shouldShowWifiCallingForSub(int subId) { if (SubscriptionManager.isValidSubscriptionId(subId) - && MobileNetworkUtils.isWifiCallingEnabled( - mContext, subId, queryImsState(subId), - getPhoneAccountHandleForSubscriptionId(subId)) - && isWifiCallingAvailableForCarrier(subId)) { + && MobileNetworkUtils.isWifiCallingEnabled(mContext, subId, queryImsState(subId), + null)) { return true; } return false; } - private boolean isWifiCallingAvailableForCarrier(int subId) { - boolean isWifiCallingAvailableForCarrier = false; - if (mCarrierConfigManager != null) { - final PersistableBundle carrierConfig = - mCarrierConfigManager.getConfigForSubId(subId); - if (carrierConfig != null) { - isWifiCallingAvailableForCarrier = carrierConfig.getBoolean( - CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL); - } - } - Log.d(TAG, "isWifiCallingAvailableForCarrier:" + isWifiCallingAvailableForCarrier); - return isWifiCallingAvailableForCarrier; - } - @Override public String getPreferenceKey() { return KEY_PREFERENCE_WIFICALLING_GROUP; diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java index af56a88a98d..ff5da52525b 100644 --- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java +++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java @@ -81,7 +81,7 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro super(context, key); mSubId = subId; mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class); - mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); mLifecycleOwner = lifecycleOwner; if (lifecycle != null) { lifecycle.addObserver(this); @@ -100,7 +100,8 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro @OnLifecycleEvent(ON_START) public void onStart() { - mMobileNetworkRepository.addRegister(mLifecycleOwner); + mMobileNetworkRepository.addRegister(mLifecycleOwner, this, mSubId); + mMobileNetworkRepository.updateEntity(); if (mListener == null) { mListener = new GlobalSettingsChangeListener(mContext, Settings.Global.DATA_ROAMING) { @@ -126,7 +127,7 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro @OnLifecycleEvent(ON_STOP) public void onStop() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(this); stopMonitor(); stopMonitorSubIdSpecific(); } diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java index 2d7ba38a801..1bc2f908e3d 100644 --- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java @@ -25,7 +25,6 @@ import android.provider.Settings; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; -import android.telephony.PhoneStateListener; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java index c0b903df3c4..e3e83dcb337 100644 --- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java +++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java @@ -267,7 +267,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon private void queryNetworkSelectionMode(String tag) { mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode(); - Log.d(LOG_TAG, tag + ": query commend done. mCacheOfModeStatus: " + mCacheOfModeStatus); + Log.d(LOG_TAG, tag + ": query command done. mCacheOfModeStatus: " + mCacheOfModeStatus); } @VisibleForTesting diff --git a/src/com/android/settings/notification/app/ConversationNotificationSettings.java b/src/com/android/settings/notification/app/ConversationNotificationSettings.java index b452309f84c..02ea6c060ec 100644 --- a/src/com/android/settings/notification/app/ConversationNotificationSettings.java +++ b/src/com/android/settings/notification/app/ConversationNotificationSettings.java @@ -99,6 +99,7 @@ public class ConversationNotificationSettings extends NotificationSettings { mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(), mBackend, false /* isAppPage */, null /* dependentFieldListener */)); mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend)); + mControllers.add(new ConversationPromotePreferenceController(context, this, mBackend)); mControllers.add(new BubbleCategoryPreferenceController(context)); mControllers.add(new BubbleLinkPreferenceController(context)); return new ArrayList<>(mControllers); diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt index fbdde0b982c..7f7d8c544b4 100644 --- a/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt +++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt @@ -16,17 +16,25 @@ package com.android.settings.spa.app.appinfo +import android.app.AppOpsManager import android.content.Context import android.content.pm.ApplicationInfo import android.os.UserManager +import android.widget.Toast import androidx.compose.runtime.Composable import androidx.compose.runtime.State +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settings.Utils +import com.android.settings.applications.appinfo.AppInfoDashboardFragment import com.android.settingslib.spa.widget.scaffold.MoreOptionsAction +import com.android.settingslib.spaprivileged.framework.common.appOpsManager import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager import com.android.settingslib.spaprivileged.framework.common.userManager import com.android.settingslib.spaprivileged.model.app.IPackageManagers @@ -35,6 +43,8 @@ import com.android.settingslib.spaprivileged.model.app.userId import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.template.scaffold.RestrictedMenuItem import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.withContext @Composable @@ -44,13 +54,11 @@ fun AppInfoSettingsMoreOptions( packageManagers: IPackageManagers = PackageManagers, ) { val state = app.produceState(packageManagers).value ?: return - when { - // We don't allow uninstalling update for DO/PO if it's a system app, because it will clear - // data on all users. We also don't allow uninstalling for all users if it's DO/PO for any - // user. - state.isProfileOrDeviceOwner -> return - !state.shownUninstallUpdates && !state.shownUninstallForAllUsers -> return - } + var restrictedSettingsAllowed by rememberSaveable { mutableStateOf(false) } + if (!state.shownUninstallUpdates && + !state.shownUninstallForAllUsers && + !(state.shouldShowAccessRestrictedSettings && !restrictedSettingsAllowed) + ) return MoreOptionsAction { val restrictions = Restrictions(userId = app.userId, keys = listOf(UserManager.DISALLOW_APPS_CONTROL)) @@ -70,13 +78,37 @@ fun AppInfoSettingsMoreOptions( packageInfoPresenter.startUninstallActivity(forAllUsers = true) } } + if (state.shouldShowAccessRestrictedSettings && !restrictedSettingsAllowed) { + MenuItem(text = stringResource(R.string.app_restricted_settings_lockscreen_title)) { + app.allowRestrictedSettings(packageInfoPresenter.context) { + restrictedSettingsAllowed = true + } + } + } + } +} + +private fun ApplicationInfo.allowRestrictedSettings(context: Context, onSuccess: () -> Unit) { + AppInfoDashboardFragment.showLockScreen(context) { + context.appOpsManager.setMode( + AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, + uid, + packageName, + AppOpsManager.MODE_ALLOWED, + ) + onSuccess() + val toastString = context.getString( + R.string.toast_allows_restricted_settings_successfully, + loadLabel(context.packageManager), + ) + Toast.makeText(context, toastString, Toast.LENGTH_LONG).show() } } private data class AppInfoSettingsMoreOptionsState( - val isProfileOrDeviceOwner: Boolean, val shownUninstallUpdates: Boolean, val shownUninstallForAllUsers: Boolean, + val shouldShowAccessRestrictedSettings: Boolean, ) @Composable @@ -86,20 +118,40 @@ private fun ApplicationInfo.produceState( val context = LocalContext.current return produceState(initialValue = null, this) { withContext(Dispatchers.IO) { - value = AppInfoSettingsMoreOptionsState( - isProfileOrDeviceOwner = Utils.isProfileOrDeviceOwner( - context.userManager, context.devicePolicyManager, packageName - ), - shownUninstallUpdates = isShowUninstallUpdates(context), - shownUninstallForAllUsers = isShowUninstallForAllUsers( - userManager = context.userManager, - packageManagers = packageManagers, - ), - ) + value = getMoreOptionsState(context, packageManagers) } } } +private suspend fun ApplicationInfo.getMoreOptionsState( + context: Context, + packageManagers: IPackageManagers, +) = coroutineScope { + val shownUninstallUpdatesDeferred = async { + isShowUninstallUpdates(context) + } + val shownUninstallForAllUsersDeferred = async { + isShowUninstallForAllUsers( + userManager = context.userManager, + packageManagers = packageManagers, + ) + } + val shouldShowAccessRestrictedSettingsDeferred = async { + shouldShowAccessRestrictedSettings(context.appOpsManager) + } + val isProfileOrDeviceOwner = + Utils.isProfileOrDeviceOwner(context.userManager, context.devicePolicyManager, packageName) + AppInfoSettingsMoreOptionsState( + // We don't allow uninstalling update for DO/PO if it's a system app, because it will clear + // data on all users. + shownUninstallUpdates = !isProfileOrDeviceOwner && shownUninstallUpdatesDeferred.await(), + // We also don't allow uninstalling for all users if it's DO/PO for any user. + shownUninstallForAllUsers = + !isProfileOrDeviceOwner && shownUninstallForAllUsersDeferred.await(), + shouldShowAccessRestrictedSettings = shouldShowAccessRestrictedSettingsDeferred.await(), + ) +} + private fun ApplicationInfo.isShowUninstallUpdates(context: Context): Boolean = isUpdatedSystemApp && context.userManager.isUserAdmin(userId) && !context.resources.getBoolean(R.bool.config_disable_uninstall_update) @@ -116,3 +168,8 @@ private fun ApplicationInfo.isOtherUserHasInstallPackage( ): Boolean = userManager.aliveUsers .filter { it.id != userId } .any { packageManagers.isPackageInstalledAsUser(packageName, it.id) } + +private fun ApplicationInfo.shouldShowAccessRestrictedSettings(appOpsManager: AppOpsManager) = + appOpsManager.noteOpNoThrow( + AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, uid, packageName, null, null + ) == AppOpsManager.MODE_IGNORED diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettings.java b/src/com/android/settings/wifi/calling/WifiCallingSettings.java index 89266964ba7..42ce1b13bab 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettings.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettings.java @@ -257,7 +257,8 @@ public class WifiCallingSettings extends SettingsPreferenceFragment for (SubscriptionInfo subInfo : subInfoList) { int subId = subInfo.getSubscriptionId(); try { - if (queryImsState(subId).isWifiCallingProvisioned()) { + if (MobileNetworkUtils.isWifiCallingEnabled(getContext(), subId, + queryImsState(subId), null)) { selectedList.add(subInfo); } } catch (Exception exception) {} diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java index b5735efc2f5..912fada3229 100644 --- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java @@ -95,10 +95,11 @@ public class MobileNetworkSummaryControllerTest { doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class); doReturn(mEuiccManager).when(mContext).getSystemService(EuiccManager.class); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mMobileNetworkRepository = MobileNetworkRepository.create(mContext, mMobileNetworkCallback); + mMobileNetworkRepository = MobileNetworkRepository.getInstance(mContext); mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); - mMobileNetworkRepository.addRegister(mLifecycleOwner); + mMobileNetworkRepository.addRegister(mLifecycleOwner, mMobileNetworkCallback, + SubscriptionManager.INVALID_SUBSCRIPTION_ID); when(mTelephonyManager.getNetworkCountryIso()).thenReturn(""); when(mSubscriptionManager.isActiveSubscriptionId(anyInt())).thenReturn(true); @@ -114,7 +115,7 @@ public class MobileNetworkSummaryControllerTest { @After public void tearDown() { - mMobileNetworkRepository.removeRegister(); + mMobileNetworkRepository.removeRegister(mMobileNetworkCallback); SubscriptionUtil.setActiveSubscriptionsForTesting(null); SubscriptionUtil.setAvailableSubscriptionsForTesting(null); } diff --git a/tests/spa_unit/AndroidManifest.xml b/tests/spa_unit/AndroidManifest.xml index ec777410080..5a7f5659ce6 100644 --- a/tests/spa_unit/AndroidManifest.xml +++ b/tests/spa_unit/AndroidManifest.xml @@ -19,6 +19,8 @@ xmlns:tools="http://schemas.android.com/tools" package="com.android.settings.tests.spa_unit"> + + diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt index 318debab238..71035163057 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptionsTest.kt @@ -16,6 +16,8 @@ package com.android.settings.spa.app.appinfo +import android.app.AppOpsManager +import android.app.KeyguardManager import android.app.admin.DevicePolicyManager import android.content.Context import android.content.pm.ApplicationInfo @@ -27,6 +29,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performClick import androidx.test.core.app.ApplicationProvider @@ -36,6 +39,7 @@ import com.android.settings.R import com.android.settings.Utils import com.android.settingslib.spa.testutils.delay import com.android.settingslib.spa.testutils.waitUntilExists +import com.android.settingslib.spaprivileged.framework.common.appOpsManager import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager import com.android.settingslib.spaprivileged.framework.common.userManager import com.android.settingslib.spaprivileged.model.app.IPackageManagers @@ -46,6 +50,7 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock +import org.mockito.Mockito.verify import org.mockito.MockitoSession import org.mockito.Spy import org.mockito.quality.Strictness @@ -73,6 +78,12 @@ class AppInfoSettingsMoreOptionsTest { @Mock private lateinit var devicePolicyManager: DevicePolicyManager + @Mock + private lateinit var appOpsManager: AppOpsManager + + @Mock + private lateinit var keyguardManager: KeyguardManager + @Spy private var resources = context.resources @@ -90,6 +101,9 @@ class AppInfoSettingsMoreOptionsTest { whenever(context.packageManager).thenReturn(packageManager) whenever(context.userManager).thenReturn(userManager) whenever(context.devicePolicyManager).thenReturn(devicePolicyManager) + whenever(context.appOpsManager).thenReturn(appOpsManager) + whenever(context.getSystemService(KeyguardManager::class.java)).thenReturn(keyguardManager) + whenever(keyguardManager.isKeyguardSecure).thenReturn(false) whenever(Utils.isProfileOrDeviceOwner(userManager, devicePolicyManager, PACKAGE_NAME)) .thenReturn(false) } @@ -143,6 +157,35 @@ class AppInfoSettingsMoreOptionsTest { ) } + @Test + fun shouldShowAccessRestrictedSettings() { + whenever( + appOpsManager.noteOpNoThrow( + AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, UID, PACKAGE_NAME, null, null + ) + ).thenReturn(AppOpsManager.MODE_IGNORED) + val app = ApplicationInfo().apply { + packageName = PACKAGE_NAME + uid = UID + } + + setContent(app) + composeTestRule.onRoot().performClick() + + composeTestRule.waitUntilExists( + hasText(context.getString(R.string.app_restricted_settings_lockscreen_title)) + ) + composeTestRule + .onNodeWithText(context.getString(R.string.app_restricted_settings_lockscreen_title)) + .performClick() + verify(appOpsManager).setMode( + AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, + UID, + PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED, + ) + } + private fun setContent(app: ApplicationInfo) { composeTestRule.setContent { CompositionLocalProvider(LocalContext provides context) { diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java index 39fd6577324..9cfa7ed20c9 100644 --- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java @@ -75,7 +75,7 @@ public class CredentialManagerPreferenceControllerTest { mScreen.addPreference(mCredentialsPreferenceCategory); } - @Test + /*@Test // Tests that getAvailabilityStatus() does not throw an exception if it's called before the // Controller is initialized (this can happen during indexing). public void getAvailabilityStatus_withoutInit_returnsUnavailable() { @@ -122,11 +122,11 @@ public class CredentialManagerPreferenceControllerTest { @Test public void buildSwitchPreference() { CredentialProviderInfo providerInfo1 = - createCredentialProviderInfoWithIsEnabled( - "com.android.provider1", "ClassA", "Service Title", false); + createCredentialProviderInfoWithSubtitle( + "com.android.provider1", "ClassA", "Service Title", null); CredentialProviderInfo providerInfo2 = - createCredentialProviderInfoWithIsEnabled( - "com.android.provider2", "ClassA", "Service Title", false); + createCredentialProviderInfoWithSubtitle( + "com.android.provider2", "ClassA", "Service Title", "Summary Text"); CredentialManagerPreferenceController controller = createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); @@ -147,11 +147,13 @@ public class CredentialManagerPreferenceControllerTest { SwitchPreference pref = controller.createPreference(mContext, providerInfo1); assertThat(pref.getTitle().toString()).isEqualTo("Service Title"); assertThat(pref.isChecked()).isTrue(); + assertThat(pref.getSummary()).isNull(); // Create the pref (not checked). SwitchPreference pref2 = controller.createPreference(mContext, providerInfo2); assertThat(pref2.getTitle().toString()).isEqualTo("Service Title"); assertThat(pref2.isChecked()).isFalse(); + assertThat(pref2.getSummary().toString()).isEqualTo("Summary Text"); } @Test @@ -250,7 +252,7 @@ public class CredentialManagerPreferenceControllerTest { assertThat(enabledServices.size()).isEqualTo(1); assertThat(enabledServices.contains("com.android.provider1/ClassA")).isFalse(); assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue(); - } + }*/ @Test public void displayPreference_withServices_preferencesAdded_sameAppShouldBeMerged() { @@ -297,6 +299,7 @@ public class CredentialManagerPreferenceControllerTest { Map prefs = controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory); + assertThat(prefs.keySet()).containsExactly(TEST_PACKAGE_NAME_A, TEST_PACKAGE_NAME_B, TEST_PACKAGE_NAME_C); assertThat(prefs.size()).isEqualTo(3); assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A)).isTrue(); assertThat(prefs.get(TEST_PACKAGE_NAME_A).getTitle()).isEqualTo(TEST_TITLE_APP_A); @@ -335,6 +338,23 @@ public class CredentialManagerPreferenceControllerTest { .build(); } + private CredentialProviderInfo createCredentialProviderInfoWithSubtitle( + String packageName, String className, CharSequence label, CharSequence subtitle) { + ServiceInfo si = new ServiceInfo(); + si.packageName = packageName; + si.name = className; + si.nonLocalizedLabel = "test"; + + si.applicationInfo = new ApplicationInfo(); + si.applicationInfo.packageName = packageName; + si.applicationInfo.nonLocalizedLabel = "test"; + + return new CredentialProviderInfo.Builder(si) + .setOverrideLabel(label) + .setSettingsSubtitle(subtitle) + .build(); + } + private CredentialProviderInfo createCredentialProviderInfoWithAppLabel( String packageName, String className, CharSequence serviceLabel, String appLabel) { return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel)