/* * Copyright (C) 2023 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.settings.SettingsEnums import android.content.Context import android.os.Looper import android.os.UserManager import android.util.Log import android.widget.Toast import androidx.annotation.VisibleForTesting import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settings.ResetNetworkRequest import com.android.settings.Utils import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.spa.preference.ComposePreferenceController import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext /** * This is to show a preference regarding resetting Bluetooth and Wi-Fi. */ class BluetoothWiFiResetPreferenceController(context: Context, preferenceKey: String) : ComposePreferenceController(context, preferenceKey) { private val restrictionChecker = NetworkResetRestrictionChecker(context) override fun getAvailabilityStatus() = if (restrictionChecker.hasUserRestriction()) CONDITIONALLY_UNAVAILABLE else AVAILABLE @Composable override fun Content() { val coroutineScope = rememberCoroutineScope() val dialogPresenter = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.reset_bluetooth_wifi_button_text), ) { reset(coroutineScope) }, dismissButton = AlertDialogButton(text = stringResource(R.string.cancel)), title = stringResource(R.string.reset_bluetooth_wifi_title), ) { Text(stringResource(R.string.reset_bluetooth_wifi_desc)) } RestrictedPreference( model = object : PreferenceModel { override val title = stringResource(R.string.reset_bluetooth_wifi_title) override val onClick = dialogPresenter::open }, restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_NETWORK_RESET)), ) } /** * User pressed confirmation button, for starting reset operation. */ private fun reset(coroutineScope: CoroutineScope) { // User confirm the reset operation featureFactory.metricsFeatureProvider .action(mContext, SettingsEnums.RESET_BLUETOOTH_WIFI_CONFIRM, true) // Run reset in background thread coroutineScope.launch { try { withContext(Dispatchers.Default) { resetOperation().run() } } catch (e: Exception) { Log.e(TAG, "Exception during reset", e) return@launch } Toast.makeText( mContext, R.string.reset_bluetooth_wifi_complete_toast, Toast.LENGTH_SHORT, ).show() } } @VisibleForTesting fun resetOperation(): Runnable = if (Utils.isMobileDataCapable(mContext) || Utils.isVoiceCapable(mContext)) { ResetNetworkRequest( ResetNetworkRequest.RESET_WIFI_MANAGER or ResetNetworkRequest.RESET_WIFI_P2P_MANAGER or ResetNetworkRequest.RESET_BLUETOOTH_MANAGER ) .toResetNetworkOperationBuilder(mContext, Looper.getMainLooper()) } else { // For device without telephony capabilities ResetNetworkRequest( ResetNetworkRequest.RESET_CONNECTIVITY_MANAGER or ResetNetworkRequest.RESET_VPN_MANAGER or ResetNetworkRequest.RESET_WIFI_MANAGER or ResetNetworkRequest.RESET_WIFI_P2P_MANAGER or ResetNetworkRequest.RESET_BLUETOOTH_MANAGER ) .toResetNetworkOperationBuilder(mContext, Looper.getMainLooper()) .resetTelephonyAndNetworkPolicyManager(ResetNetworkRequest.ALL_SUBSCRIPTION_ID) }.build() private companion object { private const val TAG = "BluetoothWiFiResetPref" } }