Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,10 @@
<string name="settings_shortcut">Settings shortcut</string>
<!-- Wireless controls settings screen, setting check box label -->
<string name="airplane_mode">Airplane mode</string>
<!-- Title for setting that turns on airplane mode when the device starts [CHAR LIMIT=NONE] -->
<string name="airplane_mode_on_boot_title">Turn on airplane mode on boot</string>
<!-- Summary for setting that turns on airplane mode when the device starts [CHAR LIMIT=NONE] -->
<string name="airplane_mode_on_boot_summary">Enables airplane mode when the device is booting up regardless of previous airplane mode state</string>
<!-- Wireless Settings screen title for things like Wi-Fi, bluetooth, airplane mode. -->
<string name="wireless_networks_settings_title">Wireless &amp; networks</string>

Expand Down
36 changes: 36 additions & 0 deletions res/xml/airplane_mode_settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="airplane_mode_settings_screen"
android:title="@string/airplane_mode">

<com.android.settingslib.RestrictedSwitchPreference
android:key="airplane_mode_on"
android:title="@string/airplane_mode"
android:icon="@drawable/ic_airplanemode_active"
settings:controller="com.android.settings.network.AirplaneModePreferenceController"
settings:userRestriction="no_airplane_mode" />

<com.android.settingslib.RestrictedSwitchPreference
android:key="airplane_mode_on_boot"
android:title="@string/airplane_mode_on_boot_title"
android:summary="@string/airplane_mode_on_boot_summary"
settings:controller="com.android.settings.network.AirplaneModeOnBootPreferenceController"
settings:userRestriction="no_airplane_mode" />

</PreferenceScreen>
5 changes: 3 additions & 2 deletions res/xml/network_provider_internet.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@
settings:controller="com.android.settings.network.GoogleEuiccLpaController"
settings:userRestriction="no_config_mobile_networks"/>

<com.android.settingslib.RestrictedSwitchPreference
<com.android.settingslib.PrimarySwitchPreference
android:key="airplane_mode_on"
android:title="@string/airplane_mode"
android:icon="@drawable/ic_airplanemode_active"
android:order="-5"
android:fragment="com.android.settings.network.AirplaneModeSettings"
settings:controller="com.android.settings.network.AirplaneModePreferenceController"
settings:userRestriction="no_airplane_mode"/>

Expand Down Expand Up @@ -138,7 +139,7 @@
android:title="@string/remote_provisioning_title"
android:order="35"
settings:controller="com.android.settings.network.RemoteProvisioningPrefController" />

<Preference
android:key="widevine_provisioning_settings"
android:title="@string/widevine_provisioning_title"
Expand Down
2 changes: 2 additions & 0 deletions src/com/android/settings/core/gateway/SettingsGateway.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
import com.android.settings.location.LocationServices;
import com.android.settings.location.LocationSettings;
import com.android.settings.location.WifiScanningFragment;
import com.android.settings.network.AirplaneModeSettings;
import com.android.settings.network.MobileNetworkListFragment;
import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.network.NetworkProviderSettings;
Expand Down Expand Up @@ -240,6 +241,7 @@ public class SettingsGateway {
CreateShortcut.class.getName(),
BluetoothPairingDetail.class.getName(),
BluetoothDashboardFragment.class.getName(),
AirplaneModeSettings.class.getName(),
WifiNetworkDetailsFragment.class.getName(),
ConfigureWifiSettings.class.getName(),
SavedAccessPointsWifiSettings2.class.getName(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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.content.Context
import android.provider.Settings
import androidx.preference.Preference
import com.android.settings.R
import com.android.settings.core.TogglePreferenceController

class AirplaneModeOnBootPreferenceController(
context: Context,
preferenceKey: String,
) : TogglePreferenceController(context, preferenceKey) {

override fun getAvailabilityStatus(): Int =
if (AirplaneModePreferenceController.isAvailable(mContext)) AVAILABLE
else UNSUPPORTED_ON_DEVICE

override fun isChecked(): Boolean =
Settings.Global.getInt(
mContext.contentResolver,
Settings.Global.AIRPLANE_MODE_ON_BOOT,
0,
) != 0

override fun setChecked(isChecked: Boolean): Boolean {
return Settings.Global.putInt(
mContext.contentResolver,
Settings.Global.AIRPLANE_MODE_ON_BOOT,
if (isChecked) 1 else 0
)
}

override fun getSliceHighlightMenuRes(): Int = R.string.menu_key_network

companion object {
const val KEY: String = "airplane_mode_on_boot"
}
}
3 changes: 1 addition & 2 deletions src/com/android/settings/network/AirplaneModePreference.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import com.android.settings.contract.KEY_AIRPLANE_MODE
import com.android.settings.metrics.PreferenceActionMetricsProvider
import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn
import com.android.settings.restriction.PreferenceRestrictionMixin
import com.android.settingslib.RestrictedSwitchPreference
import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.KeyValueStoreDelegate
import com.android.settingslib.datastore.SettingsGlobalStore
Expand Down Expand Up @@ -89,7 +88,7 @@ class AirplaneModePreference :
override fun storage(context: Context) = createDataStore(context)

override fun onCreate(context: PreferenceLifecycleContext) {
context.requirePreference<RestrictedSwitchPreference>(KEY).onPreferenceChangeListener =
context.requirePreference<Preference>(KEY).onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference, _: Any ->
if (isInEcmMode(context)) {
showEcmDialog(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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());
}
}

Expand All @@ -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);
}
}
}
Expand Down
71 changes: 71 additions & 0 deletions src/com/android/settings/network/AirplaneModeScreen.kt
Original file line number Diff line number Diff line change
@@ -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<PreferenceRestrictionMixin>.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<out Fragment>? = AirplaneModeSettings::class.java

companion object {
const val KEY = "airplane_mode_screen"
}
}
46 changes: 46 additions & 0 deletions src/com/android/settings/network/AirplaneModeSettings.kt
Original file line number Diff line number Diff line change
@@ -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"
}
}
2 changes: 1 addition & 1 deletion src/com/android/settings/network/NetworkDashboardScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down