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
}