diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f4ff282238c..fc3888b8df7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -102,8 +102,6 @@ - - { - final DeleteSimProfileConfirmationDialog dialogFragment = - DeleteSimProfileConfirmationDialog.newInstance(mSubscriptionInfo); - dialogFragment.setTargetFragment(mParentFragment, 0); - dialogFragment.show(mParentFragment.getFragmentManager(), - DeleteSimProfileConfirmationDialog.TAG); + final Intent intent = new Intent(EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED); + intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID, + mSubscriptionInfo.getSubscriptionId()); + mParentFragment.startActivityForResult(intent, mRequestCode); return true; }); } diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java deleted file mode 100644 index c176f3cc911..00000000000 --- a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2019 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.telephony; - -import android.app.Activity; -import android.app.Dialog; -import android.app.PendingIntent; -import android.app.ProgressDialog; -import android.app.settings.SettingsEnums; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.telephony.euicc.EuiccManager; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import com.android.settings.R; -import com.android.settings.core.instrumentation.InstrumentedDialogFragment; - -public class DeleteSimProfileProgressDialog extends InstrumentedDialogFragment { - public static final String TAG = "delete_sim_progress"; - - // Note that this must be listed in AndroidManfiest.xml in a tag - @VisibleForTesting - static final String PENDING_INTENT = - "com.android.settings.DELETE_SIM_PROFILE_RESULT"; - private static final int PENDING_INTENT_REQUEST_CODE = 1; - private static final String KEY_SUBSCRIPTION_ID = "subscription_id"; - @VisibleForTesting - static final String KEY_DELETE_STARTED = "delete_started"; - - private boolean mDeleteStarted; - private BroadcastReceiver mReceiver; - - public static DeleteSimProfileProgressDialog newInstance(int subscriptionId) { - final DeleteSimProfileProgressDialog dialog = new DeleteSimProfileProgressDialog(); - final Bundle args = new Bundle(); - args.putInt(KEY_SUBSCRIPTION_ID, subscriptionId); - dialog.setArguments(args); - return dialog; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(KEY_DELETE_STARTED, mDeleteStarted); - } - - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - if (savedInstanceState != null) { - mDeleteStarted = savedInstanceState.getBoolean(KEY_DELETE_STARTED, false); - } - final Context context = getContext(); - final ProgressDialog progressDialog = new ProgressDialog(context); - progressDialog.setMessage( - context.getString(R.string.mobile_network_erase_sim_dialog_progress)); - - mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - dismiss(); - final Activity activity = getActivity(); - if (activity != null && !activity.isFinishing()) { - activity.finish(); - } - } - }; - context.registerReceiver(mReceiver, new IntentFilter(PENDING_INTENT)); - - if (!mDeleteStarted) { - final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, - PENDING_INTENT_REQUEST_CODE, new Intent(PENDING_INTENT), - PendingIntent.FLAG_ONE_SHOT); - - final EuiccManager euiccManager = context.getSystemService(EuiccManager.class); - final int subId = getArguments().getInt(KEY_SUBSCRIPTION_ID); - euiccManager.deleteSubscription(subId, pendingIntent); - mDeleteStarted = true; - } - - return progressDialog; - } - - @Override - public void onDismiss(@NonNull DialogInterface dialog) { - if (mReceiver != null) { - final Context context = getContext(); - if (context != null) { - context.unregisterReceiver(mReceiver); - } - mReceiver = null; - } - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.DIALOG_DELETE_SIM_PROGRESS; - } -} diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index e18971d43d6..f8e5c3a518f 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -61,6 +61,7 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment { private static final String LOG_TAG = "NetworkSettings"; public static final int REQUEST_CODE_EXIT_ECM = 17; + public static final int REQUEST_CODE_DELETE_SUBSCRIPTION = 18; @VisibleForTesting static final String KEY_CLICKED_PREF = "key_clicked_pref"; @@ -138,7 +139,8 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment { use(BillingCyclePreferenceController.class).init(mSubId); use(MmsMessagePreferenceController.class).init(mSubId); use(DisabledSubscriptionController.class).init(getLifecycle(), mSubId); - use(DeleteSimProfilePreferenceController.class).init(mSubId, this); + use(DeleteSimProfilePreferenceController.class).init(mSubId, this, + REQUEST_CODE_DELETE_SUBSCRIPTION); } use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId); use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId); @@ -226,6 +228,13 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment { } break; + case REQUEST_CODE_DELETE_SUBSCRIPTION: + final Activity activity = getActivity(); + if (activity != null && !activity.isFinishing()) { + activity.finish(); + } + break; + default: break; } diff --git a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialogTest.java b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialogTest.java deleted file mode 100644 index 9b6f5511e0d..00000000000 --- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialogTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2019 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.telephony; - -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.telephony.SubscriptionInfo; - -import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.FragmentActivity; - -import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.androidx.fragment.FragmentController; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = ShadowAlertDialogCompat.class) -public class DeleteSimProfileConfirmationDialogTest { - @Mock - private SubscriptionInfo mSubscriptionInfo; - - private DeleteSimProfileConfirmationDialog mDialogFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mDialogFragment = spy(DeleteSimProfileConfirmationDialog.newInstance(mSubscriptionInfo)); - doNothing().when(mDialogFragment).beginDeletionWithProgress(); - } - - @Test - public void showDialog_dialogCancelled_deleteNotCalled() { - FragmentController.setupFragment(mDialogFragment, FragmentActivity.class, - 0 /* containerViewId */, - null /* bundle */); - final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); - dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick(); - verify(mDialogFragment, never()).beginDeletionWithProgress(); - } - - @Test - public void showDialog_dialogOk_deleteWasCalled() { - FragmentController.setupFragment(mDialogFragment, FragmentActivity.class, - 0 /* containerViewId */, - null /* bundle */); - final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); - dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); - verify(mDialogFragment).beginDeletionWithProgress(); - } -} 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 21fd19bf50b..ca8fcf80fc4 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java @@ -18,11 +18,15 @@ package com.android.settings.network.telephony; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.Intent; import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; import android.telephony.euicc.EuiccManager; import androidx.fragment.app.Fragment; @@ -35,6 +39,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; @@ -46,12 +51,12 @@ import java.util.Arrays; @RunWith(RobolectricTestRunner.class) public class DeleteSimProfilePreferenceControllerTest { private static final String PREF_KEY = "delete_profile_key"; + private static final int REQUEST_CODE = 4321; private static final int SUB_ID = 1234; private static final int OTHER_ID = 5678; @Mock private Fragment mFragment; - @Mock private SubscriptionInfo mSubscriptionInfo; @Mock @@ -85,27 +90,42 @@ public class DeleteSimProfilePreferenceControllerTest { @Test public void getAvailabilityStatus_noSubs_notAvailable() { SubscriptionUtil.setAvailableSubscriptionsForTesting(new ArrayList<>()); - mController.init(SUB_ID, mFragment); + mController.init(SUB_ID, mFragment, REQUEST_CODE); assertThat(mController.isAvailable()).isFalse(); } @Test public void getAvailabilityStatus_physicalSim_notAvailable() { when(mSubscriptionInfo.isEmbedded()).thenReturn(false); - mController.init(SUB_ID, mFragment); + mController.init(SUB_ID, mFragment, REQUEST_CODE); assertThat(mController.isAvailable()).isFalse(); } @Test public void getAvailabilityStatus_unknownSim_notAvailable() { when(mSubscriptionInfo.getSubscriptionId()).thenReturn(OTHER_ID); - mController.init(SUB_ID, mFragment); + mController.init(SUB_ID, mFragment, REQUEST_CODE); assertThat(mController.isAvailable()).isFalse(); } @Test public void getAvailabilityStatus_knownEsim_isAvailable() { - mController.init(SUB_ID, mFragment); + mController.init(SUB_ID, mFragment, REQUEST_CODE); assertThat(mController.isAvailable()).isTrue(); } + + @Test + public void onPreferenceClick_startsIntent() { + mController.init(SUB_ID, mFragment, REQUEST_CODE); + mController.displayPreference(mScreen); + mPreference.performClick(); + + final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mFragment).startActivityForResult(intentCaptor.capture(), eq(REQUEST_CODE)); + final Intent intent = intentCaptor.getValue(); + assertThat(intent.getAction()).isEqualTo( + EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED); + assertThat(intent.getIntExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID, + SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(SUB_ID); + } } diff --git a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialogTest.java b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialogTest.java deleted file mode 100644 index aebcc461ea2..00000000000 --- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialogTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2019 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.telephony; - -import static com.android.settings.network.telephony.DeleteSimProfileProgressDialog.KEY_DELETE_STARTED; -import static com.android.settings.network.telephony.DeleteSimProfileProgressDialog.PENDING_INTENT; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.notNull; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Dialog; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.telephony.euicc.EuiccManager; - -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; - -import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = ShadowAlertDialogCompat.class) -public class DeleteSimProfileProgressDialogTest { - private static final int SUB_ID = 111; - - @Mock - private FragmentActivity mActivity; - @Mock - private Fragment mTargetFragment; - @Mock - private EuiccManager mEuiccManager; - - private Context mContext; - private DeleteSimProfileProgressDialog mDialogFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - - when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager); - mDialogFragment = spy(DeleteSimProfileProgressDialog.newInstance(SUB_ID)); - when(mDialogFragment.getContext()).thenReturn(mContext); - when(mDialogFragment.getTargetFragment()).thenReturn(mTargetFragment); - when(mDialogFragment.getActivity()).thenReturn(mActivity); - } - - @Test - public void onCreateDialog_firstShowing_deleteStartedAndRecordedInOutState() { - mDialogFragment.onCreateDialog(null); - verify(mEuiccManager).deleteSubscription(eq(SUB_ID), notNull()); - - final Bundle outState = new Bundle(); - mDialogFragment.onSaveInstanceState(outState); - assertThat(outState.containsKey(KEY_DELETE_STARTED)).isTrue(); - assertThat(outState.getBoolean(KEY_DELETE_STARTED)).isTrue(); - } - - @Test - public void showDialog_secondShowing_deleteNotStarted() { - final Bundle inState = new Bundle(); - inState.putBoolean(KEY_DELETE_STARTED, true); - mDialogFragment.onCreateDialog(inState); - - verify(mEuiccManager, never()).deleteSubscription(anyInt(), any()); - - final Bundle outState = new Bundle(); - mDialogFragment.onSaveInstanceState(outState); - assertThat(outState.containsKey(KEY_DELETE_STARTED)).isTrue(); - assertThat(outState.getBoolean(KEY_DELETE_STARTED)).isTrue(); - } - - @Test - public void showDialog_pendingIntentReceiverFired_activityFinished() { - mDialogFragment.onCreateDialog(null); - - final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass( - PendingIntent.class); - verify(mEuiccManager).deleteSubscription(eq(SUB_ID), intentCaptor.capture()); - assertThat(intentCaptor.getValue()).isNotNull(); - - final ArgumentCaptor receiverCaptor = ArgumentCaptor.forClass( - BroadcastReceiver.class); - verify(mContext).registerReceiver(receiverCaptor.capture(), any(IntentFilter.class)); - - doNothing().when(mDialogFragment).dismiss(); - receiverCaptor.getValue().onReceive(mContext, new Intent(PENDING_INTENT)); - verify(mDialogFragment).dismiss(); - verify(mActivity).finish(); - } - - @Test - public void onDismiss_receiverUnregistered() { - Dialog dialog = mDialogFragment.onCreateDialog(null); - final ArgumentCaptor receiverCaptor = ArgumentCaptor.forClass( - BroadcastReceiver.class); - verify(mContext).registerReceiver(receiverCaptor.capture(), any(IntentFilter.class)); - - mDialogFragment.onDismiss(dialog); - verify(mContext).unregisterReceiver(eq(receiverCaptor.getValue())); - } -} 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 011bca5733e..a999a9ee1cf 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java @@ -16,11 +16,14 @@ package com.android.settings.network.telephony; +import static com.android.settings.network.telephony.MobileNetworkSettings.REQUEST_CODE_DELETE_SUBSCRIPTION; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.usage.NetworkStatsManager; @@ -80,6 +83,7 @@ public class MobileNetworkSettingsTest { args.putInt(Settings.EXTRA_SUB_ID, subscriptionId); mFragment.setArguments(args); when(mFragment.getActivity()).thenReturn(mActivity); + when(mActivity.isFinishing()).thenReturn(false); when(mActivity.getSystemService(NetworkPolicyManager.class)).thenReturn( mNetworkPolicyManager); } @@ -118,4 +122,17 @@ public class MobileNetworkSettingsTest { .count()) .isEqualTo(1); } + + @Test + public void onActivityResult_noActivity_noCrash() { + when(mFragment.getActivity()).thenReturn(null); + // this should not crash + mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null); + } + + @Test + public void onActivityResult_deleteSubscription_activityFinishes() { + mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null); + verify(mActivity).finish(); + } }