Always confirm eSim removal.

Test: atest DeleteSimProfilePreferenceControllerTest
Bug: 313604661

Change-Id: I0c43790bf43bedcc2e8075aa7be0b25876c731b4
This commit is contained in:
Jan Tomljanovic
2023-12-12 10:58:29 +00:00
parent 4345908c39
commit db1402a4df
8 changed files with 10 additions and 236 deletions

View File

@@ -258,9 +258,6 @@
com.android.settings.intelligence com.android.settings.intelligence
</string> </string>
<!-- Whether the confirmation for sim deletion is defaulted to be on or off-->
<bool name="config_sim_deletion_confirmation_default_on">false</bool>
<!-- Package Installer package name --> <!-- Package Installer package name -->
<string name="config_package_installer_package_name" translatable="false"> <string name="config_package_installer_package_name" translatable="false">
com.android.packageinstaller com.android.packageinstaller

View File

@@ -204,14 +204,6 @@
settings:keywords="@string/keywords_app_pinning" settings:keywords="@string/keywords_app_pinning"
settings:controller="com.android.settings.security.ScreenPinningPreferenceController" /> settings:controller="com.android.settings.security.ScreenPinningPreferenceController" />
<SwitchPreferenceCompat
android:order="290"
android:key="confirm_sim_deletion"
android:title="@string/confirm_sim_deletion_title"
android:summary="@string/confirm_sim_deletion_description"
settings:isPreferenceVisible="@bool/config_show_sim_info"
settings:controller="com.android.settings.security.ConfirmSimDeletionPreferenceController" />
<Preference <Preference
android:order="300" android:order="300"
android:id="@+id/memtag_page" android:id="@+id/memtag_page"

View File

@@ -106,14 +106,6 @@
settings:keywords="@string/keywords_app_pinning" settings:keywords="@string/keywords_app_pinning"
settings:controller="com.android.settings.security.ScreenPinningPreferenceController" /> settings:controller="com.android.settings.security.ScreenPinningPreferenceController" />
<SwitchPreferenceCompat
android:order="290"
android:key="confirm_sim_deletion"
android:title="@string/confirm_sim_deletion_title"
android:summary="@string/confirm_sim_deletion_description"
settings:isPreferenceVisible="@bool/config_show_sim_info"
settings:controller="com.android.settings.security.ConfirmSimDeletionPreferenceController" />
<com.android.settingslib.RestrictedPreference <com.android.settingslib.RestrictedPreference
android:order="300" android:order="300"
android:id="@+id/memtag_page" android:id="@+id/memtag_page"

View File

@@ -32,7 +32,6 @@ import androidx.fragment.app.FragmentManager;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.network.helper.ConfirmationSimDeletionPredicate;
import com.android.settings.system.ResetDashboardFragment; import com.android.settings.system.ResetDashboardFragment;
import com.android.settings.wifi.dpp.WifiDppUtils; import com.android.settings.wifi.dpp.WifiDppUtils;
@@ -76,14 +75,7 @@ public class EraseEuiccDataDialogFragment extends InstrumentedDialogFragment imp
if (which == DialogInterface.BUTTON_POSITIVE) { if (which == DialogInterface.BUTTON_POSITIVE) {
Context context = getContext(); Context context = getContext();
if (ConfirmationSimDeletionPredicate.getSingleton().test(context)) { WifiDppUtils.showLockScreen(context, () -> runAsyncWipe(context));
// Create a "verify it's you" verification over keyguard
// when "erase" button been pressed.
// This might protect from erasing by some automation process.
WifiDppUtils.showLockScreen(context, () -> runAsyncWipe(context));
} else {
runAsyncWipe(context);
}
} }
} }

View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) 2021 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.network.helper;
import android.app.KeyguardManager;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import java.util.function.Predicate;
/**
* {@link Predicate} for detecting the configuration of confirm SIM deletion.
*/
public class ConfirmationSimDeletionPredicate implements Predicate<Context> {
public static final String KEY_CONFIRM_SIM_DELETION = "confirm_sim_deletion";
private static final ConfirmationSimDeletionPredicate sSingleton =
new ConfirmationSimDeletionPredicate();
// Get singleton of this predicate
public static final ConfirmationSimDeletionPredicate getSingleton() {
return sSingleton;
}
/**
* Get default configuration of confirm SIM deletion.
*
* @param Context context
* @return the configuration of confirm SIM deletion
*/
private static boolean getDefaultValue(Context context) {
return context.getResources()
.getBoolean(R.bool.config_sim_deletion_confirmation_default_on);
}
/**
* Get the configuration of confirm SIM deletion.
*
* @param Context context
* @return the configuration of confirm SIM deletion
*/
public boolean test(Context context) {
final KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
if ((keyguardManager != null) && !keyguardManager.isKeyguardSecure()) {
return false;
}
return Settings.Global.getInt(context.getContentResolver(), KEY_CONFIRM_SIM_DELETION,
getDefaultValue(context) ? 1 : 0) == 1;
}
}

View File

