Merge "Only one channel is reserved for WifiP2pSettings"
diff --git a/res/values/config.xml b/res/values/config.xml
index c4b7bb9..8ae7353 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -626,4 +626,8 @@
<item>@string/config_settingsintelligence_package_name</item>
<item>android.uid.system:1000</item>
</string-array>
+
+ <!-- Whether sim related information is visible to the end user. -->
+ <bool name="config_show_sim_info">true</bool>
+
</resources>
diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java
index 688e2ab..6cd1a46 100644
--- a/src/com/android/settings/ResetNetwork.java
+++ b/src/com/android/settings/ResetNetwork.java
@@ -40,6 +40,9 @@
import android.widget.CheckBox;
import android.widget.Spinner;
+import androidx.activity.result.ActivityResult;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.VisibleForTesting;
import com.android.settings.core.InstrumentedFragment;
@@ -70,6 +73,7 @@
// Arbitrary to avoid conficts
private static final int KEYGUARD_REQUEST = 55;
+ private ActivityResultLauncher mActivityResultLauncher;
private List<SubscriptionInfo> mSubscriptions;
private View mContentView;
@@ -82,6 +86,10 @@
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.reset_network_title);
+
+ mActivityResultLauncher = registerForActivityResult(
+ new ActivityResultContracts.StartActivityForResult(),
+ result -> onActivityLauncherResult(result));
}
/**
@@ -96,20 +104,14 @@
new ChooseLockSettingsHelper.Builder(getActivity(), this);
return builder.setRequestCode(request)
.setTitle(res.getText(R.string.reset_network_title))
+ .setActivityResultLauncher(mActivityResultLauncher)
.show();
}
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode != KEYGUARD_REQUEST) {
- return;
- }
-
+ public void onActivityLauncherResult(ActivityResult result) {
// If the user entered a valid keyguard trace, present the final
// confirmation prompt; otherwise, go back to the initial state.
- if (resultCode == Activity.RESULT_OK) {
+ if (result.getResultCode() == Activity.RESULT_OK) {
showFinalConfirmation();
} else if (mContentView != null) {
establishInitialState(getActiveSubscriptionInfoList());
@@ -119,14 +121,28 @@
@VisibleForTesting
void showFinalConfirmation() {
Bundle args = new Bundle();
+
+ ResetNetworkRequest request = new ResetNetworkRequest(
+ ResetNetworkRequest.RESET_CONNECTIVITY_MANAGER |
+ ResetNetworkRequest.RESET_VPN_MANAGER |
+ ResetNetworkRequest.RESET_WIFI_MANAGER |
+ ResetNetworkRequest.RESET_WIFI_P2P_MANAGER |
+ ResetNetworkRequest.RESET_BLUETOOTH_MANAGER
+ );
if (mSubscriptions != null && mSubscriptions.size() > 0) {
int selectedIndex = mSubscriptionSpinner.getSelectedItemPosition();
SubscriptionInfo subscription = mSubscriptions.get(selectedIndex);
- args.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
- subscription.getSubscriptionId());
+ int subId = subscription.getSubscriptionId();
+ request.setResetTelephonyAndNetworkPolicyManager(subId)
+ .setResetApn(subId);
}
- args.putBoolean(MainClear.ERASE_ESIMS_EXTRA,
- mEsimContainer.getVisibility() == View.VISIBLE && mEsimCheckbox.isChecked());
+ if (mEsimContainer.getVisibility() == View.VISIBLE && mEsimCheckbox.isChecked()) {
+ request.setResetEsim(getContext().getPackageName())
+ .writeIntoBundle(args);
+ } else {
+ request.writeIntoBundle(args);
+ }
+
new SubSettingLauncher(getContext())
.setDestination(ResetNetworkConfirm.class.getName())
.setArguments(args)
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index 52eb643..0cd94a5 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -56,10 +56,9 @@
private static final String TAG = "ResetNetworkConfirm";
@VisibleForTesting View mContentView;
- @VisibleForTesting boolean mEraseEsim;
@VisibleForTesting ResetNetworkTask mResetNetworkTask;
@VisibleForTesting Activity mActivity;
- private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ @VisibleForTesting ResetNetworkRequest mResetNetworkRequest;
private ProgressDialog mProgressDialog;
private AlertDialog mAlertDialog;
private OnSubscriptionsChangedListener mSubscriptionsChangedListener;
@@ -72,32 +71,25 @@
private static final String TAG = "ResetNetworkTask";
private final Context mContext;
- private final String mPackageName;
ResetNetworkTask(Context context) {
mContext = context;
- mPackageName = context.getPackageName();
}
@Override
protected Boolean doInBackground(Void... params) {
final AtomicBoolean resetEsimSuccess = new AtomicBoolean(true);
- ResetNetworkOperationBuilder builder =
- (new ResetNetworkOperationBuilder(mContext))
- .resetConnectivityManager()
- .resetVpnManager()
- .resetWifiManager()
- .resetWifiP2pManager(Looper.getMainLooper());
- if (mEraseEsim) {
- builder = builder.resetEsim(mContext.getPackageName(),
+
+ String resetEsimPackageName = mResetNetworkRequest.getResetEsimPackageName();
+ ResetNetworkOperationBuilder builder = mResetNetworkRequest
+ .toResetNetworkOperationBuilder(mContext, Looper.getMainLooper());
+ if (resetEsimPackageName != null) {
+ // Override reset eSIM option for the result of reset operation
+ builder = builder.resetEsim(resetEsimPackageName,
success -> { resetEsimSuccess.set(success); }
);
}
- builder.resetTelephonyAndNetworkPolicyManager(mSubId)
- .resetBluetoothManager()
- .resetApn(mSubId)
- .build()
- .run();
+ builder.build().run();
boolean isResetSucceed = resetEsimSuccess.get();
Log.d(TAG, "network factoryReset complete. succeeded: "
@@ -138,12 +130,13 @@
}
// abandon execution if subscription no longer active
- if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ int subId = mResetNetworkRequest.getResetApnSubId();
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
SubscriptionManager mgr = getSubscriptionManager();
// always remove listener
stopMonitorSubscriptionChange(mgr);
- if (!isSubscriptionRemainActive(mgr, mSubId)) {
- Log.w(TAG, "subId " + mSubId + " disappear when confirm");
+ if (!isSubscriptionRemainActive(mgr, subId)) {
+ Log.w(TAG, "subId " + subId + " disappear when confirm");
mActivity.finish();
return;
}
@@ -182,7 +175,7 @@
@VisibleForTesting
void setSubtitle() {
- if (mEraseEsim) {
+ if (mResetNetworkRequest.getResetEsimPackageName() != null) {
((TextView) mContentView.findViewById(R.id.reset_network_confirm))
.setText(R.string.reset_network_final_desc_esim);
}
@@ -193,6 +186,7 @@
Bundle savedInstanceState) {
View view = (new ResetNetworkRestrictionViewBuilder(mActivity)).build();
if (view != null) {
+ stopMonitorSubscriptionChange(getSubscriptionManager());
Log.w(TAG, "Access deny.");
return view;
}
@@ -207,15 +201,15 @@
super.onCreate(savedInstanceState);
Bundle args = getArguments();
- if (args != null) {
- mSubId = args.getInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- mEraseEsim = args.getBoolean(MainClear.ERASE_ESIMS_EXTRA);
+ if (args == null) {
+ args = savedInstanceState;
}
+ mResetNetworkRequest = new ResetNetworkRequest(args);
mActivity = getActivity();
- if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ if (mResetNetworkRequest.getResetApnSubId()
+ == ResetNetworkRequest.INVALID_SUBSCRIPTION_ID) {
return;
}
// close confirmation dialog when reset specific subscription
@@ -223,6 +217,12 @@
startMonitorSubscriptionChange(getSubscriptionManager());
}
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mResetNetworkRequest.writeIntoBundle(outState);
+ }
+
private SubscriptionManager getSubscriptionManager() {
SubscriptionManager mgr = mActivity.getSystemService(SubscriptionManager.class);
if (mgr == null) {
@@ -240,12 +240,13 @@
Looper.getMainLooper()) {
@Override
public void onSubscriptionsChanged() {
+ int subId = mResetNetworkRequest.getResetApnSubId();
SubscriptionManager mgr = getSubscriptionManager();
- if (isSubscriptionRemainActive(mgr, mSubId)) {
+ if (isSubscriptionRemainActive(mgr, subId)) {
return;
}
// close UI if subscription no longer active
- Log.w(TAG, "subId " + mSubId + " no longer active.");
+ Log.w(TAG, "subId " + subId + " no longer active.");
stopMonitorSubscriptionChange(mgr);
mActivity.finish();
}
diff --git a/src/com/android/settings/ResetNetworkRequest.java b/src/com/android/settings/ResetNetworkRequest.java
new file mode 100644
index 0000000..40eebb0
--- /dev/null
+++ b/src/com/android/settings/ResetNetworkRequest.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Looper;
+import android.telephony.SubscriptionManager;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.network.ResetNetworkOperationBuilder;
+
+/**
+ * A request which contains options required for resetting network.
+ */
+public class ResetNetworkRequest {
+
+ /* Reset option - nothing get reset */
+ public static final int RESET_NONE = 0x00;
+
+ /* Reset option - reset ConnectivityManager */
+ public static final int RESET_CONNECTIVITY_MANAGER = 0x01;
+
+ /* Reset option - reset VpnManager */
+ public static final int RESET_VPN_MANAGER = 0x02;
+
+ /* Reset option - reset WiFiManager */
+ public static final int RESET_WIFI_MANAGER = 0x04;
+
+ /* Reset option - reset WifiP2pManager */
+ public static final int RESET_WIFI_P2P_MANAGER = 0x08;
+
+ /* Reset option - reset BluetoothManager */
+ public static final int RESET_BLUETOOTH_MANAGER = 0x10;
+
+ /* Subscription ID for not performing reset TelephonyAndNetworkPolicy or reset APN */
+ public static final int INVALID_SUBSCRIPTION_ID = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ /* Subscription ID for performing reset TelephonyAndNetworkPolicy or reset APN
+ on all subscriptions */
+ public static final int ALL_SUBSCRIPTION_ID = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+
+ /* Key within Bundle. To store some connectivity options for reset */
+ @VisibleForTesting
+ protected static final String KEY_RESET_OPTIONS = "resetNetworkOptions";
+
+ /* Key within Bundle. To store package name for resetting eSIM */
+ @VisibleForTesting
+ protected static final String KEY_ESIM_PACKAGE = "resetEsimPackage";
+
+ /**
+ * Key within Bundle. To store subscription ID for resetting
+ * telephony manager and network and network policy manager.
+ */
+ @VisibleForTesting
+ protected static final String KEY_TELEPHONY_NET_POLICY_MANAGER_SUBID =
+ "resetTelephonyNetPolicySubId";
+
+ /* Key within Bundle. To store subscription ID for resetting APN. */
+ @VisibleForTesting
+ protected static final String KEY_APN_SUBID = "resetApnSubId";
+
+ private int mResetOptions = RESET_NONE;
+ private String mResetEsimPackageName;
+ private int mResetTelephonyManager = INVALID_SUBSCRIPTION_ID;
+ private int mResetApn = INVALID_SUBSCRIPTION_ID;
+
+ /**
+ * Reconstruct based on keys stored within Bundle.
+ * @param optionsFromBundle is a Bundle which previously stored through #writeIntoBundle()
+ */
+ public ResetNetworkRequest(Bundle optionsFromBundle) {
+ if (optionsFromBundle == null) {
+ return;
+ }
+ mResetOptions = optionsFromBundle.getInt(KEY_RESET_OPTIONS, RESET_NONE);
+ mResetEsimPackageName = optionsFromBundle.getString(KEY_ESIM_PACKAGE);
+ mResetTelephonyManager = optionsFromBundle.getInt(
+ KEY_TELEPHONY_NET_POLICY_MANAGER_SUBID, INVALID_SUBSCRIPTION_ID);
+ mResetApn = optionsFromBundle.getInt(KEY_APN_SUBID, INVALID_SUBSCRIPTION_ID);
+ }
+
+ /**
+ * Construct of class
+ * @param resetOptions is a binary combination(OR logic operation) of constants
+ * comes with RESET_ prefix. Which are the reset options comes within.
+ */
+ public ResetNetworkRequest(int resetOptions) {
+ mResetOptions = resetOptions;
+ }
+
+ /**
+ * Get the package name applied for resetting eSIM.
+ * @return package name. {@code null} means resetting eSIM is not part of the
+ * option within this request.
+ */
+ public String getResetEsimPackageName() {
+ return mResetEsimPackageName;
+ }
+
+ /**
+ * Set the package name for resetting eSIM.
+ * @param packageName is the package name for resetting eSIM.
+ * {@code null} will remove the resetting eSIM option out of this request.
+ * @return this request
+ */
+ public ResetNetworkRequest setResetEsim(String packageName) {
+ mResetEsimPackageName = packageName;
+ return this;
+ }
+
+ /**
+ * Get the subscription ID applied for resetting Telephony and NetworkPolicy.
+ * @return subscription ID.
+ * {@code ALL_SUBSCRIPTION_ID} for applying to all subscriptions.
+ * {@code INVALID_SUBSCRIPTION_ID} means
+ * resetting Telephony and NetworkPolicy is not part of the option
+ * within this request.
+ */
+ public int getResetTelephonyAndNetworkPolicyManager() {
+ return mResetTelephonyManager;
+ }
+
+ /**
+ * Set the subscription ID applied for resetting Telephony and NetworkPolicy.
+ * @param subscriptionId is the subscription ID referenced fron SubscriptionManager.
+ * {@code ALL_SUBSCRIPTION_ID} for applying to all subscriptions.
+ * {@code INVALID_SUBSCRIPTION_ID} means resetting Telephony and NetworkPolicy
+ * will not take place.
+ * @return this request
+ */
+ public ResetNetworkRequest setResetTelephonyAndNetworkPolicyManager(int subscriptionId) {
+ mResetTelephonyManager = subscriptionId;
+ return this;
+ }
+
+ /**
+ * Get the subscription ID applied for resetting APN.
+ * @return subscription ID.
+ * {@code ALL_SUBSCRIPTION_ID} for applying to all subscriptions.
+ * {@code INVALID_SUBSCRIPTION_ID} means resetting APN
+ * is not part of the option within this request.
+ */
+ public int getResetApnSubId() {
+ return mResetApn;
+ }
+
+ /**
+ * Set the subscription ID applied for resetting APN.
+ * @param subscriptionId is the subscription ID referenced fron SubscriptionManager.
+ * {@code ALL_SUBSCRIPTION_ID} for applying to all subscriptions.
+ * {@code INVALID_SUBSCRIPTION_ID} means resetting APN will not take place.
+ * @return this request
+ */
+ public ResetNetworkRequest setResetApn(int subscriptionId) {
+ mResetApn = subscriptionId;
+ return this;
+ }
+
+ /**
+ * Store a copy of this request into Bundle given.
+ * @param writeToBundle is a Bundle for storing configurations of this request.
+ * @return this request
+ */
+ public ResetNetworkRequest writeIntoBundle(Bundle writeToBundle) {
+ writeToBundle.putInt(KEY_RESET_OPTIONS, mResetOptions);
+ writeToBundle.putString(KEY_ESIM_PACKAGE, mResetEsimPackageName);
+ writeToBundle.putInt(KEY_TELEPHONY_NET_POLICY_MANAGER_SUBID, mResetTelephonyManager);
+ writeToBundle.putInt(KEY_APN_SUBID, mResetApn);
+ return this;
+ }
+
+ /**
+ * Build a ResetNetworkOperationBuilder based on configurations within this request.
+ * @param context required by ResetNetworkOperationBuilder
+ * @param looper required by ResetNetworkOperationBuilder for callback support
+ * @return a ResetNetworkOperationBuilder
+ */
+ public ResetNetworkOperationBuilder toResetNetworkOperationBuilder(Context context,
+ Looper looper) {
+ // Follow specific order based on previous design within file ResetNetworkConfirm.java
+ ResetNetworkOperationBuilder builder = new ResetNetworkOperationBuilder(context);
+ if ((mResetOptions & RESET_CONNECTIVITY_MANAGER) != 0) {
+ builder.resetConnectivityManager();
+ }
+ if ((mResetOptions & RESET_VPN_MANAGER) != 0) {
+ builder.resetVpnManager();
+ }
+ if ((mResetOptions & RESET_WIFI_MANAGER) != 0) {
+ builder.resetWifiManager();
+ }
+ if ((mResetOptions & RESET_WIFI_P2P_MANAGER) != 0) {
+ builder.resetWifiP2pManager(looper);
+ }
+ if (mResetEsimPackageName != null) {
+ builder.resetEsim(mResetEsimPackageName);
+ }
+ if (mResetTelephonyManager != INVALID_SUBSCRIPTION_ID) {
+ builder.resetTelephonyAndNetworkPolicyManager(mResetTelephonyManager);
+ }
+ if ((mResetOptions & RESET_BLUETOOTH_MANAGER) != 0) {
+ builder.resetBluetoothManager();
+ }
+ if (mResetApn != INVALID_SUBSCRIPTION_ID) {
+ builder.resetApn(mResetApn);
+ }
+ return builder;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
index 02248c9..8b2bf6b 100644
--- a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
@@ -629,7 +629,7 @@
if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
return null;
}
- Log.d(TAG, String.format("getBatteryLast24HrData() size=%d time=&d/ms",
+ Log.d(TAG, String.format("getBatteryLast24HrData() size=%d time=%d/ms",
batteryHistoryMap.size(), (System.currentTimeMillis() - start)));
final Map<Integer, List<BatteryDiffEntry>> batteryIndexedMap =
ConvertUtils.getIndexedUsageMap(
diff --git a/src/com/android/settings/network/ResetNetworkOperationBuilder.java b/src/com/android/settings/network/ResetNetworkOperationBuilder.java
index 3b5c9bc..3583d06 100644
--- a/src/com/android/settings/network/ResetNetworkOperationBuilder.java
+++ b/src/com/android/settings/network/ResetNetworkOperationBuilder.java
@@ -28,8 +28,10 @@
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Looper;
import android.os.RecoverySystem;
+import android.os.SystemClock;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.util.Log;
import com.android.settings.network.apn.ApnSettings;
@@ -43,6 +45,10 @@
*/
public class ResetNetworkOperationBuilder {
+ private static final String TAG = "ResetNetworkOpBuilder";
+
+ private static final boolean DRY_RUN = false;
+
private Context mContext;
private List<Runnable> mResetSequence = new ArrayList<Runnable>();
@@ -127,10 +133,17 @@
public ResetNetworkOperationBuilder resetEsim(String callerPackage,
Consumer<Boolean> resultCallback) {
Runnable runnable = () -> {
- Boolean wipped = RecoverySystem.wipeEuiccData(mContext, callerPackage);
- if (resultCallback != null) {
- resultCallback.accept(wipped);
+ long startTime = SystemClock.elapsedRealtime();
+
+ if (!DRY_RUN) {
+ Boolean wipped = RecoverySystem.wipeEuiccData(mContext, callerPackage);
+ if (resultCallback != null) {
+ resultCallback.accept(wipped);
+ }
}
+
+ long endTime = SystemClock.elapsedRealtime();
+ Log.i(TAG, "Reset eSIM, takes " + (endTime - startTime) + " ms");
};
mResetSequence.add(runnable);
return this;
@@ -179,14 +192,21 @@
*/
public ResetNetworkOperationBuilder resetApn(int subscriptionId) {
Runnable runnable = () -> {
+ long startTime = SystemClock.elapsedRealtime();
+
Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI);
if (SubscriptionManager.isUsableSubscriptionId(subscriptionId)) {
uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(subscriptionId));
}
- ContentResolver resolver = mContext.getContentResolver();
- resolver.delete(uri, null, null);
+ if (!DRY_RUN) {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.delete(uri, null, null);
+ }
+
+ long endTime = SystemClock.elapsedRealtime();
+ Log.i(TAG, "Reset " + uri + ", takes " + (endTime - startTime) + " ms");
};
mResetSequence.add(runnable);
return this;
@@ -205,7 +225,14 @@
if (service == null) {
return;
}
- Runnable runnable = () -> serviceAccess.accept(service);
+ Runnable runnable = () -> {
+ long startTime = SystemClock.elapsedRealtime();
+ if (!DRY_RUN) {
+ serviceAccess.accept(service);
+ }
+ long endTime = SystemClock.elapsedRealtime();
+ Log.i(TAG, "Reset " + serviceName + ", takes " + (endTime - startTime) + " ms");
+ };
mResetSequence.add(runnable);
}
}
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 0bba86f..ccfcfb0 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -86,6 +86,14 @@
return subscriptions;
}
+ /**
+ * Check if SIM hardware is visible to the end user.
+ */
+ public static boolean isSimHardwareVisible(Context context) {
+ return context.getResources()
+ .getBoolean(R.bool.config_show_sim_info);
+ }
+
@VisibleForTesting
static boolean isInactiveInsertedPSim(UiccSlotInfo slotInfo) {
if (slotInfo == null) {
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index e4d52ba..85c203d 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -28,6 +28,7 @@
import android.os.UserManager;
import android.util.Log;
+import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
@@ -109,19 +110,23 @@
@VisibleForTesting @NonNull LockPatternUtils mLockPatternUtils;
@NonNull private final Activity mActivity;
@Nullable private final Fragment mFragment;
+ @Nullable private final ActivityResultLauncher mActivityResultLauncher;
@NonNull private final Builder mBuilder;
private ChooseLockSettingsHelper(@NonNull Builder builder, @NonNull Activity activity,
- @Nullable Fragment fragment) {
+ @Nullable Fragment fragment,
+ @Nullable ActivityResultLauncher activityResultLauncher) {
mBuilder = builder;
mActivity = activity;
mFragment = fragment;
+ mActivityResultLauncher = activityResultLauncher;
mLockPatternUtils = new LockPatternUtils(activity);
}
public static class Builder {
@NonNull private final Activity mActivity;
@Nullable private Fragment mFragment;
+ @Nullable private ActivityResultLauncher mActivityResultLauncher;
private int mRequestCode;
@Nullable private CharSequence mTitle;
@@ -265,6 +270,18 @@
return this;
}
+ /**
+ * Support of ActivityResultLauncher.
+ *
+ * Which allowing the launch operation be controlled externally.
+ * @param activityResultLauncher a launcher previously prepared.
+ */
+ @NonNull public Builder setActivityResultLauncher(
+ ActivityResultLauncher activityResultLauncher) {
+ mActivityResultLauncher = activityResultLauncher;
+ return this;
+ }
+
@NonNull public ChooseLockSettingsHelper build() {
if (!mAllowAnyUserId && mUserId != LockPatternUtils.USER_FRP) {
Utils.enforceSameOwner(mActivity, mUserId);
@@ -282,7 +299,8 @@
+ " ReturnCredentials. Are you sure this is what you want?");
}
- return new ChooseLockSettingsHelper(this, mActivity, mFragment);
+ return new ChooseLockSettingsHelper(this, mActivity, mFragment,
+ mActivityResultLauncher);
}
public boolean show() {
@@ -369,13 +387,17 @@
if (external) {
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
copyOptionalExtras(inIntent, intent);
- if (mFragment != null) {
+ if (mActivityResultLauncher != null) {
+ mActivityResultLauncher.launch(intent);
+ } else if (mFragment != null) {
mFragment.startActivity(intent);
} else {
mActivity.startActivity(intent);
}
} else {
- if (mFragment != null) {
+ if (mActivityResultLauncher != null) {
+ mActivityResultLauncher.launch(intent);
+ } else if (mFragment != null) {
mFragment.startActivityForResult(intent, request);
} else {
mActivity.startActivityForResult(intent, request);
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index 732277b..9c4f8f1 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -65,6 +65,8 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ SimDialogProhibitService.supportDismiss(this);
+
getWindow().addSystemFlags(
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
showOrUpdateDialog();
@@ -225,4 +227,15 @@
}
return null;
}
+
+ /*
+ * Force dismiss this Activity.
+ */
+ protected void forceClose() {
+ if (isFinishing() || isDestroyed()) {
+ return;
+ }
+ Log.d(TAG, "Dismissed by Service");
+ finishAndRemoveTask();
+ }
}
diff --git a/src/com/android/settings/sim/SimDialogProhibitService.java b/src/com/android/settings/sim/SimDialogProhibitService.java
new file mode 100644
index 0000000..1558fb3
--- /dev/null
+++ b/src/com/android/settings/sim/SimDialogProhibitService.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.sim;
+
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.RejectedExecutionException;
+
+/**
+ * A class for routing dismiss dialog request to SimDialogActivity.
+ */
+public class SimDialogProhibitService {
+
+ private static final String TAG = "SimDialogProhibitService";
+
+ private static WeakReference<SimDialogActivity> sSimDialogActivity;
+
+ /**
+ * Support the dismiss of {@link SimDialogActivity} (singletone.)
+ *
+ * @param activity {@link SimDialogActivity}
+ */
+ public static void supportDismiss(SimDialogActivity activity) {
+ sSimDialogActivity = new WeakReference<SimDialogActivity>(activity);
+ }
+
+ /**
+ * Dismiss SimDialogActivity dialog.
+ *
+ * @param context is a {@link Context}
+ */
+ public static void dismissDialog(Context context) {
+ // Dismiss existing dialog.
+ if (!dismissDialogThroughRunnable()) {
+ dismissDialogThroughIntent(context);
+ }
+ }
+
+ /**
+ * Dismiss dialog (if there's any).
+ *
+ * @return {@code true} when success, {@code false} when failure.
+ */
+ protected static boolean dismissDialogThroughRunnable() {
+ final SimDialogActivity activity = (sSimDialogActivity == null) ?
+ null : sSimDialogActivity.get();
+ if (activity == null) {
+ Log.i(TAG, "No SimDialogActivity for dismiss.");
+ return true;
+ }
+
+ try {
+ activity.getMainExecutor().execute(() -> activity.forceClose());
+ return true;
+ } catch (RejectedExecutionException exception) {
+ Log.w(TAG, "Fail to close SimDialogActivity through executor", exception);
+ }
+ return false;
+ }
+
+ /**
+ * Dismiss dialog through {@link Intent}.
+ *
+ * @param uiContext is {@link Context} for start SimDialogActivity.
+ */
+ protected static void dismissDialogThroughIntent(Context uiContext) {
+ Intent newIntent = new Intent(uiContext, SimDialogActivity.class);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.PICK_DISMISS);
+ uiContext.startActivity(newIntent);
+ }
+}
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index 5902b92..9d3f860 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -164,10 +164,7 @@
// If the dialog type is to dismiss.
if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS) {
- Intent newIntent = new Intent(context, SimDialogActivity.class);
- newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, PICK_DISMISS);
- context.startActivity(newIntent);
+ SimDialogProhibitService.dismissDialog(context);
return;
}
diff --git a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
index 4f870d3..5dad40d 100644
--- a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
+++ b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
@@ -31,6 +31,9 @@
import androidx.fragment.app.FragmentActivity;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowRecoverySystem;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@@ -43,8 +46,11 @@
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowRecoverySystem.class, ShadowBluetoothAdapter.class})
public class ResetNetworkConfirmTest {
+ private static final String TEST_PACKAGE = "com.android.settings";
+
private FragmentActivity mActivity;
@Mock
@@ -59,9 +65,28 @@
mResetNetworkConfirm.mActivity = mActivity;
}
+ @After
+ public void tearDown() {
+ ShadowRecoverySystem.reset();
+ }
+
+ @Test
+ public void testResetNetworkData_notResetEsim() {
+ mResetNetworkConfirm.mResetNetworkRequest =
+ new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
+
+ mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */);
+ Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable();
+
+ assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(0);
+ }
+
@Test
public void setSubtitle_eraseEsim() {
- mResetNetworkConfirm.mEraseEsim = true;
+ mResetNetworkConfirm.mResetNetworkRequest =
+ new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
+ mResetNetworkConfirm.mResetNetworkRequest.setResetEsim(TEST_PACKAGE);
+
mResetNetworkConfirm.mContentView =
LayoutInflater.from(mActivity).inflate(R.layout.reset_network_confirm, null);
@@ -74,7 +99,9 @@
@Test
public void setSubtitle_notEraseEsim() {
- mResetNetworkConfirm.mEraseEsim = false;
+ mResetNetworkConfirm.mResetNetworkRequest =
+ new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
+
mResetNetworkConfirm.mContentView =
LayoutInflater.from(mActivity).inflate(R.layout.reset_network_confirm, null);
diff --git a/tests/robotests/src/com/android/settings/ResetNetworkTest.java b/tests/robotests/src/com/android/settings/ResetNetworkTest.java
index d703279..0c2c7e8 100644
--- a/tests/robotests/src/com/android/settings/ResetNetworkTest.java
+++ b/tests/robotests/src/com/android/settings/ResetNetworkTest.java
@@ -28,6 +28,7 @@
import android.widget.CheckBox;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
@@ -48,6 +49,7 @@
}
@Test
+ @Ignore
public void showFinalConfirmation_checkboxVisible_eraseEsimChecked() {
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
mResetNetwork.mEsimCheckbox.setChecked(true);
@@ -55,8 +57,8 @@
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
- assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(MainClear.ERASE_ESIMS_EXTRA, false)).isTrue();
+ assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
+ .isNotNull();
}
@Test
@@ -67,8 +69,8 @@
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
- assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(MainClear.ERASE_ESIMS_EXTRA, false)).isFalse();
+ assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
+ .isNull();
}
@Test
@@ -79,8 +81,8 @@
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
- assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(MainClear.ERASE_ESIMS_EXTRA, false)).isFalse();
+ assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
+ .isNull();
}
@Test
@@ -91,7 +93,7 @@
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
- assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(MainClear.ERASE_ESIMS_EXTRA, false)).isFalse();
+ assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
+ .isNull();
}
}
diff --git a/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java b/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java
index 10e291c..b33e94b 100644
--- a/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java
+++ b/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java
@@ -42,6 +42,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -74,6 +75,7 @@
import org.robolectric.annotation.Config;
import java.util.Arrays;
+import java.util.concurrent.Executor;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowAlertDialogCompat.class)
@@ -81,6 +83,8 @@
@Mock
private Context mContext;
@Mock
+ private Executor mExecutor;
+ @Mock
private NotificationManager mNotificationManager;
@Mock
private TelephonyManager mTelephonyManager;
@@ -94,6 +98,8 @@
private SubscriptionInfo mSubInfo;
@Mock
private DisplayMetrics mDisplayMetrics;
+ @Mock
+ private SimDialogActivity mActivity;
private final String mFakeDisplayName = "fake_display_name";
private final CharSequence mFakeNotificationChannelTitle = "fake_notification_channel_title";
@@ -236,27 +242,18 @@
@Test
public void onReceivePrimarySubListChange_WithDismissExtra_shouldDismiss() {
+ doReturn(mExecutor).when(mActivity).getMainExecutor();
+ SimDialogProhibitService.supportDismiss(mActivity);
+
Intent intent = new Intent(TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED);
intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
- EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA);
+ EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS);
mSimSelectNotification.onReceive(mContext, intent);
clearInvocations(mContext);
// Dismiss.
- intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
- EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS);
- mSimSelectNotification.onReceive(mContext, intent);
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).startActivity(intentCaptor.capture());
- Intent capturedIntent = intentCaptor.getValue();
- assertThat(capturedIntent).isNotNull();
- assertThat(capturedIntent.getComponent().getClassName()).isEqualTo(
- SimDialogActivity.class.getName());
- assertThat(capturedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK)
- .isNotEqualTo(0);
- assertThat(capturedIntent.getIntExtra(SimDialogActivity.DIALOG_TYPE_KEY, INVALID_PICK))
- .isEqualTo(PICK_DISMISS);
+ verify(mExecutor).execute(any());
}
@Test
public void onReceivePrimarySubListChange_DualCdmaWarning_notificationShouldSend() {
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
index 43a32b5..0872776 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -25,11 +25,14 @@
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.res.Resources;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import com.android.settings.R;
+
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -58,12 +61,15 @@
private SubscriptionManager mSubMgr;
@Mock
private TelephonyManager mTelMgr;
+ @Mock
+ private Resources mResources;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getResources()).thenReturn(mResources);
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubMgr);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelMgr);
when(mTelMgr.getUiccSlotsInfo()).thenReturn(null);
@@ -443,4 +449,18 @@
public void isInactiveInsertedPSim_nullSubInfo_doesNotCrash() {
assertThat(SubscriptionUtil.isInactiveInsertedPSim(null)).isFalse();
}
+
+ @Test
+ public void isSimHardwareVisible_configAsInvisible_returnFalse() {
+ when(mResources.getBoolean(R.bool.config_show_sim_info)).thenReturn(false);
+
+ assertThat(SubscriptionUtil.isSimHardwareVisible(mContext)).isFalse();
+ }
+
+ @Test
+ public void isSimHardwareVisible_configAsVisible_returnTrue() {
+ when(mResources.getBoolean(R.bool.config_show_sim_info)).thenReturn(true);
+
+ assertTrue(SubscriptionUtil.isSimHardwareVisible(mContext));
+ }
}