From c3028291edfb4371e94f664c57a1580da0680894 Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Fri, 18 Nov 2022 14:37:13 +0000 Subject: [PATCH] [Settings] Code Refactor Adjust code structure for maintainance. Bug: 259611847 Test: auto test Change-Id: I1fab8d0347f64c01ee768e4bb9ea838a9e7ad4fc --- .../android/settings/ResetNetworkConfirm.java | 104 ++------- .../network/EraseEuiccDataDialogFragment.java | 11 +- .../network/ResetNetworkOperationBuilder.java | 211 ++++++++++++++++++ .../settings/ResetNetworkConfirmTest.java | 47 ---- .../ResetNetworkOperationBuilderTest.java | 132 +++++++++++ 5 files changed, 366 insertions(+), 139 deletions(-) create mode 100644 src/com/android/settings/network/ResetNetworkOperationBuilder.java create mode 100644 tests/unit/src/com/android/settings/network/ResetNetworkOperationBuilderTest.java diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java index 8926d5c1624..52eb6434b2f 100644 --- a/src/com/android/settings/ResetNetworkConfirm.java +++ b/src/com/android/settings/ResetNetworkConfirm.java @@ -19,23 +19,12 @@ package com.android.settings; import android.app.Activity; import android.app.ProgressDialog; import android.app.settings.SettingsEnums; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothManager; -import android.content.ContentResolver; import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkPolicyManager; -import android.net.Uri; -import android.net.VpnManager; -import android.net.wifi.WifiManager; -import android.net.wifi.p2p.WifiP2pManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.Looper; -import android.os.RecoverySystem; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; -import android.telephony.TelephonyManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -48,8 +37,10 @@ import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import com.android.settings.core.InstrumentedFragment; +import com.android.settings.network.ResetNetworkOperationBuilder; import com.android.settings.network.ResetNetworkRestrictionViewBuilder; -import com.android.settings.network.apn.ApnSettings; + +import java.util.concurrent.atomic.AtomicBoolean; /** * Confirm and execute a reset of the network settings to a clean "just out of the box" @@ -90,54 +81,25 @@ public class ResetNetworkConfirm extends InstrumentedFragment { @Override protected Boolean doInBackground(Void... params) { - boolean isResetSucceed = true; - ConnectivityManager connectivityManager = (ConnectivityManager) - mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - if (connectivityManager != null) { - connectivityManager.factoryReset(); - } - - VpnManager vpnManager = mContext.getSystemService(VpnManager.class); - if (vpnManager != null) { - vpnManager.factoryReset(); - } - - WifiManager wifiManager = (WifiManager) - mContext.getSystemService(Context.WIFI_SERVICE); - if (wifiManager != null) { - wifiManager.factoryReset(); - } - - p2pFactoryReset(mContext); - + final AtomicBoolean resetEsimSuccess = new AtomicBoolean(true); + ResetNetworkOperationBuilder builder = + (new ResetNetworkOperationBuilder(mContext)) + .resetConnectivityManager() + .resetVpnManager() + .resetWifiManager() + .resetWifiP2pManager(Looper.getMainLooper()); if (mEraseEsim) { - isResetSucceed = RecoverySystem.wipeEuiccData(mContext, mPackageName); + builder = builder.resetEsim(mContext.getPackageName(), + success -> { resetEsimSuccess.set(success); } + ); } + builder.resetTelephonyAndNetworkPolicyManager(mSubId) + .resetBluetoothManager() + .resetApn(mSubId) + .build() + .run(); - TelephonyManager telephonyManager = (TelephonyManager) - mContext.getSystemService(TelephonyManager.class) - .createForSubscriptionId(mSubId); - if (telephonyManager != null) { - telephonyManager.resetSettings(); - } - - NetworkPolicyManager policyManager = (NetworkPolicyManager) - mContext.getSystemService(Context.NETWORK_POLICY_SERVICE); - if (policyManager != null) { - String subscriberId = telephonyManager.getSubscriberId(); - policyManager.factoryReset(subscriberId); - } - - BluetoothManager btManager = (BluetoothManager) - mContext.getSystemService(Context.BLUETOOTH_SERVICE); - if (btManager != null) { - BluetoothAdapter btAdapter = btManager.getAdapter(); - if (btAdapter != null) { - btAdapter.clearBluetooth(); - } - } - - restoreDefaultApn(mContext); + boolean isResetSucceed = resetEsimSuccess.get(); Log.d(TAG, "network factoryReset complete. succeeded: " + String.valueOf(isResetSucceed)); return isResetSucceed; @@ -201,20 +163,6 @@ public class ResetNetworkConfirm extends InstrumentedFragment { } }; - @VisibleForTesting - void p2pFactoryReset(Context context) { - WifiP2pManager wifiP2pManager = (WifiP2pManager) - context.getSystemService(Context.WIFI_P2P_SERVICE); - if (wifiP2pManager != null) { - WifiP2pManager.Channel channel = wifiP2pManager.initialize( - context.getApplicationContext(), context.getMainLooper(), - null /* listener */); - if (channel != null) { - wifiP2pManager.factoryReset(channel, null /* listener */); - } - } - } - private ProgressDialog getProgressDialog(Context context) { final ProgressDialog progressDialog = new ProgressDialog(context); progressDialog.setIndeterminate(true); @@ -224,20 +172,6 @@ public class ResetNetworkConfirm extends InstrumentedFragment { return progressDialog; } - /** - * Restore APN settings to default. - */ - private void restoreDefaultApn(Context context) { - Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI); - - if (SubscriptionManager.isUsableSubscriptionId(mSubId)) { - uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(mSubId)); - } - - ContentResolver resolver = context.getContentResolver(); - resolver.delete(uri, null, null); - } - /** * Configure the UI for the final confirmation interaction */ diff --git a/src/com/android/settings/network/EraseEuiccDataDialogFragment.java b/src/com/android/settings/network/EraseEuiccDataDialogFragment.java index 2c3847c9f2b..32903bde7ba 100644 --- a/src/com/android/settings/network/EraseEuiccDataDialogFragment.java +++ b/src/com/android/settings/network/EraseEuiccDataDialogFragment.java @@ -89,12 +89,9 @@ public class EraseEuiccDataDialogFragment extends InstrumentedDialogFragment imp } private void runAsyncWipe(Context context) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - RecoverySystem.wipeEuiccData( - context, PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK); - } - }); + Runnable runnable = (new ResetNetworkOperationBuilder(context)) + .resetEsim(PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK) + .build(); + AsyncTask.execute(runnable); } } diff --git a/src/com/android/settings/network/ResetNetworkOperationBuilder.java b/src/com/android/settings/network/ResetNetworkOperationBuilder.java new file mode 100644 index 00000000000..3b5c9bce646 --- /dev/null +++ b/src/com/android/settings/network/ResetNetworkOperationBuilder.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2022 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; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.content.ContentResolver; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkPolicyManager; +import android.net.Uri; +import android.net.VpnManager; +import android.net.wifi.WifiManager; +import android.net.wifi.p2p.WifiP2pManager; +import android.os.Looper; +import android.os.RecoverySystem; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; + +import com.android.settings.network.apn.ApnSettings; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +/** + * A builder for creating a Runnable resetting network configurations. + */ +public class ResetNetworkOperationBuilder { + + private Context mContext; + private List mResetSequence = new ArrayList(); + + /** + * Constructor of builder. + * + * @param context Context + */ + public ResetNetworkOperationBuilder(Context context) { + mContext = context; + } + + /** + * Append a step of resetting ConnectivityManager. + * @return this + */ + public ResetNetworkOperationBuilder resetConnectivityManager() { + attachSystemServiceWork(Context.CONNECTIVITY_SERVICE, + (Consumer) cm -> { + cm.factoryReset(); + }); + return this; + } + + /** + * Append a step of resetting VpnManager. + * @return this + */ + public ResetNetworkOperationBuilder resetVpnManager() { + attachSystemServiceWork(Context.VPN_MANAGEMENT_SERVICE, + (Consumer) vpnManager -> { + vpnManager.factoryReset(); + }); + return this; + } + + /** + * Append a step of resetting WifiManager. + * @return this + */ + public ResetNetworkOperationBuilder resetWifiManager() { + attachSystemServiceWork(Context.WIFI_SERVICE, + (Consumer) wifiManager -> { + wifiManager.factoryReset(); + }); + return this; + } + + /** + * Append a step of resetting WifiP2pManager. + * @param callbackLooper looper to support callback from WifiP2pManager + * @return this + */ + public ResetNetworkOperationBuilder resetWifiP2pManager(Looper callbackLooper) { + attachSystemServiceWork(Context.WIFI_P2P_SERVICE, + (Consumer) wifiP2pManager -> { + WifiP2pManager.Channel channel = wifiP2pManager.initialize( + mContext, callbackLooper, null /* listener */); + if (channel != null) { + wifiP2pManager.factoryReset(channel, null /* listener */); + } + }); + return this; + } + + /** + * Append a step of resetting E-SIM. + * @param callerPackage package name of caller + * @return this + */ + public ResetNetworkOperationBuilder resetEsim(String callerPackage) { + resetEsim(callerPackage, null); + return this; + } + + /** + * Append a step of resetting E-SIM. + * @param callerPackage package name of caller + * @param resultCallback a Consumer dealing with result of resetting eSIM + * @return this + */ + public ResetNetworkOperationBuilder resetEsim(String callerPackage, + Consumer resultCallback) { + Runnable runnable = () -> { + Boolean wipped = RecoverySystem.wipeEuiccData(mContext, callerPackage); + if (resultCallback != null) { + resultCallback.accept(wipped); + } + }; + mResetSequence.add(runnable); + return this; + } + + /** + * Append a step of resetting TelephonyManager and . + * @param subscriptionId of a SIM card + * @return this + */ + public ResetNetworkOperationBuilder resetTelephonyAndNetworkPolicyManager( + int subscriptionId) { + final AtomicReference subscriberId = new AtomicReference(); + attachSystemServiceWork(Context.TELEPHONY_SERVICE, + (Consumer) tm -> { + TelephonyManager subIdTm = tm.createForSubscriptionId(subscriptionId); + subscriberId.set(subIdTm.getSubscriberId()); + subIdTm.resetSettings(); + }); + attachSystemServiceWork(Context.NETWORK_POLICY_SERVICE, + (Consumer) policyManager -> { + policyManager.factoryReset(subscriberId.get()); + }); + return this; + } + + /** + * Append a step of resetting BluetoothAdapter. + * @return this + */ + public ResetNetworkOperationBuilder resetBluetoothManager() { + attachSystemServiceWork(Context.BLUETOOTH_SERVICE, + (Consumer) btManager -> { + BluetoothAdapter btAdapter = btManager.getAdapter(); + if (btAdapter != null) { + btAdapter.clearBluetooth(); + } + }); + return this; + } + + /** + * Append a step of resetting APN configurations. + * @param subscriptionId of a SIM card + * @return this + */ + public ResetNetworkOperationBuilder resetApn(int subscriptionId) { + Runnable runnable = () -> { + Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI); + + if (SubscriptionManager.isUsableSubscriptionId(subscriptionId)) { + uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(subscriptionId)); + } + + ContentResolver resolver = mContext.getContentResolver(); + resolver.delete(uri, null, null); + }; + mResetSequence.add(runnable); + return this; + } + + /** + * Construct a Runnable containing all operations appended. + * @return Runnable + */ + public Runnable build() { + return () -> mResetSequence.forEach(runnable -> runnable.run()); + } + + protected void attachSystemServiceWork(String serviceName, Consumer serviceAccess) { + T service = (T) mContext.getSystemService(serviceName); + if (service == null) { + return; + } + Runnable runnable = () -> serviceAccess.accept(service); + mResetSequence.add(runnable); + } +} diff --git a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java index e4495f42b90..4f870d3226b 100644 --- a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java +++ b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java @@ -25,16 +25,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.net.wifi.p2p.WifiP2pManager; import android.os.Looper; import android.view.LayoutInflater; import android.widget.TextView; import androidx.fragment.app.FragmentActivity; -import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; -import com.android.settings.testutils.shadow.ShadowRecoverySystem; - import org.junit.After; import org.junit.Before; import org.junit.Ignore; @@ -47,65 +43,22 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowRecoverySystem.class, ShadowBluetoothAdapter.class}) public class ResetNetworkConfirmTest { private FragmentActivity mActivity; - @Mock - private WifiP2pManager mWifiP2pManager; @Mock private ResetNetworkConfirm mResetNetworkConfirm; @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mWifiP2pManager.initialize(any(Context.class), any(Looper.class), any())) - .thenReturn(mock(WifiP2pManager.Channel.class)); mResetNetworkConfirm = new ResetNetworkConfirm(); mActivity = spy(Robolectric.setupActivity(FragmentActivity.class)); - when(mActivity.getSystemService(Context.WIFI_P2P_SERVICE)).thenReturn(mWifiP2pManager); mResetNetworkConfirm.mActivity = mActivity; } - @After - public void tearDown() { - ShadowRecoverySystem.reset(); - } - - @Test - @Ignore - public void testResetNetworkData_resetEsim() { - mResetNetworkConfirm.mEraseEsim = true; - - mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */); - Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable(); - - assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(1); - } - - @Test - @Ignore - public void testResetNetworkData_notResetEsim() { - mResetNetworkConfirm.mEraseEsim = false; - - mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */); - Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable(); - - assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(0); - } - - /** - * Test for WifiP2pManager factoryReset method. - */ - @Test - public void testResetNetworkData_resetP2p() { - mResetNetworkConfirm.p2pFactoryReset(mActivity); - - verify(mWifiP2pManager).factoryReset(any(WifiP2pManager.Channel.class), any()); - } - @Test public void setSubtitle_eraseEsim() { mResetNetworkConfirm.mEraseEsim = true; diff --git a/tests/unit/src/com/android/settings/network/ResetNetworkOperationBuilderTest.java b/tests/unit/src/com/android/settings/network/ResetNetworkOperationBuilderTest.java new file mode 100644 index 00000000000..6f5440ba5a7 --- /dev/null +++ b/tests/unit/src/com/android/settings/network/ResetNetworkOperationBuilderTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2022 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; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkPolicyManager; +import android.net.VpnManager; +import android.net.wifi.WifiManager; +import android.net.wifi.p2p.WifiP2pManager; +import android.telephony.TelephonyManager; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidJUnit4.class) +public class ResetNetworkOperationBuilderTest { + + @Mock + private ConnectivityManager mConnectivityManager; + @Mock + private VpnManager mVpnManager; + @Mock + private WifiManager mWifiManager; + @Mock + private WifiP2pManager mWifiP2pManager; + @Mock + private WifiP2pManager.Channel mChannel; + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private NetworkPolicyManager mNetworkPolicyManager; + + private Context mContext; + private ResetNetworkOperationBuilder mBuilder; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(ApplicationProvider.getApplicationContext()); + + mBuilder = spy(new ResetNetworkOperationBuilder(mContext)); + } + + @Test + public void resetConnectivityManager_performReset_whenBuildAndRun() { + doReturn(mConnectivityManager).when(mContext) + .getSystemService(Context.CONNECTIVITY_SERVICE); + + mBuilder.resetConnectivityManager().build().run(); + + verify(mConnectivityManager).factoryReset(); + } + + @Test + public void resetVpnManager_performReset_whenBuildAndRun() { + doReturn(mVpnManager).when(mContext) + .getSystemService(Context.VPN_MANAGEMENT_SERVICE); + + mBuilder.resetVpnManager().build().run(); + + verify(mVpnManager).factoryReset(); + } + + @Test + public void resetWifiManager_performReset_whenBuildAndRun() { + doReturn(mWifiManager).when(mContext) + .getSystemService(Context.WIFI_SERVICE); + + mBuilder.resetWifiManager().build().run(); + + verify(mWifiManager).factoryReset(); + } + + @Test + public void resetWifiP2pManager_performReset_whenBuildAndRun() { + doReturn(mChannel).when(mWifiP2pManager).initialize(mContext, null, null); + doReturn(mWifiP2pManager).when(mContext) + .getSystemService(Context.WIFI_P2P_SERVICE); + + mBuilder.resetWifiP2pManager(null).build().run(); + + verify(mWifiP2pManager).factoryReset(mChannel, null); + } + + @Test + public void resetTelephonyAndNetworkPolicyManager_performReset_whenBuildAndRun() { + int subId = 3; + String imsi = "123456789012345"; + + doReturn(mTelephonyManager).when(mTelephonyManager) + .createForSubscriptionId(anyInt()); + doReturn(mTelephonyManager).when(mContext) + .getSystemService(Context.TELEPHONY_SERVICE); + doReturn(mNetworkPolicyManager).when(mContext) + .getSystemService(Context.NETWORK_POLICY_SERVICE); + + doReturn(imsi).when(mTelephonyManager).getSubscriberId(); + + mBuilder.resetTelephonyAndNetworkPolicyManager(subId).build().run(); + + verify(mTelephonyManager).resetSettings(); + verify(mNetworkPolicyManager).factoryReset(imsi); + } +}