WifiController.java revision c12783a90e08bd2e20eb75f68192fbf7bad80357
111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff/*
211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * Copyright (C) 2013 The Android Open Source Project
311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff *
411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License");
511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * you may not use this file except in compliance with the License.
611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * You may obtain a copy of the License at
711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff *
811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff *      http://www.apache.org/licenses/LICENSE-2.0
911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff *
1011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * Unless required by applicable law or agreed to in writing, software
1111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS,
1211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * See the License for the specific language governing permissions and
1411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff * limitations under the License.
1511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff */
1611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
1711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffpackage com.android.server.wifi;
1811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
1911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.app.AlarmManager;
2011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.app.PendingIntent;
2111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.content.BroadcastReceiver;
2211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.content.Context;
2311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.content.Intent;
2411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.content.IntentFilter;
2511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.database.ContentObserver;
2611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.net.ConnectivityManager;
2711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.net.NetworkInfo;
2811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.net.wifi.WifiConfiguration;
2911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.net.wifi.WifiManager;
3011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_MODE_FULL;
3111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_MODE_FULL_HIGH_PERF;
3211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_MODE_SCAN_ONLY;
3311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.net.wifi.WifiStateMachine;
3411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.os.Handler;
3511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.os.Looper;
3611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.os.Message;
37c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwaltimport android.os.SystemClock;
3811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.os.WorkSource;
3911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.provider.Settings;
4011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport android.util.Slog;
4111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
4211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport com.android.internal.util.Protocol;
4311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport com.android.internal.util.State;
4411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport com.android.internal.util.StateMachine;
4511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport com.android.server.wifi.WifiService.LockList;
4611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
4711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport java.io.FileDescriptor;
4811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffimport java.io.PrintWriter;
4911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
5011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriffclass WifiController extends StateMachine {
5111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private static final String TAG = "WifiController";
5211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private static final boolean DBG = false;
5311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private Context mContext;
5411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private boolean mScreenOff;
5511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private boolean mDeviceIdle;
5611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private int mPluggedType;
5711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private int mStayAwakeConditions;
5811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private long mIdleMillis;
5911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private int mSleepPolicy;
6011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
6111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private AlarmManager mAlarmManager;
6211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private PendingIntent mIdleIntent;
6311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private static final int IDLE_REQUEST = 0;
6411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
6511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
6611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * See {@link Settings.Global#WIFI_IDLE_MS}. This is the default value if a
6711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Settings.Global value is not present. This timeout value is chosen as
6811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * the approximate point at which the battery drain caused by Wi-Fi
6911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * being enabled but not active exceeds the battery drain caused by
7011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * re-establishing a connection to the mobile data network.
7111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
7211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private static final long DEFAULT_IDLE_MS = 15 * 60 * 1000; /* 15 minutes */
7311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
74c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt    /**
75c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt     * See {@link Settings.Global#WIFI_REENABLE_DELAY_MS}.  This is the default value if a
76c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt     * Settings.Global value is not present.  This is the minimum time after wifi is disabled
77c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt     * we'll act on an enable.  Enable requests received before this delay will be deferred.
78c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt     */
79c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt    private static final long DEFAULT_REENABLE_DELAY_MS = 500;
80c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
8111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    NetworkInfo mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", "");
8211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
8311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private static final String ACTION_DEVICE_IDLE =
8411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            "com.android.server.WifiManager.action.DEVICE_IDLE";
8511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
8611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* References to values tracked in WifiService */
8711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    final WifiStateMachine mWifiStateMachine;
8811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    final WifiSettingsStore mSettingsStore;
8911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    final LockList mLocks;
9011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
9111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
9211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Temporary for computing UIDS that are responsible for starting WIFI.
9311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Protected by mWifiStateTracker lock.
9411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
9511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private final WorkSource mTmpWorkSource = new WorkSource();
9611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
97c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt    private long mReEnableDelayMillis;
98c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
9911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private static final int BASE = Protocol.BASE_WIFI_CONTROLLER;
10011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
10111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_EMERGENCY_MODE_CHANGED     = BASE + 1;
10211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_SCREEN_ON                  = BASE + 2;
10311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_SCREEN_OFF                 = BASE + 3;
10411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_BATTERY_CHANGED            = BASE + 4;
10511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_DEVICE_IDLE                = BASE + 5;
10611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_LOCKS_CHANGED              = BASE + 6;
10711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_SCAN_ALWAYS_MODE_CHANGED   = BASE + 7;
10811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_WIFI_TOGGLED               = BASE + 8;
10911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_AIRPLANE_TOGGLED           = BASE + 9;
11011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    static final int CMD_SET_AP                     = BASE + 10;
111c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt    static final int CMD_DEFERRED_TOGGLE            = BASE + 11;
11211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
11311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private DefaultState mDefaultState = new DefaultState();
11411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private StaEnabledState mStaEnabledState = new StaEnabledState();
11511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private ApStaDisabledState mApStaDisabledState = new ApStaDisabledState();
11611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private StaDisabledWithScanState mStaDisabledWithScanState = new StaDisabledWithScanState();
11711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private ApEnabledState mApEnabledState = new ApEnabledState();
11811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private DeviceActiveState mDeviceActiveState = new DeviceActiveState();
11911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private DeviceInactiveState mDeviceInactiveState = new DeviceInactiveState();
12011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private ScanOnlyLockHeldState mScanOnlyLockHeldState = new ScanOnlyLockHeldState();
12111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private FullLockHeldState mFullLockHeldState = new FullLockHeldState();
12211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private FullHighPerfLockHeldState mFullHighPerfLockHeldState = new FullHighPerfLockHeldState();
12311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private NoLockHeldState mNoLockHeldState = new NoLockHeldState();
12411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private EcmState mEcmState = new EcmState();
12511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
12611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    WifiController(Context context, WifiService service, Looper looper) {
12711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        super(TAG, looper);
12811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mContext = context;
12911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mWifiStateMachine = service.mWifiStateMachine;
13011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mSettingsStore = service.mSettingsStore;
13111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mLocks = service.mLocks;
13211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
13311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
13411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
13511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);
13611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
13711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        addState(mDefaultState);
13811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            addState(mApStaDisabledState, mDefaultState);
13911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            addState(mStaEnabledState, mDefaultState);
14011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                addState(mDeviceActiveState, mStaEnabledState);
14111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                addState(mDeviceInactiveState, mStaEnabledState);
14211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    addState(mScanOnlyLockHeldState, mDeviceInactiveState);
14311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    addState(mFullLockHeldState, mDeviceInactiveState);
14411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    addState(mFullHighPerfLockHeldState, mDeviceInactiveState);
14511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    addState(mNoLockHeldState, mDeviceInactiveState);
14611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            addState(mStaDisabledWithScanState, mDefaultState);
14711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            addState(mApEnabledState, mDefaultState);
14811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            addState(mEcmState, mDefaultState);
14911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        setInitialState(mApStaDisabledState);
15011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        setLogRecSize(25);
15111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        setLogOnlyTransitions(true);
15211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
15311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        IntentFilter filter = new IntentFilter();
15411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        filter.addAction(ACTION_DEVICE_IDLE);
15511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
15611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mContext.registerReceiver(
15711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                new BroadcastReceiver() {
15811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    @Override
15911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    public void onReceive(Context context, Intent intent) {
16011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        String action = intent.getAction();
16111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        if (action.equals(ACTION_DEVICE_IDLE)) {
16211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            sendMessage(CMD_DEVICE_IDLE);
16311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
16411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
16511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                                    WifiManager.EXTRA_NETWORK_INFO);
16611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        }
16711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
16811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                },
16911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                new IntentFilter(filter));
17011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
17111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        initializeAndRegisterForSettingsChange(looper);
17211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
17311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
17411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void initializeAndRegisterForSettingsChange(Looper looper) {
17511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        Handler handler = new Handler(looper);
17611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        readStayAwakeConditions();
17711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        registerForStayAwakeModeChange(handler);
17811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        readWifiIdleTime();
17911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        registerForWifiIdleTimeChange(handler);
1809f2e83135c046ab475a101ae7c020d94db8f53d9Irfan Sheriff        readWifiSleepPolicy();
18111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        registerForWifiSleepPolicyChange(handler);
182c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        readWifiReEnableDelay();
18311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
18411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
18511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void readStayAwakeConditions() {
18611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mStayAwakeConditions = Settings.Global.getInt(mContext.getContentResolver(),
18711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
18811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
18911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
19011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void readWifiIdleTime() {
19111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mIdleMillis = Settings.Global.getLong(mContext.getContentResolver(),
19211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.WIFI_IDLE_MS, DEFAULT_IDLE_MS);
19311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
19411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
19511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void readWifiSleepPolicy() {
19611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mSleepPolicy = Settings.Global.getInt(mContext.getContentResolver(),
19711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.WIFI_SLEEP_POLICY,
19811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.WIFI_SLEEP_POLICY_NEVER);
19911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
20011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
201c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt    private void readWifiReEnableDelay() {
202c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        mReEnableDelayMillis = Settings.Global.getLong(mContext.getContentResolver(),
203c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                Settings.Global.WIFI_REENABLE_DELAY_MS, DEFAULT_REENABLE_DELAY_MS);
204c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt    }
205c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
20611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
20711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Observes settings changes to scan always mode.
20811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
20911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void registerForStayAwakeModeChange(Handler handler) {
21011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        ContentObserver contentObserver = new ContentObserver(handler) {
21111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            @Override
21211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            public void onChange(boolean selfChange) {
21311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                readStayAwakeConditions();
21411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
21511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        };
21611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
21711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mContext.getContentResolver().registerContentObserver(
21811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.getUriFor(Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
21911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                false, contentObserver);
22011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
22111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
22211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
22311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Observes settings changes to scan always mode.
22411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
22511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void registerForWifiIdleTimeChange(Handler handler) {
22611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        ContentObserver contentObserver = new ContentObserver(handler) {
22711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            @Override
22811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            public void onChange(boolean selfChange) {
22911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                readWifiIdleTime();
23011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
23111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        };
23211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
23311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mContext.getContentResolver().registerContentObserver(
23411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.getUriFor(Settings.Global.WIFI_IDLE_MS),
23511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                false, contentObserver);
23611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
23711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
23811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
23911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Observes changes to wifi sleep policy
24011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
24111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void registerForWifiSleepPolicyChange(Handler handler) {
24211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        ContentObserver contentObserver = new ContentObserver(handler) {
24311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            @Override
24411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            public void onChange(boolean selfChange) {
24511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                readWifiSleepPolicy();
24611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
24711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        };
24811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mContext.getContentResolver().registerContentObserver(
24911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                Settings.Global.getUriFor(Settings.Global.WIFI_SLEEP_POLICY),
25011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                false, contentObserver);
25111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
25211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
25311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
25411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Determines whether the Wi-Fi chipset should stay awake or be put to
25511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * sleep. Looks at the setting for the sleep policy and the current
25611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * conditions.
25711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     *
25811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * @see #shouldDeviceStayAwake(int)
25911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
26011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private boolean shouldWifiStayAwake(int pluggedType) {
26111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        if (mSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER) {
26211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            // Never sleep
26311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return true;
26411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        } else if ((mSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED) &&
26511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                (pluggedType != 0)) {
26611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            // Never sleep while plugged, and we're plugged
26711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return true;
26811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        } else {
26911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            // Default
27011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return shouldDeviceStayAwake(pluggedType);
27111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
27211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
27311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
27411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /**
27511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * Determine whether the bit value corresponding to {@code pluggedType} is set in
27611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * the bit string mStayAwakeConditions. This determines whether the device should
27711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * stay awake based on the current plugged type.
27811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     *
27911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * @param pluggedType the type of plug (USB, AC, or none) for which the check is
28011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * being made
28111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * @return {@code true} if {@code pluggedType} indicates that the device is
28211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     * supposed to stay awake, {@code false} otherwise.
28311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff     */
28411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private boolean shouldDeviceStayAwake(int pluggedType) {
28511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        return (mStayAwakeConditions & pluggedType) != 0;
28611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
28711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
28811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void updateBatteryWorkSource() {
28911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mTmpWorkSource.clear();
29011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        if (mDeviceIdle) {
29111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mLocks.updateWorkSource(mTmpWorkSource);
29211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
29311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        mWifiStateMachine.updateBatteryWorkSource(mTmpWorkSource);
29411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
29511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
29611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class DefaultState extends State {
29711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
29811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
29911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (msg.what) {
30011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SCREEN_ON:
30111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    mAlarmManager.cancel(mIdleIntent);
30211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    mScreenOff = false;
30311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    mDeviceIdle = false;
30411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    updateBatteryWorkSource();
30511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
30611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SCREEN_OFF:
30711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    mScreenOff = true;
30811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    /*
30911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * Set a timer to put Wi-Fi to sleep, but only if the screen is off
31011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * AND the "stay on while plugged in" setting doesn't match the
31111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * current power conditions (i.e, not plugged in, plugged in to USB,
31211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * or plugged in to AC).
31311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    */
31411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (!shouldWifiStayAwake(mPluggedType)) {
31511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        //Delayed shutdown if wifi is connected
31611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        if (mNetworkInfo.getDetailedState() ==
31711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                                NetworkInfo.DetailedState.CONNECTED) {
31811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            if (DBG) Slog.d(TAG, "set idle timer: " + mIdleMillis + " ms");
31911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            mAlarmManager.set(AlarmManager.RTC_WAKEUP,
32011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                                    System.currentTimeMillis() + mIdleMillis, mIdleIntent);
32111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        } else {
32211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            sendMessage(CMD_DEVICE_IDLE);
32311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        }
32411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
32511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
32611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_DEVICE_IDLE:
32711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    mDeviceIdle = true;
32811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    updateBatteryWorkSource();
32911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
33011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_BATTERY_CHANGED:
33111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    /*
33211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * Set a timer to put Wi-Fi to sleep, but only if the screen is off
33311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * AND we are transitioning from a state in which the device was supposed
33411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * to stay awake to a state in which it is not supposed to stay awake.
33511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * If "stay awake" state is not changing, we do nothing, to avoid resetting
33611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * the already-set timer.
33711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    */
33811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    int pluggedType = msg.arg1;
33911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (DBG) Slog.d(TAG, "battery changed pluggedType: " + pluggedType);
34011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mScreenOff && shouldWifiStayAwake(mPluggedType) &&
34111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            !shouldWifiStayAwake(pluggedType)) {
34211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        long triggerTime = System.currentTimeMillis() + mIdleMillis;
34311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        if (DBG) Slog.d(TAG, "set idle timer for " + mIdleMillis + "ms");
34411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
34511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
34611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
34711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    mPluggedType = pluggedType;
34811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
34911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SET_AP:
35011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SCAN_ALWAYS_MODE_CHANGED:
35111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_LOCKS_CHANGED:
35211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_WIFI_TOGGLED:
35311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_AIRPLANE_TOGGLED:
35411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_EMERGENCY_MODE_CHANGED:
355c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                case CMD_DEFERRED_TOGGLE:
35611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
35711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
35811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    throw new RuntimeException("WifiController.handleMessage " + msg.what);
35911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
36011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return HANDLED;
36111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
36211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
36311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
36411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
36511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class ApStaDisabledState extends State {
366c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private int mDeferredEnableSerialNumber = 0;
367c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private boolean mHaveDeferredEnable = false;
368c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private long mDisabledTimestamp;
369c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
37011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
37111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
37211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setSupplicantRunning(false);
373c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            // Supplicant can't restart right away, so not the time we switched off
374c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            mDisabledTimestamp = SystemClock.elapsedRealtime();
375c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            mDeferredEnableSerialNumber++;
376c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            mHaveDeferredEnable = false;
37711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
37811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
37911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
38011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (msg.what) {
38111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_WIFI_TOGGLED:
38211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_AIRPLANE_TOGGLED:
38311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mSettingsStore.isWifiToggleEnabled()) {
384c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                        if (doDeferEnable(msg)) {
385c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            if (mHaveDeferredEnable) {
386c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                                //  have 2 toggles now, inc serial number an ignore both
387c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                                mDeferredEnableSerialNumber++;
388c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            }
389c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            mHaveDeferredEnable = !mHaveDeferredEnable;
390c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            break;
391c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                        }
39211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        if (mDeviceIdle == false) {
39311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            transitionTo(mDeviceActiveState);
39411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        } else {
39511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            checkLocksAndTransitionWhenDeviceIdle();
39611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        }
39711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
39811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
39911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SCAN_ALWAYS_MODE_CHANGED:
40011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mSettingsStore.isScanAlwaysAvailable()) {
40111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mStaDisabledWithScanState);
40211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
40311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
40411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SET_AP:
40511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (msg.arg1 == 1) {
40611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        mWifiStateMachine.setHostApRunning((WifiConfiguration) msg.obj,
40711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                                true);
40811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApEnabledState);
40911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
41011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
411c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                case CMD_DEFERRED_TOGGLE:
412c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                    if (msg.arg1 != mDeferredEnableSerialNumber) break;
413c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                    sendMessage((Message)(msg.obj));
414c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                    break;
41511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
41611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return NOT_HANDLED;
41711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
41811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return HANDLED;
41911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
42011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
421c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private boolean doDeferEnable(Message msg) {
422c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
423c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            if (delaySoFar > mReEnableDelayMillis) {
424c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                return false;
425c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            }
426c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
427c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            // need to defer this action.
428c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
429c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            deferredMsg.obj = Message.obtain(msg);
430c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
431c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar);
432c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            return true;
433c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        }
434c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
43511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
43611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
43711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class StaEnabledState extends State {
43811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
43911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
44011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setSupplicantRunning(true);
44111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
44211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
44311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
44411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (msg.what) {
44511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_WIFI_TOGGLED:
44611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (! mSettingsStore.isWifiToggleEnabled()) {
44711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        if (mSettingsStore.isScanAlwaysAvailable()) {
44811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            transitionTo(mStaDisabledWithScanState);
44911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        } else {
45011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            transitionTo(mApStaDisabledState);
45111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        }
45211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
45311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
45411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_AIRPLANE_TOGGLED:
45511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    /* When wi-fi is turned off due to airplane,
45611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    * disable entirely (including scan)
45711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    */
45811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (! mSettingsStore.isWifiToggleEnabled()) {
45911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApStaDisabledState);
46011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
46111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
46211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_EMERGENCY_MODE_CHANGED:
46311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (msg.arg1 == 1) {
46411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mEcmState);
46511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        break;
46611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
46711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
46811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return NOT_HANDLED;
46911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
47011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
47111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return HANDLED;
47211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
47311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
47411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
47511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class StaDisabledWithScanState extends State {
476c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private int mDeferredEnableSerialNumber = 0;
477c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private boolean mHaveDeferredEnable = false;
478c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private long mDisabledTimestamp;
479c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
48011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
48111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
48211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setSupplicantRunning(true);
48311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE);
48411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setDriverStart(true);
485c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            // Supplicant can't restart right away, so not the time we switched off
486c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            mDisabledTimestamp = SystemClock.elapsedRealtime();
487c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            mDeferredEnableSerialNumber++;
488c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            mHaveDeferredEnable = false;
48911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
49011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
49111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
49211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
49311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (msg.what) {
49411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_WIFI_TOGGLED:
49511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mSettingsStore.isWifiToggleEnabled()) {
496c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                        if (doDeferEnable(msg)) {
497c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            if (mHaveDeferredEnable) {
498c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                                // have 2 toggles now, inc serial number and ignore both
499c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                                mDeferredEnableSerialNumber++;
500c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            }
501c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            mHaveDeferredEnable = !mHaveDeferredEnable;
502c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                            break;
503c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                        }
50411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        if (mDeviceIdle == false) {
50511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            transitionTo(mDeviceActiveState);
50611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        } else {
50711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            checkLocksAndTransitionWhenDeviceIdle();
50811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        }
50911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
51011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
51111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_AIRPLANE_TOGGLED:
51211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mSettingsStore.isAirplaneModeOn() &&
51311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                            ! mSettingsStore.isWifiToggleEnabled()) {
51411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApStaDisabledState);
51511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
51611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SCAN_ALWAYS_MODE_CHANGED:
51711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (! mSettingsStore.isScanAlwaysAvailable()) {
51811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApStaDisabledState);
51911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
52011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
52111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SET_AP:
52211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    // Before starting tethering, turn off supplicant for scan mode
52311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (msg.arg1 == 1) {
52411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        deferMessage(msg);
52511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApStaDisabledState);
52611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
52711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
528c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                case CMD_DEFERRED_TOGGLE:
529c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                    if (msg.arg1 != mDeferredEnableSerialNumber) break;
530c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                    sendMessage((Message)(msg.obj));
531c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                    break;
53211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
53311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return NOT_HANDLED;
53411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
53511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return HANDLED;
53611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
537c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
538c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        private boolean doDeferEnable(Message msg) {
539c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
540c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            if (delaySoFar > mReEnableDelayMillis) {
541c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt                return false;
542c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            }
543c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            // need to defer this action.
544c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
545c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            deferredMsg.obj = Message.obtain(msg);
546c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
547c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar);
548c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt            return true;
549c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt        }
550c12783a90e08bd2e20eb75f68192fbf7bad80357Robert Greenwalt
55111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
55211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
55311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class ApEnabledState extends State {
55411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
55511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
55611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (msg.what) {
55711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_AIRPLANE_TOGGLED:
55811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mSettingsStore.isAirplaneModeOn()) {
55911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        mWifiStateMachine.setHostApRunning(null, false);
56011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApStaDisabledState);
56111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
56211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
56311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SET_AP:
56411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (msg.arg1 == 0) {
56511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        mWifiStateMachine.setHostApRunning(null, false);
56611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mApStaDisabledState);
56711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
56811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
56911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
57011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return NOT_HANDLED;
57111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
57211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return HANDLED;
57311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
57411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
57511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
57611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class EcmState extends State {
57711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
57811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
57911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setSupplicantRunning(false);
58011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
58111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
58211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
58311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
58411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            if (msg.what == CMD_EMERGENCY_MODE_CHANGED && msg.arg1 == 0) {
58511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                if (mSettingsStore.isWifiToggleEnabled()) {
58611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    if (mDeviceIdle == false) {
58711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        transitionTo(mDeviceActiveState);
58811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    } else {
58911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                        checkLocksAndTransitionWhenDeviceIdle();
59011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    }
59111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                } else if (mSettingsStore.isScanAlwaysAvailable()) {
59211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    transitionTo(mStaDisabledWithScanState);
59311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                } else {
59411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    transitionTo(mApStaDisabledState);
59511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                }
59611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                return HANDLED;
59711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            } else {
59811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                return NOT_HANDLED;
59911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
60011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
60111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
60211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
60311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* Parent: StaEnabledState */
60411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class DeviceActiveState extends State {
60511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
60611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
60711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
60811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setDriverStart(true);
60911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setHighPerfModeEnabled(false);
61011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
61111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
61211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
61311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
61411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            if (msg.what == CMD_DEVICE_IDLE) {
61511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                checkLocksAndTransitionWhenDeviceIdle();
61611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                // We let default state handle the rest of work
61711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
61811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            return NOT_HANDLED;
61911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
62011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
62111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
62211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* Parent: StaEnabledState */
62311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class DeviceInactiveState extends State {
62411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
62511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public boolean processMessage(Message msg) {
62611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (msg.what) {
62711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_LOCKS_CHANGED:
62811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    checkLocksAndTransitionWhenDeviceIdle();
62911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    updateBatteryWorkSource();
63011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return HANDLED;
63111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case CMD_SCREEN_ON:
63211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    transitionTo(mDeviceActiveState);
63311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    // More work in default state
63411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return NOT_HANDLED;
63511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
63611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    return NOT_HANDLED;
63711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
63811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
63911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
64011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
64111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a scan only lock. */
64211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class ScanOnlyLockHeldState extends State {
64311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
64411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
64511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE);
64611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setDriverStart(true);
64711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
64811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
64911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
65011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a full lock. */
65111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class FullLockHeldState extends State {
65211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
65311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
65411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
65511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setDriverStart(true);
65611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setHighPerfModeEnabled(false);
65711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
65811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
65911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
66011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a high perf lock. */
66111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class FullHighPerfLockHeldState extends State {
66211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
66311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
66411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
66511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setDriverStart(true);
66611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setHighPerfModeEnabled(true);
66711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
66811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
66911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
67011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    /* Parent: DeviceInactiveState. Device is inactive and no app is holding a wifi lock. */
67111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    class NoLockHeldState extends State {
67211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        @Override
67311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        public void enter() {
67411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            mWifiStateMachine.setDriverStart(false);
67511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
67611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
67711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
67811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    private void checkLocksAndTransitionWhenDeviceIdle() {
67911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        if (mLocks.hasLocks()) {
68011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            switch (mLocks.getStrongestLockMode()) {
68111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case WIFI_MODE_FULL:
68211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    transitionTo(mFullLockHeldState);
68311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
68411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case WIFI_MODE_FULL_HIGH_PERF:
68511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    transitionTo(mFullHighPerfLockHeldState);
68611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
68711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                case WIFI_MODE_SCAN_ONLY:
68811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    transitionTo(mScanOnlyLockHeldState);
68911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    break;
69011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                default:
69111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                    loge("Illegal lock " + mLocks.getStrongestLockMode());
69211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
69311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        } else {
69411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            if (mSettingsStore.isScanAlwaysAvailable()) {
69511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                transitionTo(mScanOnlyLockHeldState);
69611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            } else {
69711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff                transitionTo(mNoLockHeldState);
69811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff            }
69911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        }
70011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
70111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
70211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    @Override
70311aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
70411aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        super.dump(fd, pw, args);
70511aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff
70611aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        pw.println("mScreenOff " + mScreenOff);
70711aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        pw.println("mDeviceIdle " + mDeviceIdle);
70811aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        pw.println("mPluggedType " + mPluggedType);
70911aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        pw.println("mIdleMillis " + mIdleMillis);
71011aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff        pw.println("mSleepPolicy " + mSleepPolicy);
71111aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff    }
71211aefad94de6569c4c7394e7bc5fdeb0ae60d5bbIrfan Sheriff}
713