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

Commit 0a3438c1 authored by Bonian Chen's avatar Bonian Chen Committed by Android (Google) Code Review
Browse files

Merge "[Settings] Add BT and WiFi reset option"

parents 7786ca83 dc6877f2
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -2697,6 +2697,16 @@
    <!-- SD card & phone storage settings screen, message on screen after user selects Reset network settings [CHAR LIMIT=NONE] -->
    <string name="reset_network_desc">This will reset all network settings, including:\n\n<li>Wi\u2011Fi</li>\n<li>Mobile data</li>\n<li>Bluetooth</li>"</string>
    <!-- Reset Bluetooth and Wi-Fi Network -->
    <!-- Dialog title to reset Bluetooth and Wi-Fi settings -->
    <string name="reset_bluetooth_wifi_title">Reset Bluetooth &amp; Wi\u2011Fi</string>
    <!-- Dialog context when reset Bluetooth and Wi-Fi settings [CHAR LIMIT=NONE] -->
    <string name="reset_bluetooth_wifi_desc">This will reset all Wi\u2011Fi &amp; Bluetooth settings. You can\u2019t undo this action.</string>
    <!-- Confirmation button text when reset Bluetooth and Wi-Fi settings [CHAR LIMIT=NONE] -->
    <string name="reset_bluetooth_wifi_button_text">Reset</string>
    <!-- Reset Bluetooth and Wi-Fi complete toast text [CHAR LIMIT=75] -->
    <string name="reset_bluetooth_wifi_complete_toast">Bluetooth &amp; Wi\u2011Fi have been reset</string>
    <!-- Erase Euicc -->
    <!-- Confirmation button of dialog to confirm resetting user's app preferences [CHAR LIMIT=NONE] -->
    <string name="erase_euicc_data_button">Erase</string>
+8 −0
Original line number Diff line number Diff line
@@ -28,6 +28,14 @@
        settings:useAdminDisabledSummary="true"
        android:fragment="com.android.settings.ResetNetwork" />

    <!-- Bluetooth and WiFi reset -->
    <com.android.settingslib.RestrictedPreference
        android:key="network_reset_bluetooth_wifi_pref"
        android:title="@string/reset_bluetooth_wifi_title"
        settings:userRestriction="no_network_reset"
        settings:useAdminDisabledSummary="true"
        settings:controller="com.android.settings.network.BluetoothWiFiResetPreferenceController" />

    <!-- Reset app preferences -->
    <Preference
        android:key="reset_app_prefs"
+173 −0
Original line number Diff line number Diff line
/*
 * 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.app.ProgressDialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;

import com.android.settings.R;
import com.android.settings.ResetNetworkRequest;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

/**
 * This is to show a preference regarding resetting Bluetooth and Wi-Fi.
 */
public class BluetoothWiFiResetPreferenceController extends BasePreferenceController
        implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {

    private static final String TAG = "BtWiFiResetPreferenceController";

    private final NetworkResetRestrictionChecker mRestrictionChecker;

    private DialogInterface mResetDialog;
    private ProgressDialog mProgressDialog;
    private ExecutorService mExecutorService;

    /**
     * Constructer.
     * @param context Context
     * @param preferenceKey is the key for Preference
     */
    public BluetoothWiFiResetPreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey);

        // restriction check
        mRestrictionChecker = new NetworkResetRestrictionChecker(context);
    }

    @Override
    public int getAvailabilityStatus() {
        return mRestrictionChecker.hasUserRestriction() ?
                CONDITIONALLY_UNAVAILABLE : AVAILABLE;
    }

    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
            return false;
        }
        buildResetDialog(preference);
        return true;
    }

    /**
     * This is a pop-up dialog showing detail of this reset option.
     */
    void buildResetDialog(Preference preference) {
        if (mResetDialog != null) {
            return;
        }
        mResetDialog = new AlertDialog.Builder(mContext)
                .setTitle(R.string.reset_bluetooth_wifi_title)
                .setMessage(R.string.reset_bluetooth_wifi_desc)
                .setPositiveButton(R.string.reset_bluetooth_wifi_button_text, this)
                .setNegativeButton(R.string.cancel, null /* OnClickListener */)
                .setOnDismissListener(this)
                .show();
    }

    public void onDismiss(DialogInterface dialog) {
        if (mResetDialog == dialog) {
            mResetDialog = null;
        }
    }

    /**
     * User pressed confirmation button, for starting reset operation.
     */
    public void onClick(DialogInterface dialog, int which) {
        if (mResetDialog != dialog) {
            return;
        }

        // User confirm the reset operation
        MetricsFeatureProvider provider = FeatureFactory.getFactory(mContext)
                .getMetricsFeatureProvider();
        provider.action(mContext, SettingsEnums.RESET_BLUETOOTH_WIFI_CONFIRM, true);

        // Non-cancelable progress dialog
        mProgressDialog = getProgressDialog(mContext);
        mProgressDialog.show();

        // Run reset in background thread
        mExecutorService = Executors.newSingleThreadExecutor();
        mExecutorService.execute(() -> {
            final AtomicReference<Exception> exceptionDuringReset =
                    new AtomicReference<Exception>();
            try {
                resetOperation();
            } catch (Exception exception) {
                exceptionDuringReset.set(exception);
            }
            mContext.getMainExecutor().execute(() -> endOfReset(exceptionDuringReset.get()));
        });
    }

    @VisibleForTesting
    protected ProgressDialog getProgressDialog(Context context) {
        final ProgressDialog progressDialog = new ProgressDialog(context);
        progressDialog.setIndeterminate(true);
        progressDialog.setCancelable(false);
        progressDialog.setMessage(
                context.getString(R.string.main_clear_progress_text));
        return progressDialog;
    }

    @VisibleForTesting
    protected void resetOperation() throws Exception {
        new ResetNetworkRequest(
                ResetNetworkRequest.RESET_WIFI_MANAGER |
                ResetNetworkRequest.RESET_WIFI_P2P_MANAGER |
                ResetNetworkRequest.RESET_BLUETOOTH_MANAGER
        ).toResetNetworkOperationBuilder(mContext, Looper.getMainLooper())
                .build().run();
    }

    @VisibleForTesting
    protected void endOfReset(Exception exceptionDuringReset) {
        if (mExecutorService != null) {
            mExecutorService.shutdown();
            mExecutorService = null;
        }
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
        if (exceptionDuringReset == null) {
            Toast.makeText(mContext, R.string.reset_bluetooth_wifi_complete_toast,
                    Toast.LENGTH_SHORT).show();
        } else {
            Log.e(TAG, "Exception during reset", exceptionDuringReset);
        }
    }
}
+58 −0
Original line number Diff line number Diff line
/*
 * 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 com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;

import android.content.Context;

import com.android.settings.R;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowToast;

@RunWith(RobolectricTestRunner.class)
public class BluetoothWiFiResetPreferenceControllerTest {

    private static final String PREFERENCE_KEY = "network_reset_bluetooth_wifi_pref";

    private Context mContext;
    private BluetoothWiFiResetPreferenceController mTarget;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = spy(RuntimeEnvironment.application);

        mTarget = spy(new BluetoothWiFiResetPreferenceController(mContext, PREFERENCE_KEY));
    }

    @Test
    public void endOfReset_toastMessage_whenSuccess() {
        mTarget.endOfReset(null);

        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
                mContext.getString(R.string.reset_bluetooth_wifi_complete_toast));
    }

}