Merge "Add new warning dialogue when user is Resetting mobile network settings." into 24D1-dev

This commit is contained in:
Rafael Higuera Silva
2024-04-05 23:43:02 +00:00
committed by Android (Google) Code Review
8 changed files with 195 additions and 17 deletions

View File

@@ -49,6 +49,7 @@ import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.ResetNetworkRestrictionViewBuilder;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.telephony.EuiccRacConnectivityDialogActivity;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
@@ -121,6 +122,8 @@ public class ResetNetwork extends InstrumentedFragment {
@VisibleForTesting
void showFinalConfirmation() {
Bundle args = new Bundle();
Context context = getContext();
boolean resetSims = false;
// TODO(b/317276437) Simplify the logic once flag is released
int resetOptions = ResetNetworkRequest.RESET_CONNECTIVITY_MANAGER
@@ -142,18 +145,25 @@ public class ResetNetwork extends InstrumentedFragment {
}
}
if (mEsimContainer.getVisibility() == View.VISIBLE && mEsimCheckbox.isChecked()) {
request.setResetEsim(getContext().getPackageName())
.writeIntoBundle(args);
resetSims = true;
request.setResetEsim(context.getPackageName()).writeIntoBundle(args);
} else {
request.writeIntoBundle(args);
}
new SubSettingLauncher(getContext())
.setDestination(ResetNetworkConfirm.class.getName())
.setArguments(args)
.setTitleRes(R.string.reset_mobile_network_settings_confirm_title)
.setSourceMetricsCategory(getMetricsCategory())
.launch();
SubSettingLauncher launcher =
new SubSettingLauncher(context)
.setDestination(ResetNetworkConfirm.class.getName())
.setArguments(args)
.setTitleRes(R.string.reset_mobile_network_settings_confirm_title)
.setSourceMetricsCategory(getMetricsCategory());
if (resetSims && SubscriptionUtil.shouldShowRacDialog(context)) {
context.startActivity(
EuiccRacConnectivityDialogActivity.getIntent(context, launcher.toIntent()));
} else {
launcher.launch();
}
}
/**

View File

@@ -17,12 +17,14 @@
package com.android.settings.core;
import android.annotation.StringRes;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
@@ -129,14 +131,22 @@ public class SubSettingLauncher {
}
public void launch() {
launchWithIntent(toIntent());
}
/**
* Launch sub settings activity with an intent.
*
* @param intent the settings intent we want to launch
*/
public void launchWithIntent(@NonNull Intent intent) {
verifyIntent(intent);
if (mLaunched) {
throw new IllegalStateException(
"This launcher has already been executed. Do not reuse");
}
mLaunched = true;
final Intent intent = toIntent();
boolean launchAsUser = mLaunchRequest.mUserHandle != null
&& mLaunchRequest.mUserHandle.getIdentifier() != UserHandle.myUserId();
boolean launchForResult = mLaunchRequest.mResultListener != null;
@@ -152,6 +162,28 @@ public class SubSettingLauncher {
}
}
/**
* Verify intent is correctly constructed.
*
* @param intent the intent to verify
*/
@VisibleForTesting
public void verifyIntent(@NonNull Intent intent) {
String className = SubSettings.class.getName();
ComponentName componentName = intent.getComponent();
String destinationName = intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT);
int sourceMetricsCategory =
intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1);
if (componentName != null && !TextUtils.equals(className, componentName.getClassName())) {
throw new IllegalArgumentException(String.format("Class must be: %s", className));
} else if (TextUtils.isEmpty(destinationName)) {
throw new IllegalArgumentException("Destination fragment must be set");
} else if (sourceMetricsCategory < 0) {
throw new IllegalArgumentException("Source metrics category must be set");
}
}
public Intent toIntent() {
final Intent intent = new Intent(Intent.ACTION_MAIN);
copyExtras(intent);

View File

@@ -50,8 +50,7 @@ public class EraseEuiccDataController extends BasePreferenceController {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
if (SubscriptionUtil.hasSubscriptionWithRacCarrier(mContext)
&& !SubscriptionUtil.isConnectedToWifi(mContext)) {
if (SubscriptionUtil.shouldShowRacDialog(mContext)) {
EuiccRacConnectivityDialogFragment.show(mHostFragment);
} else {
EraseEuiccDataDialogFragment.show(mHostFragment);

View File

@@ -80,6 +80,7 @@ public class SubscriptionUtil {
private static List<SubscriptionInfo> sAvailableResultsForTesting;
private static List<SubscriptionInfo> sActiveResultsForTesting;
@Nullable private static Boolean sEnableRacDialogForTesting;
@VisibleForTesting
public static void setAvailableSubscriptionsForTesting(List<SubscriptionInfo> results) {
@@ -91,6 +92,11 @@ public class SubscriptionUtil {
sActiveResultsForTesting = results;
}
@VisibleForTesting
public static void setEnableRacDialogForTesting(boolean enableRacDialog) {
sEnableRacDialogForTesting = enableRacDialog;
}
public static List<SubscriptionInfo> getActiveSubscriptions(SubscriptionManager manager) {
//TODO (b/315499317) : Refactor the subscription utils.
@@ -908,6 +914,19 @@ public class SubscriptionUtil {
return Arrays.stream(carriersThatUseRAC).anyMatch(cid -> cid == carrierId);
}
/**
* Check if warning dialog should be presented when erasing all eSIMS.
*
* @param context Context to check if any sim carrier use RAC and device Wi-Fi connection.
* @return {@code true} if dialog should be presented to the user.
*/
public static boolean shouldShowRacDialog(@NonNull Context context) {
if (sEnableRacDialogForTesting != null) {
return sEnableRacDialogForTesting;
}
return !isConnectedToWifi(context) && hasSubscriptionWithRacCarrier(context);
}
/**
* Retrieves NetworkCapabilities for the active network.
*

View File

@@ -23,21 +23,28 @@ import android.telephony.SubscriptionManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
/** This dialog activity advise the user to have connectivity if the eSIM uses a RAC. */
public class EuiccRacConnectivityDialogActivity extends SubscriptionActionDialogActivity
public class EuiccRacConnectivityDialogActivity extends FragmentActivity
implements WarningDialogFragment.OnConfirmListener {
private static final String TAG = "EuiccRacConnectivityDialogActivity";
// Dialog tags
private static final int DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION = 1;
private static final String ARG_SUB_ID = "sub_id";
private static final String ARG_RESET_MOBILE_NETWORK_ID = "reset_mobile_netword_id";
private int mSubId;
@Nullable
private Intent mResetMobileNetworkIntent;
/**
* Returns an intent of EuiccRacConnectivityDialogActivity.
* Returns an intent of EuiccRacConnectivityDialogActivity for Settings: erase eSIM.
*
* @param context The context used to start the EuiccRacConnectivityDialogActivity.
* @param subId The subscription ID of the subscription needs to be deleted. If the subscription
@@ -50,12 +57,29 @@ public class EuiccRacConnectivityDialogActivity extends SubscriptionActionDialog
return intent;
}
/**
* Returns an intent of EuiccRacConnectivityDialogActivity for Reset: Mobile network settings.
*
* @param context The context used to start the EuiccRacConnectivityDialogActivity.
* @param resetMobileNetworkIntent The intent that will continue the reset of mobile network
* settings.
*/
@NonNull
public static Intent getIntent(@NonNull Context context,
@NonNull Intent resetMobileNetworkIntent) {
Intent intent = new Intent(context, EuiccRacConnectivityDialogActivity.class);
intent.putExtra(ARG_RESET_MOBILE_NETWORK_ID, resetMobileNetworkIntent);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
mSubId = intent.getIntExtra(ARG_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mResetMobileNetworkIntent =
intent.getParcelableExtra(ARG_RESET_MOBILE_NETWORK_ID, Intent.class);
if (savedInstanceState == null) {
showConnectivityWarningDialog();
@@ -72,8 +96,13 @@ public class EuiccRacConnectivityDialogActivity extends SubscriptionActionDialog
switch (tag) {
case DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION:
finish();
Log.i(TAG, "Show dialogue activity that handles deleting eSIM profiles");
startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId));
if (mResetMobileNetworkIntent != null) {
Log.i(TAG, "Show fragment activity that handles mobile network settings reset");
new SubSettingLauncher(this).launchWithIntent(mResetMobileNetworkIntent);
} else {
Log.i(TAG, "Show dialogue activity that handles deleting eSIM profiles");
startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId));
}
break;
default:
Log.e(TAG, "Unrecognized confirmation dialog tag: " + tag);

View File

@@ -27,6 +27,9 @@ import android.content.Intent;
import android.view.View;
import android.widget.CheckBox;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.telephony.EuiccRacConnectivityDialogActivity;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -51,6 +54,7 @@ public class ResetNetworkTest {
@Test
@Ignore
public void showFinalConfirmation_checkboxVisible_eraseEsimChecked() {
SubscriptionUtil.setEnableRacDialogForTesting(true);
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
mResetNetwork.mEsimCheckbox.setChecked(true);
@@ -61,6 +65,21 @@ public class ResetNetworkTest {
.isNotNull();
}
@Test
public void showFinalConfirmation_checkboxVisible_eraseEsimChecked_showRacWarningDialog() {
SubscriptionUtil.setEnableRacDialogForTesting(true);
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
mResetNetwork.mEsimCheckbox.setChecked(true);
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent).isNotNull();
assertThat(intent.getComponent().getClassName()).isEqualTo(
EuiccRacConnectivityDialogActivity.class.getName());
}
@Test
public void showFinalConfirmation_checkboxVisible_eraseEsimUnchecked() {
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);

View File

@@ -67,7 +67,7 @@ public class SubSettingLauncherTest {
}
@Test(expected = IllegalStateException.class)
public void cannotReuseLauncher() {
public void cannotReuseLauncher_launchMethod() {
final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext))
.setDestination(SubSettingLauncherTest.class.getName())
.setSourceMetricsCategory(123);
@@ -76,6 +76,43 @@ public class SubSettingLauncherTest {
launcher.launch();
}
@Test(expected = IllegalArgumentException.class)
public void verifyIntent_noDestination() {
final SubSettingLauncher launcher =
spy(new SubSettingLauncher(mContext))
.setSourceMetricsCategory(123);
doNothing().when(launcher).launch(any(Intent.class));
launcher.launchWithIntent(launcher.toIntent());
}
@Test(expected = IllegalArgumentException.class)
public void verifyIntent_noMetricsCategory() {
final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext))
.setDestination(SubSettingLauncherTest.class.getName());
doNothing().when(launcher).launch(any(Intent.class));
launcher.launchWithIntent(launcher.toIntent());
}
@Test(expected = IllegalArgumentException.class)
public void verifyIntent_notTheCorrectClass() {
final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext))
.setDestination(SubSettingLauncherTest.class.getName())
.setSourceMetricsCategory(123);
doNothing().when(launcher).launch(any(Intent.class));
launcher.launchWithIntent(new Intent(Intent.ACTION_MAIN));
}
@Test(expected = IllegalStateException.class)
public void cannotReuseLauncher_launchAndLaunchWithIntentMethod() {
final SubSettingLauncher launcher =
spy(new SubSettingLauncher(mContext))
.setDestination(SubSettingLauncherTest.class.getName())
.setSourceMetricsCategory(123);
doNothing().when(launcher).launch(any(Intent.class));
launcher.launchWithIntent(launcher.toIntent());
launcher.launch();
}
@Test(expected = IllegalArgumentException.class)
public void launch_noSourceMetricsCategory_shouldCrash() {
final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext))

View File

@@ -649,6 +649,39 @@ public class SubscriptionUtilTest {
assertFalse(SubscriptionUtil.isConnectedToWifi(mContext));
}
@Test
public void hasSubscriptionWithRacCarrier_hasNoWifi_showRacDialog_returnTrue() {
when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);
final SubscriptionInfo info = mock(SubscriptionInfo.class);
when(info.getCarrierId()).thenReturn(RAC_CARRIER_ID);
when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
addNetworkTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH);
assertTrue(SubscriptionUtil.shouldShowRacDialog(mContext));
}
@Test
public void hasSubscriptionWithRacCarrier_hasWifi_showRacDialog_returnFalse() {
when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);
final SubscriptionInfo info = mock(SubscriptionInfo.class);
when(info.getCarrierId()).thenReturn(RAC_CARRIER_ID);
when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
addNetworkTransportType(NetworkCapabilities.TRANSPORT_WIFI);
assertFalse(SubscriptionUtil.shouldShowRacDialog(mContext));
}
@Test
public void hasNoSubscriptionWithRacCarrier_hasNoWifi_showRacDialog_returnFalse() {
when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);
final SubscriptionInfo info = mock(SubscriptionInfo.class);
when(info.getCarrierId()).thenReturn(NO_RAC_CARRIER_ID);
when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
addNetworkTransportType(NetworkCapabilities.TRANSPORT_WIFI);
assertFalse(SubscriptionUtil.shouldShowRacDialog(mContext));
}
private void addNetworkTransportType(int networkType) {
mNetworkCapabilities =
new NetworkCapabilities.Builder().addTransportType(networkType).build();