Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3aeb9153 authored by Raff Tsai's avatar Raff Tsai
Browse files

ANR observed under settings when trying to reset network settings

- Move reset network settings code to async task.

Test: manual, Robolectric
Fixes: 130772994
Change-Id: I59345f48ed840ecfd64c29c2c20ab8caf2679f63
parent d68c8c59
Loading
Loading
Loading
Loading
+77 −67
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.settings;

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.app.Activity;
import android.app.ProgressDialog;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
@@ -33,7 +35,6 @@ import android.os.Bundle;
import android.os.RecoverySystem;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Telephony;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater;
@@ -66,87 +67,56 @@ import com.android.settingslib.RestrictedLockUtilsInternal;
public class ResetNetworkConfirm extends InstrumentedFragment {

    @VisibleForTesting View mContentView;
    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    @VisibleForTesting boolean mEraseEsim;
    @VisibleForTesting EraseEsimAsyncTask mEraseEsimTask;
    @VisibleForTesting ResetNetworkTask mResetNetworkTask;
    @VisibleForTesting Activity mActivity;
    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private ProgressDialog mProgressDialog;

    /**
     * Async task used to erase all the eSIM profiles from the phone. If error happens during
     * Async task used to do all reset task. If error happens during
     * erasing eSIM profiles or timeout, an error msg is shown.
     */
    private static class EraseEsimAsyncTask extends AsyncTask<Void, Void, Boolean> {
    private class ResetNetworkTask extends AsyncTask<Void, Void, Boolean> {
        private final Context mContext;
        private final String mPackageName;

        EraseEsimAsyncTask(Context context, String packageName) {
        ResetNetworkTask(Context context) {
            mContext = context;
            mPackageName = packageName;
            mPackageName = context.getPackageName();
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            return RecoverySystem.wipeEuiccData(mContext, mPackageName);
        }

        @Override
        protected void onPostExecute(Boolean succeeded) {
            if (succeeded) {
                Toast.makeText(mContext, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
                        .show();
            } else {
                new AlertDialog.Builder(mContext)
                        .setTitle(R.string.reset_esim_error_title)
                        .setMessage(R.string.reset_esim_error_msg)
                        .setPositiveButton(android.R.string.ok, null /* listener */)
                        .show();
            }
        }
    }

    /**
     * The user has gone through the multiple confirmation, so now we go ahead
     * and reset the network settings to its factory-default state.
     */
    private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (Utils.isMonkeyRunning()) {
                return;
            }
            // TODO maybe show a progress screen if this ends up taking a while and won't let user
            // go back until the tasks finished.
            Context context = getActivity();

            ConnectivityManager connectivityManager = (ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);
                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connectivityManager != null) {
                connectivityManager.factoryReset();
            }

            WifiManager wifiManager = (WifiManager)
                    context.getSystemService(Context.WIFI_SERVICE);
                    mContext.getSystemService(Context.WIFI_SERVICE);
            if (wifiManager != null) {
                wifiManager.factoryReset();
            }

            p2pFactoryReset(context);
            p2pFactoryReset(mContext);

            TelephonyManager telephonyManager = (TelephonyManager)
                    context.getSystemService(Context.TELEPHONY_SERVICE);
                    mContext.getSystemService(Context.TELEPHONY_SERVICE);
            if (telephonyManager != null) {
                telephonyManager.factoryReset(mSubId);
            }

            NetworkPolicyManager policyManager = (NetworkPolicyManager)
                    context.getSystemService(Context.NETWORK_POLICY_SERVICE);
                    mContext.getSystemService(Context.NETWORK_POLICY_SERVICE);
            if (policyManager != null) {
                String subscriberId = telephonyManager.getSubscriberId(mSubId);
                policyManager.factoryReset(subscriberId);
            }

            BluetoothManager btManager = (BluetoothManager)
                    context.getSystemService(Context.BLUETOOTH_SERVICE);
                    mContext.getSystemService(Context.BLUETOOTH_SERVICE);
            if (btManager != null) {
                BluetoothAdapter btAdapter = btManager.getAdapter();
                if (btAdapter != null) {
@@ -154,23 +124,52 @@ public class ResetNetworkConfirm extends InstrumentedFragment {
                }
            }

            ImsManager.getInstance(context,
            ImsManager.getInstance(mContext,
                    SubscriptionManager.getPhoneId(mSubId)).factoryReset();
            restoreDefaultApn(context);
            esimFactoryReset(context, context.getPackageName());
            restoreDefaultApn(mContext);
            if (mEraseEsim) {
                return RecoverySystem.wipeEuiccData(mContext, mPackageName);
            } else {
                return true;
            }
        }
    };

