From a159f49e0847103befb2751392904362cc69a594 Mon Sep 17 00:00:00 2001 From: Shivansh Agarwal Date: Sun, 26 Apr 2026 22:48:07 +0530 Subject: [PATCH] Settings: Add support to enable airplane mode on boot [2/2] --- res/values/strings.xml | 4 ++ res/xml/airplane_mode_settings.xml | 36 ++++++++++ res/xml/network_provider_internet.xml | 5 +- .../core/gateway/SettingsGateway.java | 2 + .../AirplaneModeOnBootPreferenceController.kt | 54 ++++++++++++++ .../network/AirplaneModePreference.kt | 3 +- .../AirplaneModePreferenceController.java | 29 ++++++-- .../settings/network/AirplaneModeScreen.kt | 71 +++++++++++++++++++ .../settings/network/AirplaneModeSettings.kt | 46 ++++++++++++ .../network/NetworkDashboardScreen.kt | 2 +- 10 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 res/xml/airplane_mode_settings.xml create mode 100644 src/com/android/settings/network/AirplaneModeOnBootPreferenceController.kt create mode 100644 src/com/android/settings/network/AirplaneModeScreen.kt create mode 100644 src/com/android/settings/network/AirplaneModeSettings.kt diff --git a/res/values/strings.xml b/res/values/strings.xml index 1d76e61ae93..37717c8a470 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -707,6 +707,10 @@ Settings shortcut Airplane mode + + Turn on airplane mode on boot + + Enables airplane mode when the device is booting up regardless of previous airplane mode state Wireless & networks diff --git a/res/xml/airplane_mode_settings.xml b/res/xml/airplane_mode_settings.xml new file mode 100644 index 00000000000..59e59ac7731 --- /dev/null +++ b/res/xml/airplane_mode_settings.xml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/res/xml/network_provider_internet.xml b/res/xml/network_provider_internet.xml index 594d307f83e..85538756bd7 100644 --- a/res/xml/network_provider_internet.xml +++ b/res/xml/network_provider_internet.xml @@ -64,11 +64,12 @@ settings:controller="com.android.settings.network.GoogleEuiccLpaController" settings:userRestriction="no_config_mobile_networks"/> - @@ -138,7 +139,7 @@ android:title="@string/remote_provisioning_title" android:order="35" settings:controller="com.android.settings.network.RemoteProvisioningPrefController" /> - + (KEY).onPreferenceChangeListener = + context.requirePreference(KEY).onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _: Preference, _: Any -> if (isInEcmMode(context)) { showEcmDialog(context) diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java index d5ad622e2be..b3c82f52211 100644 --- a/src/com/android/settings/network/AirplaneModePreferenceController.java +++ b/src/com/android/settings/network/AirplaneModePreferenceController.java @@ -19,6 +19,7 @@ import static com.android.settings.network.SatelliteWarningDialogActivity.TYPE_IS_AIRPLANE_MODE; import android.app.Activity; +import android.app.settings.SettingsEnums; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -38,7 +39,10 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.contract.SettingsContractKt; +import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.PrimarySwitchPreference; +import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnDestroy; import com.android.settingslib.core.lifecycle.events.OnResume; @@ -70,7 +74,7 @@ public class AirplaneModePreferenceController extends TogglePreferenceController private Fragment mFragment; private AirplaneModeEnabler mAirplaneModeEnabler; - private TwoStatePreference mAirplaneModePreference; + private Preference mAirplaneModePreference; private SatelliteRepository mSatelliteRepository; @VisibleForTesting AtomicBoolean mIsSatelliteOn = new AtomicBoolean(false); @@ -190,7 +194,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { final boolean isChoiceYes = (resultCode == Activity.RESULT_OK); // Set Airplane mode based on the return value and checkbox state mAirplaneModeEnabler.setAirplaneModeInECM(isChoiceYes, - mAirplaneModePreference.isChecked()); + getPreferenceCheckedState()); } } @@ -212,8 +216,25 @@ public boolean setChecked(boolean isChecked) { @Override public void onAirplaneModeChanged(boolean isAirplaneModeOn) { - if (mAirplaneModePreference != null) { - mAirplaneModePreference.setChecked(isAirplaneModeOn); + setPreferenceCheckedState(isAirplaneModeOn); + } + + private boolean getPreferenceCheckedState() { + if (mAirplaneModePreference instanceof PrimarySwitchPreference) { + return ((PrimarySwitchPreference) mAirplaneModePreference).isChecked(); + } else if (mAirplaneModePreference instanceof TwoStatePreference) { + return ((TwoStatePreference) mAirplaneModePreference).isChecked(); + } + return isChecked(); + } + + private void setPreferenceCheckedState(boolean isAirplaneModeOn) { + if (mAirplaneModePreference instanceof PrimarySwitchPreference) { + ((PrimarySwitchPreference) mAirplaneModePreference).setChecked(isAirplaneModeOn); + } else if (mAirplaneModePreference instanceof RestrictedSwitchPreference) { + ((RestrictedSwitchPreference) mAirplaneModePreference).setChecked(isAirplaneModeOn); + } else if (mAirplaneModePreference instanceof TwoStatePreference) { + ((TwoStatePreference) mAirplaneModePreference).setChecked(isAirplaneModeOn); } } } diff --git a/src/com/android/settings/network/AirplaneModeScreen.kt b/src/com/android/settings/network/AirplaneModeScreen.kt new file mode 100644 index 00000000000..8330d129a42 --- /dev/null +++ b/src/com/android/settings/network/AirplaneModeScreen.kt @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2026 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.content.pm.PackageManager +import android.os.UserManager +import androidx.fragment.app.Fragment +import com.android.settings.R +import com.android.settings.core.PreferenceScreenMixin +import com.android.settings.restriction.PreferenceRestrictionMixin +import com.android.settingslib.metadata.PreferenceAvailabilityProvider +import com.android.settingslib.metadata.ProvidePreferenceScreen +import com.android.settingslib.metadata.preferenceHierarchy +import kotlinx.coroutines.CoroutineScope + +@ProvidePreferenceScreen(AirplaneModeScreen.KEY) +open class AirplaneModeScreen : + PreferenceScreenMixin, PreferenceAvailabilityProvider, PreferenceRestrictionMixin { + + override val key: String + get() = KEY + + override val title: Int + get() = R.string.airplane_mode + + override val icon: Int + get() = R.drawable.ic_airplanemode_active + + override val highlightMenuKey: Int + get() = R.string.menu_key_network + + override fun getMetricsCategory() = SettingsEnums.SETTINGS_NETWORK_CATEGORY + + override fun isAvailable(context: Context) = + context.resources.getBoolean(R.bool.config_show_toggle_airplane) && + !context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) + + override fun isEnabled(context: Context) = super.isEnabled(context) + + override val restrictionKeys + get() = arrayOf(UserManager.DISALLOW_AIRPLANE_MODE) + + override fun hasCompleteHierarchy() = false + + override fun getPreferenceHierarchy(context: Context, coroutineScope: CoroutineScope) = + preferenceHierarchy(context) { + +AirplaneModePreference() + } + + override fun fragmentClass(): Class? = AirplaneModeSettings::class.java + + companion object { + const val KEY = "airplane_mode_screen" + } +} diff --git a/src/com/android/settings/network/AirplaneModeSettings.kt b/src/com/android/settings/network/AirplaneModeSettings.kt new file mode 100644 index 00000000000..74fc0714623 --- /dev/null +++ b/src/com/android/settings/network/AirplaneModeSettings.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2026 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.content.Intent +import com.android.settings.R +import com.android.settings.dashboard.DashboardFragment + +class AirplaneModeSettings : DashboardFragment() { + override fun onAttach(context: Context) { + super.onAttach(context) + use(AirplaneModePreferenceController::class.java).setFragment(this) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + use(AirplaneModePreferenceController::class.java) + .onActivityResult(requestCode, resultCode, data) + } + + override fun getMetricsCategory(): Int = SettingsEnums.SETTINGS_NETWORK_CATEGORY + + override fun getLogTag(): String = TAG + + override fun getPreferenceScreenResId(): Int = R.xml.airplane_mode_settings + + private companion object { + private const val TAG = "AirplaneModeSettings" + } +} diff --git a/src/com/android/settings/network/NetworkDashboardScreen.kt b/src/com/android/settings/network/NetworkDashboardScreen.kt index f96b5d08f79..f5a918233f5 100644 --- a/src/com/android/settings/network/NetworkDashboardScreen.kt +++ b/src/com/android/settings/network/NetworkDashboardScreen.kt @@ -62,7 +62,7 @@ open class NetworkDashboardScreen : PreferenceScreenMixin, PreferenceIconProvide override fun getPreferenceHierarchy(context: Context, coroutineScope: CoroutineScope) = preferenceHierarchy(context) { if (Flags.catalystMobileNetworkList()) +MobileNetworkListScreen.KEY order -15 - +AirplaneModePreference() order -5 + +AirplaneModeScreen.KEY order -5 if (Flags.catalystRestrictBackgroundParentEntry()) +DataSaverScreen.KEY order 10 }