Switch to using an intent for eSIM erasing
We initially landed support for erasing an eSIM subscription in ag/7208624 for b/124254555 using our own confirmation/progress UI, and calling the EuiccManager.deleteSubscription method to do the deletion. It turns out this is a low-level API which doesn't handle some important cases such as subscription grouping or the eSIM slot not being active. This CL changes Settings to just launch an intent to begin an eSIM Manager flow to delete a subscription that provides its own confirmation/progress UI, and should properly handle subscription grouping and making the eSIM slot active as needed. Bug: 132114333 Test: make RunSettingsRoboTests Change-Id: Ie59fea37fa73c5e6573e1181e271ffb5d453bd08
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
@@ -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<Intent> 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);
|
||||
}
|
||||
}
|
||||
|
@@ -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<PendingIntent> intentCaptor = ArgumentCaptor.forClass(
|
||||
PendingIntent.class);
|
||||
verify(mEuiccManager).deleteSubscription(eq(SUB_ID), intentCaptor.capture());
|
||||
assertThat(intentCaptor.getValue()).isNotNull();
|
||||
|
||||
final ArgumentCaptor<BroadcastReceiver> 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<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
|
||||
BroadcastReceiver.class);
|
||||
verify(mContext).registerReceiver(receiverCaptor.capture(), any(IntentFilter.class));
|
||||
|
||||
mDialogFragment.onDismiss(dialog);
|
||||
verify(mContext).unregisterReceiver(eq(receiverCaptor.getValue()));
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user