1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.provider.Settings; 22 23 import java.io.FileDescriptor; 24 import java.io.PrintWriter; 25 26 /* Tracks persisted settings for Wi-Fi and airplane mode interaction */ 27 public class WifiSettingsStore { 28 /* Values tracked in Settings.Global.WIFI_ON */ 29 static final int WIFI_DISABLED = 0; 30 static final int WIFI_ENABLED = 1; 31 32 /* Wifi enabled while in airplane mode */ 33 private static final int WIFI_ENABLED_AIRPLANE_OVERRIDE = 2; 34 /* Wifi disabled due to airplane mode on */ 35 private static final int WIFI_DISABLED_AIRPLANE_ON = 3; 36 37 /* Persisted state that tracks the wifi & airplane interaction from settings */ 38 private int mPersistWifiState = WIFI_DISABLED; 39 /* Tracks current airplane mode state */ 40 private boolean mAirplaneModeOn = false; 41 42 private final Context mContext; 43 private final WifiSettingsConfigStore mSettingsConfigStore; 44 WifiSettingsStore(Context context, WifiSettingsConfigStore sharedPreferences)45 WifiSettingsStore(Context context, WifiSettingsConfigStore sharedPreferences) { 46 mContext = context; 47 mSettingsConfigStore = sharedPreferences; 48 mAirplaneModeOn = getPersistedAirplaneModeOn(); 49 mPersistWifiState = getPersistedWifiState(); 50 } 51 isWifiToggleEnabled()52 public synchronized boolean isWifiToggleEnabled() { 53 return mPersistWifiState == WIFI_ENABLED 54 || mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE; 55 } 56 57 /** 58 * Returns true if airplane mode is currently on. 59 * @return {@code true} if airplane mode is on. 60 */ isAirplaneModeOn()61 public synchronized boolean isAirplaneModeOn() { 62 return mAirplaneModeOn; 63 } 64 isScanAlwaysAvailableToggleEnabled()65 public synchronized boolean isScanAlwaysAvailableToggleEnabled() { 66 return getPersistedScanAlwaysAvailable(); 67 } 68 isScanAlwaysAvailable()69 public synchronized boolean isScanAlwaysAvailable() { 70 return !mAirplaneModeOn && getPersistedScanAlwaysAvailable(); 71 } 72 isWifiScoringEnabled()73 public synchronized boolean isWifiScoringEnabled() { 74 return getPersistedWifiScoringEnabled(); 75 } 76 isWifiPasspointEnabled()77 public synchronized boolean isWifiPasspointEnabled() { 78 return getPersistedWifiPasspointEnabled(); 79 } 80 getWifiMultiInternetMode()81 public synchronized int getWifiMultiInternetMode() { 82 return getPersistedWifiMultiInternetMode(); 83 } 84 handleWifiToggled(boolean wifiEnabled)85 public synchronized boolean handleWifiToggled(boolean wifiEnabled) { 86 // Can Wi-Fi be toggled in airplane mode ? 87 if (mAirplaneModeOn && !isAirplaneToggleable()) { 88 return false; 89 } 90 91 if (wifiEnabled) { 92 if (mAirplaneModeOn) { 93 persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE); 94 } else { 95 persistWifiState(WIFI_ENABLED); 96 } 97 } else { 98 // When wifi state is disabled, we do not care 99 // if airplane mode is on or not. The scenario of 100 // wifi being disabled due to airplane mode being turned on 101 // is handled handleAirplaneModeToggled() 102 persistWifiState(WIFI_DISABLED); 103 } 104 return true; 105 } 106 updateAirplaneModeTracker()107 synchronized boolean updateAirplaneModeTracker() { 108 // Is Wi-Fi sensitive to airplane mode changes ? 109 if (!isAirplaneSensitive()) { 110 return false; 111 } 112 113 mAirplaneModeOn = getPersistedAirplaneModeOn(); 114 return true; 115 } 116 handleAirplaneModeToggled()117 synchronized void handleAirplaneModeToggled() { 118 if (mAirplaneModeOn) { 119 // Wifi disabled due to airplane on 120 if (mPersistWifiState == WIFI_ENABLED) { 121 persistWifiState(WIFI_DISABLED_AIRPLANE_ON); 122 } 123 } else { 124 /* On airplane mode disable, restore wifi state if necessary */ 125 if (mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE 126 || mPersistWifiState == WIFI_DISABLED_AIRPLANE_ON) { 127 persistWifiState(WIFI_ENABLED); 128 } 129 } 130 } 131 handleWifiScanAlwaysAvailableToggled(boolean isAvailable)132 synchronized void handleWifiScanAlwaysAvailableToggled(boolean isAvailable) { 133 persistScanAlwaysAvailableState(isAvailable); 134 } 135 handleWifiScoringEnabled(boolean enabled)136 synchronized boolean handleWifiScoringEnabled(boolean enabled) { 137 persistWifiScoringEnabledState(enabled); 138 return true; 139 } 140 141 /** 142 * Handle the Wifi Passpoint enable/disable status change. 143 */ handleWifiPasspointEnabled(boolean enabled)144 public synchronized void handleWifiPasspointEnabled(boolean enabled) { 145 persistWifiPasspointEnabledState(enabled); 146 } 147 148 /** 149 * Handle the Wifi Multi Internet state change. 150 */ handleWifiMultiInternetMode(int mode)151 public synchronized void handleWifiMultiInternetMode(int mode) { 152 persistWifiMultiInternetMode(mode); 153 } 154 dump(FileDescriptor fd, PrintWriter pw, String[] args)155 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 156 pw.println("WifiState " + getPersistedWifiState()); 157 pw.println("AirplaneModeOn " + getPersistedAirplaneModeOn()); 158 pw.println("ScanAlwaysAvailable " + getPersistedScanAlwaysAvailable()); 159 pw.println("WifiScoringState " + getPersistedWifiScoringEnabled()); 160 pw.println("WifiPasspointState " + getPersistedWifiPasspointEnabled()); 161 pw.println("WifiMultiInternetMode " + getPersistedWifiMultiInternetMode()); 162 } 163 persistWifiState(int state)164 private void persistWifiState(int state) { 165 final ContentResolver cr = mContext.getContentResolver(); 166 mPersistWifiState = state; 167 Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state); 168 } 169 persistScanAlwaysAvailableState(boolean isAvailable)170 private void persistScanAlwaysAvailableState(boolean isAvailable) { 171 mSettingsConfigStore.put( 172 WifiSettingsConfigStore.WIFI_SCAN_ALWAYS_AVAILABLE, isAvailable); 173 } 174 persistWifiScoringEnabledState(boolean enabled)175 private void persistWifiScoringEnabledState(boolean enabled) { 176 mSettingsConfigStore.put( 177 WifiSettingsConfigStore.WIFI_SCORING_ENABLED, enabled); 178 } 179 persistWifiPasspointEnabledState(boolean enabled)180 private void persistWifiPasspointEnabledState(boolean enabled) { 181 mSettingsConfigStore.put( 182 WifiSettingsConfigStore.WIFI_PASSPOINT_ENABLED, enabled); 183 } 184 persistWifiMultiInternetMode(int mode)185 private void persistWifiMultiInternetMode(int mode) { 186 mSettingsConfigStore.put( 187 WifiSettingsConfigStore.WIFI_MULTI_INTERNET_MODE, mode); 188 } 189 190 /* Does Wi-Fi need to be disabled when airplane mode is on ? */ isAirplaneSensitive()191 private boolean isAirplaneSensitive() { 192 String airplaneModeRadios = Settings.Global.getString(mContext.getContentResolver(), 193 Settings.Global.AIRPLANE_MODE_RADIOS); 194 return airplaneModeRadios == null 195 || airplaneModeRadios.contains(Settings.Global.RADIO_WIFI); 196 } 197 198 /* Is Wi-Fi allowed to be re-enabled while airplane mode is on ? */ isAirplaneToggleable()199 private boolean isAirplaneToggleable() { 200 String toggleableRadios = Settings.Global.getString(mContext.getContentResolver(), 201 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 202 return toggleableRadios != null 203 && toggleableRadios.contains(Settings.Global.RADIO_WIFI); 204 } 205 getPersistedWifiState()206 private int getPersistedWifiState() { 207 final ContentResolver cr = mContext.getContentResolver(); 208 try { 209 return Settings.Global.getInt(cr, Settings.Global.WIFI_ON); 210 } catch (Settings.SettingNotFoundException e) { 211 Settings.Global.putInt(cr, Settings.Global.WIFI_ON, WIFI_DISABLED); 212 return WIFI_DISABLED; 213 } 214 } 215 getPersistedAirplaneModeOn()216 private boolean getPersistedAirplaneModeOn() { 217 return Settings.Global.getInt(mContext.getContentResolver(), 218 Settings.Global.AIRPLANE_MODE_ON, 0) == 1; 219 } 220 getPersistedScanAlwaysAvailable()221 private boolean getPersistedScanAlwaysAvailable() { 222 return mSettingsConfigStore.get( 223 WifiSettingsConfigStore.WIFI_SCAN_ALWAYS_AVAILABLE); 224 } 225 getPersistedWifiScoringEnabled()226 private boolean getPersistedWifiScoringEnabled() { 227 return mSettingsConfigStore.get( 228 WifiSettingsConfigStore.WIFI_SCORING_ENABLED); 229 } 230 getPersistedWifiPasspointEnabled()231 private boolean getPersistedWifiPasspointEnabled() { 232 return mSettingsConfigStore.get( 233 WifiSettingsConfigStore.WIFI_PASSPOINT_ENABLED); 234 } 235 getPersistedWifiMultiInternetMode()236 private int getPersistedWifiMultiInternetMode() { 237 return mSettingsConfigStore.get( 238 WifiSettingsConfigStore.WIFI_MULTI_INTERNET_MODE); 239 } 240 } 241