1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/* 2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2013 The Android Open Source Project 3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License"); 5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License. 6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at 7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * http://www.apache.org/licenses/LICENSE-2.0 9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software 11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS, 12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and 14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License. 15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi; 18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 19155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.app.AlarmManager; 20155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.app.PendingIntent; 21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.BroadcastReceiver; 22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context; 23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Intent; 24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.IntentFilter; 25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.database.ContentObserver; 26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.ConnectivityManager; 27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkInfo; 28155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiConfiguration; 29155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiManager; 30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_MODE_FULL; 31155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_MODE_FULL_HIGH_PERF; 32155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_MODE_SCAN_ONLY; 33155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Handler; 34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Looper; 35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Message; 36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.SystemClock; 37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.WorkSource; 38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.provider.Settings; 39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Slog; 40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.Protocol; 42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.State; 43155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.StateMachine; 44155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.server.wifi.WifiServiceImpl.LockList; 45155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 46155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileDescriptor; 47155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.PrintWriter; 48155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 49155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeclass WifiController extends StateMachine { 50155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final String TAG = "WifiController"; 51155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final boolean DBG = false; 52155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private Context mContext; 53155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mScreenOff; 54155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mDeviceIdle; 55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mPluggedType; 56155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mStayAwakeConditions; 57155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private long mIdleMillis; 58155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mSleepPolicy; 59155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mFirstUserSignOnSeen = false; 60155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 61155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private AlarmManager mAlarmManager; 62155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private PendingIntent mIdleIntent; 63155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final int IDLE_REQUEST = 0; 64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See {@link Settings.Global#WIFI_IDLE_MS}. This is the default value if a 67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Settings.Global value is not present. This timeout value is chosen as 68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * the approximate point at which the battery drain caused by Wi-Fi 69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * being enabled but not active exceeds the battery drain caused by 70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * re-establishing a connection to the mobile data network. 71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 72155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final long DEFAULT_IDLE_MS = 15 * 60 * 1000; /* 15 minutes */ 73155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 74155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 75155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See {@link Settings.Global#WIFI_REENABLE_DELAY_MS}. This is the default value if a 76155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Settings.Global value is not present. This is the minimum time after wifi is disabled 77155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * we'll act on an enable. Enable requests received before this delay will be deferred. 78155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 79155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final long DEFAULT_REENABLE_DELAY_MS = 500; 80155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 81155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // finding that delayed messages can sometimes be delivered earlier than expected 82155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // probably rounding errors.. add a margin to prevent problems 83155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final long DEFER_MARGIN_MS = 5; 84155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande NetworkInfo mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", ""); 86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 87155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final String ACTION_DEVICE_IDLE = 88155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande "com.android.server.WifiManager.action.DEVICE_IDLE"; 89155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 90155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* References to values tracked in WifiService */ 91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande final WifiStateMachine mWifiStateMachine; 92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande final WifiSettingsStore mSettingsStore; 93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande final LockList mLocks; 94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Temporary for computing UIDS that are responsible for starting WIFI. 97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Protected by mWifiStateTracker lock. 98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private final WorkSource mTmpWorkSource = new WorkSource(); 100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private long mReEnableDelayMillis; 102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final int BASE = Protocol.BASE_WIFI_CONTROLLER; 104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_EMERGENCY_MODE_CHANGED = BASE + 1; 106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_SCREEN_ON = BASE + 2; 107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_SCREEN_OFF = BASE + 3; 108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_BATTERY_CHANGED = BASE + 4; 109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_DEVICE_IDLE = BASE + 5; 110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_LOCKS_CHANGED = BASE + 6; 111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_SCAN_ALWAYS_MODE_CHANGED = BASE + 7; 112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_WIFI_TOGGLED = BASE + 8; 113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_AIRPLANE_TOGGLED = BASE + 9; 114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_SET_AP = BASE + 10; 115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_DEFERRED_TOGGLE = BASE + 11; 116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande static final int CMD_USER_PRESENT = BASE + 12; 117588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe static final int CMD_AP_START_FAILURE = BASE + 13; 118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private DefaultState mDefaultState = new DefaultState(); 120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private StaEnabledState mStaEnabledState = new StaEnabledState(); 121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private ApStaDisabledState mApStaDisabledState = new ApStaDisabledState(); 122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private StaDisabledWithScanState mStaDisabledWithScanState = new StaDisabledWithScanState(); 123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private ApEnabledState mApEnabledState = new ApEnabledState(); 124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private DeviceActiveState mDeviceActiveState = new DeviceActiveState(); 125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private DeviceInactiveState mDeviceInactiveState = new DeviceInactiveState(); 126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private ScanOnlyLockHeldState mScanOnlyLockHeldState = new ScanOnlyLockHeldState(); 127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private FullLockHeldState mFullLockHeldState = new FullLockHeldState(); 128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private FullHighPerfLockHeldState mFullHighPerfLockHeldState = new FullHighPerfLockHeldState(); 129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private NoLockHeldState mNoLockHeldState = new NoLockHeldState(); 130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private EcmState mEcmState = new EcmState(); 131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande WifiController(Context context, WifiServiceImpl service, Looper looper) { 133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande super(TAG, looper); 134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext = context; 135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine = service.mWifiStateMachine; 136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mSettingsStore = service.mSettingsStore; 137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mLocks = service.mLocks; 138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null); 141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0); 142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mDefaultState); 144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mApStaDisabledState, mDefaultState); 145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mStaEnabledState, mDefaultState); 146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mDeviceActiveState, mStaEnabledState); 147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mDeviceInactiveState, mStaEnabledState); 148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mScanOnlyLockHeldState, mDeviceInactiveState); 149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mFullLockHeldState, mDeviceInactiveState); 150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mFullHighPerfLockHeldState, mDeviceInactiveState); 151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mNoLockHeldState, mDeviceInactiveState); 152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mStaDisabledWithScanState, mDefaultState); 153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mApEnabledState, mDefaultState); 154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mEcmState, mDefaultState); 15513494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde 15613494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn(); 15713494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled(); 15813494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable(); 15913494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde 16013494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde log("isAirplaneModeOn = " + isAirplaneModeOn + 16113494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde ", isWifiEnabled = " + isWifiEnabled + 16213494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde ", isScanningAvailable = " + isScanningAlwaysAvailable); 16313494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde 1647b160c8a00773246660caeae9e27090c83ed6ed5David Christie if (isScanningAlwaysAvailable) { 165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setInitialState(mStaDisabledWithScanState); 166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setInitialState(mApStaDisabledState); 168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 16913494d0692330ed0f91e7f4e03805473773e7807Vinit Deshapnde 170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setLogRecSize(100); 171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setLogOnlyTransitions(false); 172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande IntentFilter filter = new IntentFilter(); 174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande filter.addAction(ACTION_DEVICE_IDLE); 175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 176588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext.registerReceiver( 178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande new BroadcastReceiver() { 179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void onReceive(Context context, Intent intent) { 181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande String action = intent.getAction(); 182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (action.equals(ACTION_DEVICE_IDLE)) { 183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendMessage(CMD_DEVICE_IDLE); 184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mNetworkInfo = (NetworkInfo) intent.getParcelableExtra( 186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande WifiManager.EXTRA_NETWORK_INFO); 187588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { 188588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe int state = intent.getIntExtra( 189588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe WifiManager.EXTRA_WIFI_AP_STATE, 190588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe WifiManager.WIFI_AP_STATE_FAILED); 191588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe if(state == WifiManager.WIFI_AP_STATE_FAILED) { 192588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe loge(TAG + "SoftAP start failed"); 193588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe sendMessage(CMD_AP_START_FAILURE); 194588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe } 195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande }, 198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande new IntentFilter(filter)); 199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande initializeAndRegisterForSettingsChange(looper); 201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void initializeAndRegisterForSettingsChange(Looper looper) { 204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Handler handler = new Handler(looper); 205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readStayAwakeConditions(); 206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande registerForStayAwakeModeChange(handler); 207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readWifiIdleTime(); 208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande registerForWifiIdleTimeChange(handler); 209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readWifiSleepPolicy(); 210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande registerForWifiSleepPolicyChange(handler); 211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readWifiReEnableDelay(); 212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void readStayAwakeConditions() { 215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mStayAwakeConditions = Settings.Global.getInt(mContext.getContentResolver(), 216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); 217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void readWifiIdleTime() { 220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mIdleMillis = Settings.Global.getLong(mContext.getContentResolver(), 221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.WIFI_IDLE_MS, DEFAULT_IDLE_MS); 222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void readWifiSleepPolicy() { 225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mSleepPolicy = Settings.Global.getInt(mContext.getContentResolver(), 226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.WIFI_SLEEP_POLICY, 227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.WIFI_SLEEP_POLICY_NEVER); 228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void readWifiReEnableDelay() { 231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mReEnableDelayMillis = Settings.Global.getLong(mContext.getContentResolver(), 232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.WIFI_REENABLE_DELAY_MS, DEFAULT_REENABLE_DELAY_MS); 233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Observes settings changes to scan always mode. 237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void registerForStayAwakeModeChange(Handler handler) { 239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ContentObserver contentObserver = new ContentObserver(handler) { 240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void onChange(boolean selfChange) { 242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readStayAwakeConditions(); 243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande }; 245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext.getContentResolver().registerContentObserver( 247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.getUriFor(Settings.Global.STAY_ON_WHILE_PLUGGED_IN), 248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande false, contentObserver); 249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Observes settings changes to scan always mode. 253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void registerForWifiIdleTimeChange(Handler handler) { 255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ContentObserver contentObserver = new ContentObserver(handler) { 256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void onChange(boolean selfChange) { 258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readWifiIdleTime(); 259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande }; 261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext.getContentResolver().registerContentObserver( 263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.getUriFor(Settings.Global.WIFI_IDLE_MS), 264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande false, contentObserver); 265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Observes changes to wifi sleep policy 269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void registerForWifiSleepPolicyChange(Handler handler) { 271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ContentObserver contentObserver = new ContentObserver(handler) { 272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void onChange(boolean selfChange) { 274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande readWifiSleepPolicy(); 275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande }; 277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext.getContentResolver().registerContentObserver( 278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Settings.Global.getUriFor(Settings.Global.WIFI_SLEEP_POLICY), 279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande false, contentObserver); 280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Determines whether the Wi-Fi chipset should stay awake or be put to 284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * sleep. Looks at the setting for the sleep policy and the current 285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * conditions. 286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * @see #shouldDeviceStayAwake(int) 288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean shouldWifiStayAwake(int pluggedType) { 290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER) { 291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Never sleep 292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return true; 293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else if ((mSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED) && 294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande (pluggedType != 0)) { 295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Never sleep while plugged, and we're plugged 296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return true; 297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Default 299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return shouldDeviceStayAwake(pluggedType); 300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Determine whether the bit value corresponding to {@code pluggedType} is set in 305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * the bit string mStayAwakeConditions. This determines whether the device should 306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * stay awake based on the current plugged type. 307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * @param pluggedType the type of plug (USB, AC, or none) for which the check is 309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * being made 310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * @return {@code true} if {@code pluggedType} indicates that the device is 311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * supposed to stay awake, {@code false} otherwise. 312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean shouldDeviceStayAwake(int pluggedType) { 314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (mStayAwakeConditions & pluggedType) != 0; 315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void updateBatteryWorkSource() { 318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mTmpWorkSource.clear(); 319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mDeviceIdle) { 320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mLocks.updateWorkSource(mTmpWorkSource); 321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.updateBatteryWorkSource(mTmpWorkSource); 323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class DefaultState extends State { 326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (msg.what) { 329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SCREEN_ON: 330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAlarmManager.cancel(mIdleIntent); 331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mScreenOff = false; 332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDeviceIdle = false; 333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande updateBatteryWorkSource(); 334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SCREEN_OFF: 336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mScreenOff = true; 337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* 338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Set a timer to put Wi-Fi to sleep, but only if the screen is off 339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * AND the "stay on while plugged in" setting doesn't match the 340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * current power conditions (i.e, not plugged in, plugged in to USB, 341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * or plugged in to AC). 342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (!shouldWifiStayAwake(mPluggedType)) { 344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande //Delayed shutdown if wifi is connected 345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mNetworkInfo.getDetailedState() == 346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande NetworkInfo.DetailedState.CONNECTED) { 347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Slog.d(TAG, "set idle timer: " + mIdleMillis + " ms"); 348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAlarmManager.set(AlarmManager.RTC_WAKEUP, 349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande System.currentTimeMillis() + mIdleMillis, mIdleIntent); 350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendMessage(CMD_DEVICE_IDLE); 352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_DEVICE_IDLE: 356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDeviceIdle = true; 357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande updateBatteryWorkSource(); 358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_BATTERY_CHANGED: 360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* 361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Set a timer to put Wi-Fi to sleep, but only if the screen is off 362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * AND we are transitioning from a state in which the device was supposed 363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * to stay awake to a state in which it is not supposed to stay awake. 364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * If "stay awake" state is not changing, we do nothing, to avoid resetting 365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * the already-set timer. 366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande int pluggedType = msg.arg1; 368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Slog.d(TAG, "battery changed pluggedType: " + pluggedType); 369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mScreenOff && shouldWifiStayAwake(mPluggedType) && 370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande !shouldWifiStayAwake(pluggedType)) { 371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande long triggerTime = System.currentTimeMillis() + mIdleMillis; 372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Slog.d(TAG, "set idle timer for " + mIdleMillis + "ms"); 373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent); 374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mPluggedType = pluggedType; 377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SET_AP: 379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SCAN_ALWAYS_MODE_CHANGED: 380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_LOCKS_CHANGED: 381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_WIFI_TOGGLED: 382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_AIRPLANE_TOGGLED: 383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_EMERGENCY_MODE_CHANGED: 384588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe case CMD_AP_START_FAILURE: 385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_USER_PRESENT: 387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mFirstUserSignOnSeen = true; 388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_DEFERRED_TOGGLE: 390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande log("DEFERRED_TOGGLE ignored due to state change"); 391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande throw new RuntimeException("WifiController.handleMessage " + msg.what); 394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class ApStaDisabledState extends State { 401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mDeferredEnableSerialNumber = 0; 402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mHaveDeferredEnable = false; 403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private long mDisabledTimestamp; 404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setSupplicantRunning(false); 408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Supplicant can't restart right away, so not the time we switched off 409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDisabledTimestamp = SystemClock.elapsedRealtime(); 410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDeferredEnableSerialNumber++; 411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mHaveDeferredEnable = false; 4128366a82ee1bff4c66d3f3642bf0a60538de5d9daJan Nordqvist mWifiStateMachine.clearANQPCache(); 413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (msg.what) { 417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_WIFI_TOGGLED: 418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_AIRPLANE_TOGGLED: 419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isWifiToggleEnabled()) { 420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (doDeferEnable(msg)) { 421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mHaveDeferredEnable) { 422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // have 2 toggles now, inc serial number an ignore both 423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDeferredEnableSerialNumber++; 424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mHaveDeferredEnable = !mHaveDeferredEnable; 426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mDeviceIdle == false) { 429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mDeviceActiveState); 430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande checkLocksAndTransitionWhenDeviceIdle(); 432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 4337b160c8a00773246660caeae9e27090c83ed6ed5David Christie } else if (mSettingsStore.isScanAlwaysAvailable()) { 4347b160c8a00773246660caeae9e27090c83ed6ed5David Christie transitionTo(mStaDisabledWithScanState); 435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SCAN_ALWAYS_MODE_CHANGED: 438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isScanAlwaysAvailable()) { 439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mStaDisabledWithScanState); 440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SET_AP: 443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.arg1 == 1) { 444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setHostApRunning((WifiConfiguration) msg.obj, 445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande true); 446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApEnabledState); 447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_DEFERRED_TOGGLE: 450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.arg1 != mDeferredEnableSerialNumber) { 451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande log("DEFERRED_TOGGLE ignored due to serial mismatch"); 452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande log("DEFERRED_TOGGLE handled"); 455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendMessage((Message)(msg.obj)); 456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean doDeferEnable(Message msg) { 464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp; 465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (delaySoFar >= mReEnableDelayMillis) { 466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return false; 467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande log("WifiController msg " + msg + " deferred for " + 470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande (mReEnableDelayMillis - delaySoFar) + "ms"); 471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // need to defer this action. 473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE); 474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande deferredMsg.obj = Message.obtain(msg); 475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande deferredMsg.arg1 = ++mDeferredEnableSerialNumber; 476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS); 477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return true; 478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class StaEnabledState extends State { 483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setSupplicantRunning(true); 486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (msg.what) { 490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_WIFI_TOGGLED: 491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (! mSettingsStore.isWifiToggleEnabled()) { 492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isScanAlwaysAvailable()) { 493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mStaDisabledWithScanState); 494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_AIRPLANE_TOGGLED: 500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* When wi-fi is turned off due to airplane, 501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * disable entirely (including scan) 502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (! mSettingsStore.isWifiToggleEnabled()) { 504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_EMERGENCY_MODE_CHANGED: 508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.arg1 == 1) { 509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mEcmState); 510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class StaDisabledWithScanState extends State { 521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mDeferredEnableSerialNumber = 0; 522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mHaveDeferredEnable = false; 523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private long mDisabledTimestamp; 524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setSupplicantRunning(true); 528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE); 529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setDriverStart(true); 530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Supplicant can't restart right away, so not the time we switched off 531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDisabledTimestamp = SystemClock.elapsedRealtime(); 532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDeferredEnableSerialNumber++; 533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mHaveDeferredEnable = false; 5348366a82ee1bff4c66d3f3642bf0a60538de5d9daJan Nordqvist mWifiStateMachine.clearANQPCache(); 535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (msg.what) { 540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_WIFI_TOGGLED: 541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isWifiToggleEnabled()) { 542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (doDeferEnable(msg)) { 543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mHaveDeferredEnable) { 544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // have 2 toggles now, inc serial number and ignore both 545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mDeferredEnableSerialNumber++; 546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mHaveDeferredEnable = !mHaveDeferredEnable; 548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mDeviceIdle == false) { 551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mDeviceActiveState); 552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande checkLocksAndTransitionWhenDeviceIdle(); 554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_AIRPLANE_TOGGLED: 558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isAirplaneModeOn() && 559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ! mSettingsStore.isWifiToggleEnabled()) { 560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SCAN_ALWAYS_MODE_CHANGED: 563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (! mSettingsStore.isScanAlwaysAvailable()) { 564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SET_AP: 568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Before starting tethering, turn off supplicant for scan mode 569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.arg1 == 1) { 570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande deferMessage(msg); 571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_DEFERRED_TOGGLE: 575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.arg1 != mDeferredEnableSerialNumber) { 576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande log("DEFERRED_TOGGLE ignored due to serial mismatch"); 577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande logd("DEFERRED_TOGGLE handled"); 580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendMessage((Message)(msg.obj)); 581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean doDeferEnable(Message msg) { 589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp; 590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (delaySoFar >= mReEnableDelayMillis) { 591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return false; 592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande log("WifiController msg " + msg + " deferred for " + 595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande (mReEnableDelayMillis - delaySoFar) + "ms"); 596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // need to defer this action. 598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE); 599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande deferredMsg.obj = Message.obtain(msg); 600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande deferredMsg.arg1 = ++mDeferredEnableSerialNumber; 601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS); 602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return true; 603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class ApEnabledState extends State { 608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (msg.what) { 611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_AIRPLANE_TOGGLED: 612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isAirplaneModeOn()) { 613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setHostApRunning(null, false); 614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SET_AP: 618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.arg1 == 0) { 619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setHostApRunning(null, false); 620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 623588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe case CMD_AP_START_FAILURE: 624588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe if(!mSettingsStore.isScanAlwaysAvailable()) { 625588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe transitionTo(mApStaDisabledState); 626588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe } else { 627588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe transitionTo(mStaDisabledWithScanState); 628588e4ba694aba1b5b34aa2596809d8fa80ecb59dxinhe } 629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class EcmState extends State { 637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setSupplicantRunning(false); 640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.what == CMD_EMERGENCY_MODE_CHANGED && msg.arg1 == 0) { 645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isWifiToggleEnabled()) { 646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mDeviceIdle == false) { 647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mDeviceActiveState); 648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande checkLocksAndTransitionWhenDeviceIdle(); 650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else if (mSettingsStore.isScanAlwaysAvailable()) { 652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mStaDisabledWithScanState); 653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mApStaDisabledState); 655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Parent: StaEnabledState */ 664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class DeviceActiveState extends State { 665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE); 668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setDriverStart(true); 669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setHighPerfModeEnabled(false); 670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (msg.what == CMD_DEVICE_IDLE) { 675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande checkLocksAndTransitionWhenDeviceIdle(); 676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // We let default state handle the rest of work 677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else if (msg.what == CMD_USER_PRESENT) { 678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // TLS networks can't connect until user unlocks keystore. KeyStore 679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // unlocks when the user punches PIN after the reboot. So use this 680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // trigger to get those networks connected. 681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mFirstUserSignOnSeen == false) { 682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.reloadTlsNetworksAndReconnect(); 683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mFirstUserSignOnSeen = true; 685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Parent: StaEnabledState */ 692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class DeviceInactiveState extends State { 693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message msg) { 695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (msg.what) { 696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_LOCKS_CHANGED: 697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande checkLocksAndTransitionWhenDeviceIdle(); 698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande updateBatteryWorkSource(); 699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case CMD_SCREEN_ON: 701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mDeviceActiveState); 702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // More work in default state 703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a scan only lock. */ 711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class ScanOnlyLockHeldState extends State { 712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE); 715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setDriverStart(true); 716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a full lock. */ 720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class FullLockHeldState extends State { 721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE); 724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setDriverStart(true); 725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setHighPerfModeEnabled(false); 726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a high perf lock. */ 730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class FullHighPerfLockHeldState extends State { 731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE); 734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setDriverStart(true); 735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setHighPerfModeEnabled(true); 736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Parent: DeviceInactiveState. Device is inactive and no app is holding a wifi lock. */ 740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class NoLockHeldState extends State { 741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mWifiStateMachine.setDriverStart(false); 744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void checkLocksAndTransitionWhenDeviceIdle() { 748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mLocks.hasLocks()) { 749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (mLocks.getStrongestLockMode()) { 750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WIFI_MODE_FULL: 751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mFullLockHeldState); 752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WIFI_MODE_FULL_HIGH_PERF: 754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mFullHighPerfLockHeldState); 755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WIFI_MODE_SCAN_ONLY: 757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mScanOnlyLockHeldState); 758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande loge("Illegal lock " + mLocks.getStrongestLockMode()); 761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mSettingsStore.isScanAlwaysAvailable()) { 764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mScanOnlyLockHeldState); 765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mNoLockHeldState); 767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande super.dump(fd, pw, args); 774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mScreenOff " + mScreenOff); 776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mDeviceIdle " + mDeviceIdle); 777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mPluggedType " + mPluggedType); 778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mIdleMillis " + mIdleMillis); 779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mSleepPolicy " + mSleepPolicy); 780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 782