Merge "[Settings] Code Refactor"

This commit is contained in:
Bonian Chen
2022-11-21 09:32:30 +00:00
committed by Gerrit Code Review
5 changed files with 366 additions and 139 deletions

View File

@@ -19,23 +19,12 @@ package com.android.settings;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.ContentResolver;
import android.content.Context; 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.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Looper; import android.os.Looper;
import android.os.RecoverySystem;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -48,8 +37,10 @@ import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
import com.android.settings.network.ResetNetworkOperationBuilder;
import com.android.settings.network.ResetNetworkRestrictionViewBuilder; 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" * 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 @Override
protected Boolean doInBackground(Void... params) { protected Boolean doInBackground(Void... params) {
boolean isResetSucceed = true; final AtomicBoolean resetEsimSuccess = new AtomicBoolean(true);
ConnectivityManager connectivityManager = (ConnectivityManager) ResetNetworkOperationBuilder builder =
mContext.getSystemService(Context.CONNECTIVITY_SERVICE); (new ResetNetworkOperationBuilder(mContext))
if (connectivityManager != null) { .resetConnectivityManager()
connectivityManager.factoryReset(); .resetVpnManager()
} .resetWifiManager()
.resetWifiP2pManager(Looper.getMainLooper());
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);
if (mEraseEsim) { 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) boolean isResetSucceed = resetEsimSuccess.get();
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);
Log.d(TAG, "network factoryReset complete. succeeded: " Log.d(TAG, "network factoryReset complete. succeeded: "
+ String.valueOf(isResetSucceed)); + String.valueOf(isResetSucceed));
return 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) { private ProgressDialog getProgressDialog(Context context) {
final ProgressDialog progressDialog = new ProgressDialog(context); final ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setIndeterminate(true); progressDialog.setIndeterminate(true);
@@ -224,20 +172,6 @@ public class ResetNetworkConfirm extends InstrumentedFragment {
return progressDialog; 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 * Configure the UI for the final confirmation interaction
*/ */

View File

@@ -89,12 +89,9 @@ public class EraseEuiccDataDialogFragment extends InstrumentedDialogFragment imp
} }
private void runAsyncWipe(Context context) { private void runAsyncWipe(Context context) {
AsyncTask.execute(new Runnable() { Runnable runnable = (new ResetNetworkOperationBuilder(context))
@Override .resetEsim(PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK)
public void run() { .build();
RecoverySystem.wipeEuiccData( AsyncTask.execute(runnable);
context, PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK);
}
});
} }
} }

View File

@@ -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<Runnable> mResetSequence = new ArrayList<Runnable>();
/**
* 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<ConnectivityManager>) cm -> {
cm.factoryReset();
});
return this;
}
/**
* Append a step of resetting VpnManager.
* @return this
*/
public ResetNetworkOperationBuilder resetVpnManager() {
attachSystemServiceWork(Context.VPN_MANAGEMENT_SERVICE,
(Consumer<VpnManager>) vpnManager -> {
vpnManager.factoryReset();
});
return this;
}
/**
* Append a step of resetting WifiManager.
* @return this
*/
public ResetNetworkOperationBuilder resetWifiManager() {
attachSystemServiceWork(Context.WIFI_SERVICE,
(Consumer<WifiManager>) 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 -> {
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<Boolean> dealing with result of resetting eSIM
* @return this
*/
public ResetNetworkOperationBuilder resetEsim(String callerPackage,
Consumer<Boolean> 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<String> subscriberId = new AtomicReference<String>();
attachSystemServiceWork(Context.TELEPHONY_SERVICE,
(Consumer<TelephonyManager>) tm -> {
TelephonyManager subIdTm = tm.createForSubscriptionId(subscriptionId);
subscriberId.set(subIdTm.getSubscriberId());
subIdTm.resetSettings();
});
attachSystemServiceWork(Context.NETWORK_POLICY_SERVICE,
(Consumer<NetworkPolicyManager>) policyManager -> {
policyManager.factoryReset(subscriberId.get());
});
return this;
}
/**
* Append a step of resetting BluetoothAdapter.
* @return this
*/
public ResetNetworkOperationBuilder resetBluetoothManager() {
attachSystemServiceWork(Context.BLUETOOTH_SERVICE,
(Consumer<BluetoothManager>) 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 <T> void attachSystemServiceWork(String serviceName, Consumer<T> serviceAccess) {
T service = (T) mContext.getSystemService(serviceName);
if (service == null) {
return;
}
Runnable runnable = () -> serviceAccess.accept(service);
mResetSequence.add(runnable);
}
}

View File

@@ -25,16 +25,12 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Looper; import android.os.Looper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.widget.TextView; import android.widget.TextView;
import androidx.fragment.app.FragmentActivity; 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.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
@@ -47,65 +43,22 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowRecoverySystem.class, ShadowBluetoothAdapter.class})
public class ResetNetworkConfirmTest { public class ResetNetworkConfirmTest {
private FragmentActivity mActivity; private FragmentActivity mActivity;
@Mock
private WifiP2pManager mWifiP2pManager;
@Mock @Mock
private ResetNetworkConfirm mResetNetworkConfirm; private ResetNetworkConfirm mResetNetworkConfirm;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mWifiP2pManager.initialize(any(Context.class), any(Looper.class), any()))
.thenReturn(mock(WifiP2pManager.Channel.class));
mResetNetworkConfirm = new ResetNetworkConfirm(); mResetNetworkConfirm = new ResetNetworkConfirm();
mActivity = spy(Robolectric.setupActivity(FragmentActivity.class)); mActivity = spy(Robolectric.setupActivity(FragmentActivity.class));
when(mActivity.getSystemService(Context.WIFI_P2P_SERVICE)).thenReturn(mWifiP2pManager);
mResetNetworkConfirm.mActivity = mActivity; 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 @Test
public void setSubtitle_eraseEsim() { public void setSubtitle_eraseEsim() {
mResetNetworkConfirm.mEraseEsim = true; mResetNetworkConfirm.mEraseEsim = true;

View File

@@ -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);
}
}