Snap for 9781601 from f0c3812123
to udc-release
Change-Id: Ib62514e1789ecc564d9d57fe30e05b9b089a6f88
This commit is contained in:
@@ -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>
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
@@ -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.
|
||||
*/
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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) {}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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">
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user