    @VisibleForTesting
    void esimFactoryReset(Context context, String packageName) {
        if (mEraseEsim) {
            mEraseEsimTask = new EraseEsimAsyncTask(context, packageName);
            mEraseEsimTask.execute();
        @Override
        protected void onPostExecute(Boolean succeeded) {
            mProgressDialog.dismiss();
            if (succeeded) {
                Toast.makeText(mContext, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
                        .show();
            } else {
            Toast.makeText(context, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
                new AlertDialog.Builder(mContext)
                        .setTitle(R.string.reset_esim_error_title)
                        .setMessage(R.string.reset_esim_error_msg)
                        .setPositiveButton(android.R.string.ok, null /* listener */)
                        .show();
            }
        }
    }

    /**
     * The user has gone through the multiple confirmation, so now we go ahead
     * and reset the network settings to its factory-default state.
     */
    @VisibleForTesting
    Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (Utils.isMonkeyRunning()) {
                return;
            }

            mProgressDialog = getProgressDialog(mActivity);
            mProgressDialog.show();

            mResetNetworkTask = new ResetNetworkTask(mActivity);
            mResetNetworkTask.execute();
        }
    };

    @VisibleForTesting
    void p2pFactoryReset(Context context) {
@@ -186,6 +185,15 @@ public class ResetNetworkConfirm extends InstrumentedFragment {
        }
    }

    private ProgressDialog getProgressDialog(Context context) {
        final ProgressDialog progressDialog = new ProgressDialog(context);
        progressDialog.setIndeterminate(true);
        progressDialog.setCancelable(false);
        progressDialog.setMessage(
                context.getString(R.string.master_clear_progress_text));
        return progressDialog;
    }

    /**
     * Restore APN settings to default.
     */
@@ -220,16 +228,16 @@ public class ResetNetworkConfirm extends InstrumentedFragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
                getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
        if (RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
                mActivity, UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
        if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mActivity,
                UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
            return inflater.inflate(R.layout.network_reset_disallowed_screen, null);
        } else if (admin != null) {
            new ActionDisabledByAdminDialogHelper(getActivity())
            new ActionDisabledByAdminDialogHelper(mActivity)
                    .prepareDialogBuilder(UserManager.DISALLOW_NETWORK_RESET, admin)
                    .setOnDismissListener(__ -> getActivity().finish())
                    .setOnDismissListener(__ -> mActivity.finish())
                    .show();
            return new View(getContext());
            return new View(mActivity);
        }
        mContentView = inflater.inflate(R.layout.reset_network_confirm, null);
        establishFinalConfirmationState();
@@ -247,13 +255,15 @@ public class ResetNetworkConfirm extends InstrumentedFragment {
                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
            mEraseEsim = args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA);
        }

        mActivity = getActivity();
    }

    @Override
    public void onDestroy() {
        if (mEraseEsimTask != null) {
            mEraseEsimTask.cancel(true /* mayInterruptIfRunning */);
            mEraseEsimTask = null;
        if (mResetNetworkTask != null) {
            mResetNetworkTask.cancel(true /* mayInterruptIfRunning */);
            mResetNetworkTask = null;
        }
        super.onDestroy();
    }
+19 −17
Original line number Diff line number Diff line
@@ -18,12 +18,12 @@ package com.android.settings;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.spy;

import android.app.Activity;
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 com.android.settings.testutils.shadow.ShadowWifiP2pManager;

@@ -38,18 +38,21 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowRecoverySystem.class, ShadowWifiP2pManager.class})
@Config(shadows = {ShadowRecoverySystem.class,
        ShadowWifiP2pManager.class, ShadowBluetoothAdapter.class
})
public class ResetNetworkConfirmTest {

    private Activity mActivity;
    private FragmentActivity mActivity;
    @Mock
    private ResetNetworkConfirm mResetNetworkConfirm;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mResetNetworkConfirm = spy(new ResetNetworkConfirm());
        mActivity = Robolectric.setupActivity(Activity.class);
        mResetNetworkConfirm = new ResetNetworkConfirm();
        mActivity = Robolectric.setupActivity(FragmentActivity.class);
        mResetNetworkConfirm.mActivity = mActivity;
    }

    @After
@@ -62,10 +65,9 @@ public class ResetNetworkConfirmTest {
    public void testResetNetworkData_resetEsim() {
        mResetNetworkConfirm.mEraseEsim = true;

        mResetNetworkConfirm.esimFactoryReset(mActivity, "" /* packageName */);
        mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */);
        Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable();

        assertThat(mResetNetworkConfirm.mEraseEsimTask).isNotNull();
        assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(1);
    }

@@ -73,9 +75,9 @@ public class ResetNetworkConfirmTest {
    public void testResetNetworkData_notResetEsim() {
        mResetNetworkConfirm.mEraseEsim = false;

        mResetNetworkConfirm.esimFactoryReset(mActivity, "" /* packageName */);
        mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */);
        Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable();

        assertThat(mResetNetworkConfirm.mEraseEsimTask).isNull();
        assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(0);
    }

+5 −0
Original line number Diff line number Diff line
@@ -51,4 +51,9 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto
    public void setConnectionState(int state) {
        mState = state;
    }

    @Implementation
    protected boolean factoryReset() {
        return true;
    }
}