Snap for 9781601 from f0c3812123 to udc-release

Change-Id: Ib62514e1789ecc564d9d57fe30e05b9b089a6f88
This commit is contained in:
Android Build Coastguard Worker
2023-03-21 03:27:33 +00:00
26 changed files with 486 additions and 263 deletions

View File

@@ -96,4 +96,11 @@
android:summary="@string/demote_conversation_summary"
settings:allowDividerAbove="true"/>
<!-- only used in ChannelPanelActivity -->
<Preference
android:key="convo_promote"
android:icon="@drawable/ic_promote_conversation"
android:title="@string/promote_conversation_title"
android:summary="@string/promote_conversation_summary" />
</PreferenceScreen>

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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<String, SubscriptionInfoEntity> sCacheSubscriptionInfoEntityMap =
private static Map<Integer, SubscriptionInfoEntity> sCacheSubscriptionInfoEntityMap =
new ArrayMap<>();
private static Map<String, MobileNetworkInfoEntity> sCacheMobileNetworkInfoEntityMap =
private static Map<Integer, MobileNetworkInfoEntity> sCacheMobileNetworkInfoEntityMap =
new ArrayMap<>();
private static Map<String, UiccInfoEntity> sCacheUiccInfoEntityMap = new ArrayMap<>();
private static Map<Integer, UiccInfoEntity> sCacheUiccInfoEntityMap = new ArrayMap<>();
private static Collection<MobileNetworkCallback> 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<SubscriptionInfoEntity> mActiveSubInfoEntityList = new ArrayList<>();
private List<UiccInfoEntity> mUiccInfoEntityList = new ArrayList<>();
private List<MobileNetworkInfoEntity> 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<Integer, SubscriptionInfo> mSubscriptionInfoMap = new ArrayMap<>();
private Map<Integer, TelephonyManager> mTelephonyManagerMap = new HashMap<>();
private Map<Integer, PhoneCallStateTelephonyCallback> 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<SubscriptionInfoEntity> 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<SubscriptionInfoEntity> activeSubInfoEntityList) {
private void onActiveSubInfoListChanged(
List<SubscriptionInfoEntity> 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<SubscriptionInfoEntity> activeSubInfoEntityList = new ArrayList<>(
mActiveSubInfoEntityList);
for (MobileNetworkCallback callback : sCallbacks) {
callback.onActiveSubInfoChanged(activeSubInfoEntityList);
}
mCallback.onActiveSubInfoChanged(mActiveSubInfoEntityList);
}
private void onAllUiccInfoChanged(List<UiccInfoEntity> 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<MobileNetworkInfoEntity> 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<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
private boolean isMultipleEnabledProfilesSupported(TelephonyManager telephonyManager) {
if (telephonyManager == null) {
if (DEBUG) {
Log.d(TAG, "TelephonyManager is null");
}
return false;
}
List<UiccCardInfo> 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);
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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.
*/

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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<AppInfoSettingsMoreOptionsState?>(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

View File

@@ -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) {}

View File

@@ -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);
}

View File

@@ -19,6 +19,8 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.settings.tests.spa_unit">
<uses-permission android:name="android.permission.MANAGE_APPOPS" />
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
<application android:debuggable="true">

View File

@@ -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) {

View File

@@ -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<String, SwitchPreference> 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)