diff --git a/res/values/config.xml b/res/values/config.xml index 42bc0d65038..2373b253aaa 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -206,6 +206,9 @@ com.android.settings.intelligence + + false + com.android.packageinstaller diff --git a/res/values/strings.xml b/res/values/strings.xml index f5b19318e04..3a62daa746d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9013,6 +9013,11 @@ Lock device when unpinning + + Confirm SIM deletion + + Verify it\u0027s you before erasing a downloaded SIM + This work profile is managed by: diff --git a/res/xml/security_dashboard_settings.xml b/res/xml/security_dashboard_settings.xml index d417bb26b5d..7610b322e28 100644 --- a/res/xml/security_dashboard_settings.xml +++ b/res/xml/security_dashboard_settings.xml @@ -147,4 +147,11 @@ android:summary="@string/summary_placeholder" android:fragment="com.android.settings.security.ScreenPinningSettings" /> - + + + \ No newline at end of file diff --git a/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java b/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java index daabf8bc0d3..b6a78a1e3e8 100644 --- a/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java +++ b/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java @@ -18,15 +18,18 @@ package com.android.settings.network.telephony; import android.content.Context; import android.content.Intent; +import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.euicc.EuiccManager; import androidx.fragment.app.Fragment; import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; +import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settings.network.SubscriptionUtil; +import com.android.settings.security.ConfirmSimDeletionPreferenceController; +import com.android.settings.wifi.dpp.WifiDppUtils; /** This controls a preference allowing the user to delete the profile for an eSIM. */ public class DeleteSimProfilePreferenceController extends BasePreferenceController { @@ -34,16 +37,19 @@ public class DeleteSimProfilePreferenceController extends BasePreferenceControll private SubscriptionInfo mSubscriptionInfo; private Fragment mParentFragment; private int mRequestCode; + private boolean mConfirmationDefaultOn; public DeleteSimProfilePreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); + mConfirmationDefaultOn = + context.getResources() + .getBoolean(R.bool.config_sim_deletion_confirmation_default_on); } public void init(int subscriptionId, Fragment parentFragment, int requestCode) { mParentFragment = parentFragment; - for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions( - mContext)) { + for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) { if (info.getSubscriptionId() == subscriptionId && info.isEmbedded()) { mSubscriptionInfo = info; break; @@ -53,16 +59,27 @@ public class DeleteSimProfilePreferenceController extends BasePreferenceControll } @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - final Preference pref = screen.findPreference(getPreferenceKey()); - pref.setOnPreferenceClickListener(p -> { - final Intent intent = new Intent(EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED); - intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID, - mSubscriptionInfo.getSubscriptionId()); - mParentFragment.startActivityForResult(intent, mRequestCode); - return true; - }); + public boolean handlePreferenceTreeClick(Preference preference) { + boolean confirmDeletion = + Settings.Global.getInt( + mContext.getContentResolver(), + ConfirmSimDeletionPreferenceController.KEY_CONFIRM_SIM_DELETION, + mConfirmationDefaultOn ? 1 : 0) + == 1; + if (confirmDeletion) { + WifiDppUtils.showLockScreen(mContext, () -> deleteSim()); + } else { + deleteSim(); + } + + return true; + } + + private void deleteSim() { + final Intent intent = new Intent(EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED); + intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID, mSubscriptionInfo.getSubscriptionId()); + mParentFragment.startActivityForResult(intent, mRequestCode); + // result handled in MobileNetworkSettings } @Override @@ -73,5 +90,4 @@ public class DeleteSimProfilePreferenceController extends BasePreferenceControll return CONDITIONALLY_UNAVAILABLE; } } - } diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index 199564dd4d2..e5ba96ab469 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -274,9 +274,11 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment { break; case REQUEST_CODE_DELETE_SUBSCRIPTION: - final Activity activity = getActivity(); - if (activity != null && !activity.isFinishing()) { - activity.finish(); + if (resultCode != Activity.RESULT_CANCELED) { + final Activity activity = getActivity(); + if (activity != null && !activity.isFinishing()) { + activity.finish(); + } } break; diff --git a/src/com/android/settings/security/ConfirmSimDeletionPreferenceController.java b/src/com/android/settings/security/ConfirmSimDeletionPreferenceController.java new file mode 100644 index 00000000000..f24d8db32b5 --- /dev/null +++ b/src/com/android/settings/security/ConfirmSimDeletionPreferenceController.java @@ -0,0 +1,86 @@ +/* + * 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.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; +import androidx.preference.TwoStatePreference; + +import com.android.settings.R; +import com.android.settings.core.TogglePreferenceController; +import com.android.settings.network.telephony.MobileNetworkUtils; + +/** Enable/disable user confirmation before deleting an eSim */ +public class ConfirmSimDeletionPreferenceController extends TogglePreferenceController { + public static final String KEY_CONFIRM_SIM_DELETION = "confirm_sim_deletion"; + private boolean mConfirmationDefaultOn; + + public ConfirmSimDeletionPreferenceController(Context context, String key) { + super(context, key); + mConfirmationDefaultOn = + context.getResources() + .getBoolean(R.bool.config_sim_deletion_confirmation_default_on); + } + + @Override + public int getAvailabilityStatus() { + // hide if eSim is not supported on the device + return MobileNetworkUtils.showEuiccSettings(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + private boolean getGlobalState() { + return Settings.Global.getInt( + mContext.getContentResolver(), + KEY_CONFIRM_SIM_DELETION, + mConfirmationDefaultOn ? 1 : 0) + == 1; + } + + @Override + public boolean isChecked() { + return getGlobalState(); + } + + @Override + public boolean setChecked(boolean isChecked) { + Settings.Global.putInt( + mContext.getContentResolver(), KEY_CONFIRM_SIM_DELETION, isChecked ? 1 : 0); + return true; + } + + @Override + public void updateState(Preference preference) { + + final KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class); + if (!keyguardManager.isKeyguardSecure()) { + 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); + } + } +} diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java index da8f003180b..effbd70dc82 100644 --- a/src/com/android/settings/security/SecuritySettings.java +++ b/src/com/android/settings/security/SecuritySettings.java @@ -20,7 +20,6 @@ import static com.android.settings.security.EncryptionStatusPreferenceController import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; -import android.provider.SearchIndexableResource; import com.android.settings.R; import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController; diff --git a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java index ca8fcf80fc4..401a92e2be4 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.Intent; +import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.euicc.EuiccManager; @@ -34,6 +35,7 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.network.SubscriptionUtil; +import com.android.settings.security.ConfirmSimDeletionPreferenceController; import org.junit.After; import org.junit.Before; @@ -118,7 +120,11 @@ public class DeleteSimProfilePreferenceControllerTest { public void onPreferenceClick_startsIntent() { mController.init(SUB_ID, mFragment, REQUEST_CODE); mController.displayPreference(mScreen); - mPreference.performClick(); + // turn off confirmation before click + Settings.Global.putInt(mContext.getContentResolver(), + ConfirmSimDeletionPreferenceController.KEY_CONFIRM_SIM_DELETION, 0); + + mController.handlePreferenceTreeClick(mPreference); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mFragment).startActivityForResult(intentCaptor.capture(), eq(REQUEST_CODE)); diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java index 9bf8370370a..a4c36725a1d 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Activity; import android.app.usage.NetworkStatsManager; import android.content.Context; import android.net.NetworkPolicyManager; @@ -111,12 +112,12 @@ public class MobileNetworkSettingsTest { public void onActivityResult_noActivity_noCrash() { when(mFragment.getActivity()).thenReturn(null); // this should not crash - mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null); + mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, Activity.RESULT_OK, null); } @Test public void onActivityResult_deleteSubscription_activityFinishes() { - mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null); + mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, Activity.RESULT_OK, null); verify(mActivity).finish(); }