WakeupController.java revision 9d60c0ff94757e8862f167f6de54789fe2e1bab2
1a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach/*
2a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * Copyright 2017 The Android Open Source Project
3a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach *
4a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * Licensed under the Apache License, Version 2.0 (the "License");
5a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * you may not use this file except in compliance with the License.
6a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * You may obtain a copy of the License at
7a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach *
8a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach *      http://www.apache.org/licenses/LICENSE-2.0
9a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach *
10a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * Unless required by applicable law or agreed to in writing, software
11a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * distributed under the License is distributed on an "AS IS" BASIS,
12a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * See the License for the specific language governing permissions and
14a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * limitations under the License.
15a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach */
16a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
17a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachpackage com.android.server.wifi;
18a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
19a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachimport android.content.Context;
20a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachimport android.database.ContentObserver;
21115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport android.net.wifi.ScanResult;
22115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport android.net.wifi.WifiConfiguration;
23115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport android.net.wifi.WifiScanner;
24a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachimport android.os.Handler;
25a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachimport android.os.Looper;
26a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachimport android.provider.Settings;
27b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbachimport android.util.ArraySet;
28115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport android.util.Log;
29a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
30a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachimport com.android.internal.annotations.VisibleForTesting;
31a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
3204263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbachimport java.io.FileDescriptor;
3304263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbachimport java.io.PrintWriter;
34b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbachimport java.util.Arrays;
35b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbachimport java.util.Collection;
36115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport java.util.HashSet;
37115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport java.util.List;
38115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbachimport java.util.Set;
39115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
4004263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach
41a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach/**
42a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * WakeupController is responsible managing Auto Wifi.
43a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach *
44a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach * <p>It determines if and when to re-enable wifi after it has been turned off by the user.
45a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach */
46a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbachpublic class WakeupController {
47a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
48115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    private static final String TAG = "WakeupController";
49115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
50b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    // TODO(b/69624403) flip to true when feature is complete
51a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    private static final boolean USE_PLATFORM_WIFI_WAKE = false;
52a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
53a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    private final Context mContext;
54a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    private final Handler mHandler;
55a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    private final FrameworkFacade mFrameworkFacade;
56a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    private final ContentObserver mContentObserver;
57a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    private final WakeupLock mWakeupLock;
58b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    private final WakeupEvaluator mWakeupEvaluator;
599d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach    private final WakeupOnboarding mWakeupOnboarding;
60a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    private final WifiConfigManager mWifiConfigManager;
61115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    private final WifiInjector mWifiInjector;
62115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
63115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    private final WifiScanner.ScanListener mScanListener = new WifiScanner.ScanListener() {
64115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        @Override
65115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        public void onPeriodChanged(int periodInMs) {
66115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            // no-op
67115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
68115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
69115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        @Override
70115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        public void onResults(WifiScanner.ScanData[] results) {
71b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            if (results.length == 1 && results[0].isAllChannelsScanned()) {
72b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach                handleScanResults(Arrays.asList(results[0].getResults()));
73b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            }
74115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
75115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
76115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        @Override
77115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        public void onFullResult(ScanResult fullScanResult) {
78115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            // no-op
79115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
80115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
81115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        @Override
82115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        public void onSuccess() {
83115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            // no-op
84115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
85115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
86115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        @Override
87115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        public void onFailure(int reason, String description) {
88115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            Log.e(TAG, "ScanListener onFailure: " + reason + ": " + description);
89115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
90115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    };
91a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
92a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    /** Whether this feature is enabled in Settings. */
93a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    private boolean mWifiWakeupEnabled;
94a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
95a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    /** Whether the WakeupController is currently active. */
96a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    private boolean mIsActive = false;
97a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach
98a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    public WakeupController(
99a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach            Context context,
100a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach            Looper looper,
101a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            WakeupLock wakeupLock,
102b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            WakeupEvaluator wakeupEvaluator,
1039d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach            WakeupOnboarding wakeupOnboarding,
104a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            WifiConfigManager wifiConfigManager,
105a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            WifiConfigStore wifiConfigStore,
106115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            WifiInjector wifiInjector,
107a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach            FrameworkFacade frameworkFacade) {
108a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        mContext = context;
109a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        mHandler = new Handler(looper);
110a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        mWakeupLock = wakeupLock;
111b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        mWakeupEvaluator = wakeupEvaluator;
1129d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        mWakeupOnboarding = wakeupOnboarding;
113a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        mWifiConfigManager = wifiConfigManager;
114a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        mFrameworkFacade = frameworkFacade;
115115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        mWifiInjector = wifiInjector;
116a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        mContentObserver = new ContentObserver(mHandler) {
117a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach            @Override
118a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach            public void onChange(boolean selfChange) {
119a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach                mWifiWakeupEnabled = mFrameworkFacade.getIntegerSetting(
120a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach                                mContext, Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
121a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach            }
122a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        };
123a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
124a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach                Settings.Global.WIFI_WAKEUP_ENABLED), true, mContentObserver);
125a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        mContentObserver.onChange(false /* selfChange */);
126a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach
127a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        // registering the store data here has the effect of reading the persisted value of the
128a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        // data sources after system boot finishes
1299d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        WakeupConfigStoreData wakeupConfigStoreData = new WakeupConfigStoreData(
1309d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach                new IsActiveDataSource(),
1319d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach                mWakeupOnboarding.getDataSource(),
1329d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach                mWakeupLock.getDataSource());
133a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        wifiConfigStore.registerStoreData(wakeupConfigStoreData);
134a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    }
135a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach
136a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    private void setActive(boolean isActive) {
137a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        if (mIsActive != isActive) {
138b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            Log.d(TAG, "Setting active to " + isActive);
139a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            mIsActive = isActive;
140a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            mWifiConfigManager.saveToStore(false /* forceWrite */);
141a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        }
142a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    }
143a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach
144a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    /**
145115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * Starts listening for incoming scans.
146115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     *
147115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * <p>Should only be called upon entering ScanMode. WakeupController registers its listener with
148115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * the WifiScanner. If the WakeupController is already active, then it returns early. Otherwise
149115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * it performs its initialization steps and sets {@link #mIsActive} to true.
150115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     */
151115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    public void start() {
152b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        Log.d(TAG, "start()");
153115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        mWifiInjector.getWifiScanner().registerScanListener(mScanListener);
154115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
155115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        // If already active, we don't want to re-initialize the lock, so return early.
156115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        if (mIsActive) {
157115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            return;
158115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
159115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        setActive(true);
160115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
161b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        if (isEnabled()) {
1629d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach            mWakeupOnboarding.maybeShowNotification();
163115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            mWakeupLock.initialize(getMostRecentSavedScanResults());
164115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
165115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    }
166115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
167115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    /**
168115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * Stops listening for scans.
169115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     *
170115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * <p>Should only be called upon leaving ScanMode. It deregisters the listener from
171115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     * WifiScanner.
172115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach     */
173115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    public void stop() {
174b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        Log.d(TAG, "stop()");
175115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        mWifiInjector.getWifiScanner().deregisterScanListener(mScanListener);
1769d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        mWakeupOnboarding.onStop();
177115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    }
178115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
179115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    /** Resets the WakeupController, setting {@link #mIsActive} to false. */
180115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    public void reset() {
181b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        Log.d(TAG, "reset()");
182115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        setActive(false);
183115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    }
184115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
185115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    /** Returns a list of saved networks from the last full scan. */
186115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    private Set<ScanResultMatchInfo> getMostRecentSavedScanResults() {
187115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        Set<ScanResultMatchInfo> goodSavedNetworks = getGoodSavedNetworks();
188115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
189115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        List<ScanResult> scanResults = mWifiInjector.getWifiScanner().getSingleScanResults();
190115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        Set<ScanResultMatchInfo> lastSeenNetworks = new HashSet<>(scanResults.size());
191115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        for (ScanResult scanResult : scanResults) {
192115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            lastSeenNetworks.add(ScanResultMatchInfo.fromScanResult(scanResult));
193115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
194115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
195115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        lastSeenNetworks.retainAll(goodSavedNetworks);
196115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        return lastSeenNetworks;
197115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    }
198115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
199115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    /** Returns a filtered list of saved networks from WifiConfigManager. */
200115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    private Set<ScanResultMatchInfo> getGoodSavedNetworks() {
201115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        List<WifiConfiguration> savedNetworks = mWifiConfigManager.getSavedNetworks();
202115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
203115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        Set<ScanResultMatchInfo> goodSavedNetworks = new HashSet<>(savedNetworks.size());
204115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        for (WifiConfiguration config : savedNetworks) {
205115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            if (isWideAreaNetwork(config)
206115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach                    || config.hasNoInternetAccess()
207115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach                    || config.noInternetAccessExpected
208115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach                    || !config.getNetworkSelectionStatus().getHasEverConnected()) {
209115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach                continue;
210115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            }
211115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach            goodSavedNetworks.add(ScanResultMatchInfo.fromWifiConfiguration(config));
212115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        }
213115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
214115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        Log.d(TAG, "getGoodSavedNetworks: " + goodSavedNetworks.size());
215115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        return goodSavedNetworks;
216115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    }
217115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
218115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    //TODO(b/69271702) implement WAN filtering
219115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    private boolean isWideAreaNetwork(WifiConfiguration wifiConfiguration) {
220115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach        return false;
221115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    }
222115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach
223115c8923f9cfee8052c03eb5c92359d4156a86b2Eric Schwarzenbach    /**
224b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach     * Handles incoming scan results.
225b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach     *
226b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach     * <p>The controller updates the WakeupLock with the incoming scan results. If WakeupLock is
227b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach     * empty, it evaluates scan results for a match with saved networks. If a match exists, it
228b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach     * enables wifi.
229a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach     *
230b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach     * @param scanResults The scan results with which to update the controller
231a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach     */
232b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    private void handleScanResults(Collection<ScanResult> scanResults) {
233b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        if (!isEnabled()) {
234b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            return;
235b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        }
236b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
2379d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        // need to show notification here in case user enables Wifi Wake when Wifi is off
2389d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        mWakeupOnboarding.maybeShowNotification();
2399d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        if (!mWakeupOnboarding.isOnboarded()) {
2409d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach            return;
2419d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach        }
2429d60c0ff94757e8862f167f6de54789fe2e1bab2Eric Schwarzenbach
243b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        // only update the wakeup lock if it's not already empty
244b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        if (!mWakeupLock.isEmpty()) {
245b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            Set<ScanResultMatchInfo> networks = new ArraySet<>();
246b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            for (ScanResult scanResult : scanResults) {
247b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach                networks.add(ScanResultMatchInfo.fromScanResult(scanResult));
248b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            }
249b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            mWakeupLock.update(networks);
250b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
251b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            // if wakeup lock is still not empty, return
252b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            if (!mWakeupLock.isEmpty()) {
253b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach                return;
254b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            }
255b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
256b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            Log.d(TAG, "WakeupLock emptied");
257b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        }
258b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
259b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        ScanResult network =
260b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach                mWakeupEvaluator.findViableNetwork(scanResults, getGoodSavedNetworks());
261b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
262b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        if (network != null) {
263b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            Log.d(TAG, "Found viable network: " + network.SSID);
264b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            enableWifi(network);
265b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        }
266b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    }
267b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
268b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    private void enableWifi(ScanResult scanResult) {
269b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        if (isEnabled() && USE_PLATFORM_WIFI_WAKE) {
270b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            //TODO(b/69055696) enable wifi (and update log statement) once path exists
271b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach            Log.d(TAG, "Enabling wifi not yet implemented. Network: " + scanResult.SSID);
272b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach        }
273b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    }
274b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach
275b6b9c915c200d71da56026d8c3aeec9c243a933aEric Schwarzenbach    /** Whether the feature is enabled in settings. */
276a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    @VisibleForTesting
277a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    boolean isEnabled() {
278a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach        return mWifiWakeupEnabled;
279a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach    }
280a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach
28104263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach    /** Dumps wakeup controller state. */
28204263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
28304263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach        pw.println("Dump of WakeupController");
28404263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach        pw.println("mWifiWakeupEnabled: " + mWifiWakeupEnabled);
28504263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach        pw.println("USE_PLATFORM_WIFI_WAKE: " + USE_PLATFORM_WIFI_WAKE);
28604263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach        pw.println("mIsActive: " + mIsActive);
28704263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach        mWakeupLock.dump(fd, pw, args);
28804263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach    }
28904263765dc4bb2a74722d69db56c5b42e7fb1bc9Eric Schwarzenbach
290a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    private class IsActiveDataSource implements WakeupConfigStoreData.DataSource<Boolean> {
291a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach
292a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        @Override
293a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        public Boolean getData() {
294a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            return mIsActive;
295a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        }
296a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach
297a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        @Override
298a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        public void setData(Boolean data) {
299a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach            mIsActive = data;
300a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach        }
301a57806da53f2eadcf12475892ae3a0e0e58d98cdEric Schwarzenbach    }
302a55e8d795bba5aa66f692cffa8fa28e3b4174546Eric Schwarzenbach}
303