@@ -26,10 +26,8 @@ import androidx.preference.PreferenceScreen
import com.android.settings.R import com.android.settings.R
import com.android.settings.core.BasePreferenceController import com.android.settings.core.BasePreferenceController
import com.android.settings.network.SubscriptionUtil import com.android.settings.network.SubscriptionUtil
import com.android.settings.security.ConfirmSimDeletionPreferenceController.KEY_CONFIRM_SIM_DELETION
import com.android.settings.wifi.dpp.WifiDppUtils import com.android.settings.wifi.dpp.WifiDppUtils
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
/** This controls a preference allowing the user to delete the profile for an eSIM. */ /** This controls a preference allowing the user to delete the profile for an eSIM. */
class DeleteSimProfilePreferenceController(context: Context, preferenceKey: String) : class DeleteSimProfilePreferenceController(context: Context, preferenceKey: String) :
@@ -63,16 +61,8 @@ class DeleteSimProfilePreferenceController(context: Context, preferenceKey: Stri
override fun handlePreferenceTreeClick(preference: Preference): Boolean { override fun handlePreferenceTreeClick(preference: Preference): Boolean {
if (preference.key != preferenceKey) return false if (preference.key != preferenceKey) return false
val confirmDeletion by mContext.settingsGlobalBoolean( WifiDppUtils.showLockScreen(mContext) { deleteSim() }
name = KEY_CONFIRM_SIM_DELETION,
defaultValue = mContext.resources
.getBoolean(R.bool.config_sim_deletion_confirmation_default_on),
)
if (confirmDeletion) {
WifiDppUtils.showLockScreen(mContext) { deleteSim() }
} else {
deleteSim()
}
return true return true
} }

View File

@@ -1,123 +0,0 @@
/*
* Copyright (C) 2020 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.security;
import android.app.KeyguardManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.UserManager;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.helper.ConfirmationSimDeletionPredicate;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/** Enable/disable user confirmation before deleting an eSim */
public class ConfirmSimDeletionPreferenceController extends BasePreferenceController implements
Preference.OnPreferenceChangeListener{
public static final String KEY_CONFIRM_SIM_DELETION =
ConfirmationSimDeletionPredicate.KEY_CONFIRM_SIM_DELETION;
private boolean mConfirmationDefaultOn;
private MetricsFeatureProvider mMetricsFeatureProvider;
private UserManager mUserManager;
private KeyguardManager mKeyguardManager;
public ConfirmSimDeletionPreferenceController(Context context, String key) {
super(context, key);
mConfirmationDefaultOn =
context.getResources()
.getBoolean(R.bool.config_sim_deletion_confirmation_default_on);
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
mUserManager = context.getSystemService(UserManager.class);
mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
}
@Override
public int getAvailabilityStatus() {
// hide if eSim is not supported on the device
return (!MobileNetworkUtils.isMobileNetworkUserRestricted(mContext)) &&
MobileNetworkUtils.showEuiccSettings(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
private boolean getGlobalState() {
return Settings.Global.getInt(
mContext.getContentResolver(),
KEY_CONFIRM_SIM_DELETION,
mConfirmationDefaultOn ? 1 : 0)
== 1;
}
public boolean isChecked() {
return getGlobalState();
}
public boolean setChecked(boolean isChecked) {
Settings.Global.putInt(
mContext.getContentResolver(), KEY_CONFIRM_SIM_DELETION, isChecked ? 1 : 0);
return true;
}
// handle UI change
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (!preference.getKey().equals(getPreferenceKey())) {
return false;
}
if (!isChecked()) {
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_CONFIRM_SIM_DELETION_ON);
setChecked(true);
return true;
} else {
// prevent disabling the feature until authorized
WifiDppUtils.showLockScreen(mContext, () -> {
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_CONFIRM_SIM_DELETION_OFF);
// set data
setChecked(false);
// set UI
((TwoStatePreference) preference).setChecked(false);
});
return false;
}
}
@Override
public void updateState(Preference preference) {
if (!mKeyguardManager.isKeyguardSecure() && mUserManager.isGuestUser()) {
preference.setEnabled(false);
if (preference instanceof TwoStatePreference) {
((TwoStatePreference) preference).setChecked(false);
}
preference.setSummary(R.string.disabled_because_no_backup_security);
} else {
preference.setEnabled(true);
if (preference instanceof TwoStatePreference) {
((TwoStatePreference) preference).setChecked(getGlobalState());
}
preference.setSummary(R.string.confirm_sim_deletion_description);
}
}
}

View File

@@ -16,15 +16,15 @@
package com.android.settings.network.telephony package com.android.settings.network.telephony
import android.app.KeyguardManager
import android.content.Context import android.content.Context
import android.os.UserManager
import android.telephony.SubscriptionInfo import android.telephony.SubscriptionInfo
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.network.SubscriptionUtil import com.android.settings.network.SubscriptionUtil
import com.android.settings.security.ConfirmSimDeletionPreferenceController
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@@ -46,8 +46,13 @@ class DeleteSimProfilePreferenceControllerTest {
on { isEmbedded } doReturn true on { isEmbedded } doReturn true
} }
private val mockKeyguardManager = mock<KeyguardManager>() {
on { isKeyguardSecure() } doReturn false
}
private var context: Context = spy(ApplicationProvider.getApplicationContext()) { private var context: Context = spy(ApplicationProvider.getApplicationContext()) {
doNothing().whenever(mock).startActivity(any()) doNothing().whenever(mock).startActivity(any())
on { getSystemService(Context.KEYGUARD_SERVICE) } doReturn mockKeyguardManager
} }
private val preference = Preference(context).apply { key = PREF_KEY } private val preference = Preference(context).apply { key = PREF_KEY }
@@ -103,11 +108,6 @@ class DeleteSimProfilePreferenceControllerTest {
fun onPreferenceClick_startsIntent() { fun onPreferenceClick_startsIntent() {
controller.init(SUB_ID) controller.init(SUB_ID)
controller.displayPreference(preferenceScreen) controller.displayPreference(preferenceScreen)
// turn off confirmation before click
var confirmDeletion by context.settingsGlobalBoolean(
name = ConfirmSimDeletionPreferenceController.KEY_CONFIRM_SIM_DELETION,
)
confirmDeletion = false
controller.handlePreferenceTreeClick(preference) controller.handlePreferenceTreeClick(preference)