1e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde/* 2e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * Copyright (C) 2008 The Android Open Source Project 3e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * 4e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * Licensed under the Apache License, Version 2.0 (the "License"); 5e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * you may not use this file except in compliance with the License. 6e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * You may obtain a copy of the License at 7e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * 8e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * http://www.apache.org/licenses/LICENSE-2.0 9e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * 10e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * Unless required by applicable law or agreed to in writing, software 11e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * distributed under the License is distributed on an "AS IS" BASIS, 12e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * See the License for the specific language governing permissions and 14e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde * limitations under the License. 15e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde */ 16e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 17a8367288377cbaed6371256ca837b7aa22280706Mitchell Willspackage com.android.server.wifi.scanner; 18e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 19ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpandeimport android.Manifest; 20e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.app.AlarmManager; 21e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.app.PendingIntent; 22e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.content.BroadcastReceiver; 23e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.content.Context; 24e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.content.Intent; 25e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.content.IntentFilter; 26cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashmanimport android.content.pm.PackageManager; 27e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.IWifiScanner; 28e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.ScanResult; 29e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.WifiManager; 30e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.WifiScanner; 31bb6942c6b6d129fd8904e341c9ce4a4118ed3e0bVinit Deshpandeimport android.net.wifi.WifiScanner.BssidInfo; 32bb6942c6b6d129fd8904e341c9ce4a4118ed3e0bVinit Deshpandeimport android.net.wifi.WifiScanner.ChannelSpec; 339153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Piusimport android.net.wifi.WifiScanner.PnoSettings; 34bb6942c6b6d129fd8904e341c9ce4a4118ed3e0bVinit Deshpandeimport android.net.wifi.WifiScanner.ScanData; 35e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.WifiScanner.ScanSettings; 36cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashmanimport android.os.Binder; 37efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpandeimport android.os.Bundle; 38e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.os.Handler; 39e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.os.Looper; 40e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.os.Message; 41e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.os.Messenger; 42e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.os.RemoteException; 43fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpandeimport android.os.WorkSource; 44297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.util.ArrayMap; 45d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpandeimport android.util.LocalLog; 46e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.util.Log; 478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Willsimport android.util.Pair; 48e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 49fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpandeimport com.android.internal.app.IBatteryStats; 50e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport com.android.internal.util.AsyncChannel; 51e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport com.android.internal.util.Protocol; 52e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport com.android.internal.util.State; 539ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport com.android.internal.util.StateMachine; 54ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Piusimport com.android.server.wifi.Clock; 55a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiInjector; 56a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiMetrics; 57a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiMetricsProto; 58a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiNative; 59a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiStateMachine; 608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Willsimport com.android.server.wifi.scanner.ChannelHelper.ChannelCollection; 61fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 62e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.io.FileDescriptor; 63e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.io.PrintWriter; 64e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.util.ArrayList; 65e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.util.Collection; 66e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.util.HashMap; 67e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.util.HashSet; 68e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport java.util.Iterator; 6919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Piusimport java.util.Set; 70e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 71e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndepublic class WifiScanningServiceImpl extends IWifiScanner.Stub { 72e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 73297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills private static final String TAG = WifiScanningService.TAG; 7484e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande private static final boolean DBG = false; 75716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe 7612836d34cc6c4497c1fa5adbb956684ecec7578eVinit Deshpande private static final int MIN_PERIOD_PER_CHANNEL_MS = 200; // DFS needs 120 ms 77ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande private static final int UNKNOWN_PID = -1; 78e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 791e911c92133843fc0a50a1b1c6f654f62e7c98a8Randy Pan private final LocalLog mLocalLog = new LocalLog(512); 80d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande 81d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills private void localLog(String message) { 82d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande mLocalLog.log(message); 83d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande } 84d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande 85d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills private void logw(String message) { 86d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande Log.w(TAG, message); 87d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande mLocalLog.log(message); 88d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande } 89d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande 90d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills private void loge(String message) { 91d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande Log.e(TAG, message); 92d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande mLocalLog.log(message); 93d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande } 94d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande 959ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private WifiScannerImpl mScannerImpl; 969ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 97e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 98e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public Messenger getMessenger() { 99dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (mClientHandler != null) { 100dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle return new Messenger(mClientHandler); 101dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } else { 102d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande loge("WifiScanningServiceImpl trying to get messenger w/o initialization"); 103dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle return null; 104dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 105e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 106e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 107efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande @Override 108efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande public Bundle getAvailableChannels(int band) { 109e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills mChannelHelper.updateChannels(); 1107e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills ChannelSpec[] channelSpecs = mChannelHelper.getAvailableScanChannels(band); 111efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande ArrayList<Integer> list = new ArrayList<Integer>(channelSpecs.length); 112bb6942c6b6d129fd8904e341c9ce4a4118ed3e0bVinit Deshpande for (ChannelSpec channelSpec : channelSpecs) { 113efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande list.add(channelSpec.frequency); 114efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande } 115efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande Bundle b = new Bundle(); 116efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande b.putIntegerArrayList(WifiScanner.GET_AVAILABLE_CHANNELS_EXTRA, list); 117efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande return b; 118efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande } 119efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande 120ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande private void enforceLocationHardwarePermission(int uid) { 121ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande mContext.enforcePermission( 122ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande Manifest.permission.LOCATION_HARDWARE, 123ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande UNKNOWN_PID, uid, 124ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande "LocationHardware"); 12546d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande } 12646d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande 127e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private class ClientHandler extends Handler { 128e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 129297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills ClientHandler(Looper looper) { 130e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde super(looper); 131e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 132e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 133e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 134e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public void handleMessage(Message msg) { 135e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde switch (msg.what) { 136297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { 137a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ExternalClientInfo client = (ExternalClientInfo) mClients.get(msg.replyTo); 138297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (client != null) { 1399e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills logw("duplicate client connection: " + msg.sendingUid + ", messenger=" 1409e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills + msg.replyTo); 141297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills client.mChannel.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, 142297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED); 143297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return; 144e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 145297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 146fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande AsyncChannel ac = new AsyncChannel(); 147297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills ac.connected(mContext, this, msg.replyTo); 148297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 149a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius client = new ExternalClientInfo(msg.sendingUid, msg.replyTo, ac); 150a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius client.register(); 151297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 152297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, 153297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills AsyncChannel.STATUS_SUCCESSFUL); 154297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 1559e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills localLog("client connected: " + client); 156fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande return; 157297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 158297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case AsyncChannel.CMD_CHANNEL_DISCONNECT: { 159a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ExternalClientInfo client = (ExternalClientInfo) mClients.get(msg.replyTo); 160297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (client != null) { 161297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills client.mChannel.disconnect(); 162e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 163297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return; 164297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 165297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 166a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ExternalClientInfo client = (ExternalClientInfo) mClients.get(msg.replyTo); 167d76a14997a969ea44daa47756dcc8f83aee96935Mitchell Wills if (client != null && msg.arg1 != AsyncChannel.STATUS_SEND_UNSUCCESSFUL 168d76a14997a969ea44daa47756dcc8f83aee96935Mitchell Wills && msg.arg1 169d76a14997a969ea44daa47756dcc8f83aee96935Mitchell Wills != AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED) { 1709e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills localLog("client disconnected: " + client + ", reason: " + msg.arg1); 171a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius client.cleanup(); 17228c7065e2af36064a230d2647782c5cdadaff2d8Vinit Deshpande } 173e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return; 174297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 175e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 176e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 17746d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande try { 178ed3f1ddf197602340e675ae4357cd0fbb145f078Vinit Deshpande enforceLocationHardwarePermission(msg.sendingUid); 17946d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande } catch (SecurityException e) { 180716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe localLog("failed to authorize app: " + e); 18146d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande replyFailed(msg, WifiScanner.REASON_NOT_AUTHORIZED, "Not authorized"); 18246d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande return; 18346d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande } 18446d6b0ac6d466002e868627488796ce3d6a154aaVinit Deshpande 185a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // Since this message is sent from WifiScanner using |sendMessageSynchronously| which 186a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // doesn't set the correct |msg.replyTo| field. 18714aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann if (msg.what == WifiScanner.CMD_GET_SCAN_RESULTS) { 1888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mBackgroundScanStateMachine.sendMessage(Message.obtain(msg)); 18914aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann return; 19014aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann } 191a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 19214aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann ClientInfo ci = mClients.get(msg.replyTo); 19314aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann if (ci == null) { 194d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande loge("Could not find client info for message " + msg.replyTo); 19514aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann replyFailed(msg, WifiScanner.REASON_INVALID_LISTENER, "Could not find listener"); 19614aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann return; 19714aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann } 19814aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann 19994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills switch (msg.what) { 20094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills case WifiScanner.CMD_START_BACKGROUND_SCAN: 20194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills case WifiScanner.CMD_STOP_BACKGROUND_SCAN: 20294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills case WifiScanner.CMD_SET_HOTLIST: 20394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills case WifiScanner.CMD_RESET_HOTLIST: 2048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mBackgroundScanStateMachine.sendMessage(Message.obtain(msg)); 2058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills break; 206c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_START_PNO_SCAN: 207c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_STOP_PNO_SCAN: 208c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mPnoScanStateMachine.sendMessage(Message.obtain(msg)); 209c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 21094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills case WifiScanner.CMD_START_SINGLE_SCAN: 21194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills case WifiScanner.CMD_STOP_SINGLE_SCAN: 2128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mSingleScanStateMachine.sendMessage(Message.obtain(msg)); 2138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills break; 21419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: 21519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_START_TRACKING_CHANGE: 21619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_STOP_TRACKING_CHANGE: 21719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mWifiChangeStateMachine.sendMessage(Message.obtain(msg)); 21819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius break; 2191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills case WifiScanner.CMD_REGISTER_SCAN_LISTENER: 2201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills logScanRequest("registerScanListener", ci, msg.arg2, null, null, null); 2211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills mSingleScanListeners.addRequest(ci, msg.arg2, null, null); 2221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills replySucceeded(msg); 2231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills break; 2241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills case WifiScanner.CMD_DEREGISTER_SCAN_LISTENER: 2251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills logScanRequest("deregisterScanListener", ci, msg.arg2, null, null, null); 2261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills mSingleScanListeners.removeRequest(ci, msg.arg2); 2271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills break; 22894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills default: 22994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "Invalid request"); 2308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills break; 231e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 232e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 233e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 234e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 235e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private static final int BASE = Protocol.BASE_WIFI_SCANNER_SERVICE; 236e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 237e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private static final int CMD_SCAN_RESULTS_AVAILABLE = BASE + 0; 238e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private static final int CMD_FULL_SCAN_RESULTS = BASE + 1; 239e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private static final int CMD_HOTLIST_AP_FOUND = BASE + 2; 240e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private static final int CMD_HOTLIST_AP_LOST = BASE + 3; 241578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills private static final int CMD_WIFI_CHANGE_DETECTED = BASE + 4; 242a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_WIFI_CHANGE_TIMEOUT = BASE + 5; 243a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_DRIVER_LOADED = BASE + 6; 244a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_DRIVER_UNLOADED = BASE + 7; 245a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_SCAN_PAUSED = BASE + 8; 246a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_SCAN_RESTARTED = BASE + 9; 247a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_SCAN_FAILED = BASE + 10; 248a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_PNO_NETWORK_FOUND = BASE + 11; 249a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int CMD_PNO_SCAN_FAILED = BASE + 12; 250e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 25118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills private final Context mContext; 25294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills private final Looper mLooper; 25394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills private final WifiScannerImpl.WifiScannerImplFactory mScannerImplFactory; 254297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills private final ArrayMap<Messenger, ClientInfo> mClients; 255297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 2561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills private final RequestList<Void> mSingleScanListeners = new RequestList<>(); 2571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills 2587e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills private ChannelHelper mChannelHelper; 259985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills private BackgroundScanScheduler mBackgroundScheduler; 260297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills private WifiNative.ScanSettings mPreviousSchedule; 261297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 2628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private WifiBackgroundScanStateMachine mBackgroundScanStateMachine; 2638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private WifiSingleScanStateMachine mSingleScanStateMachine; 26419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private WifiChangeStateMachine mWifiChangeStateMachine; 265c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private WifiPnoScanStateMachine mPnoScanStateMachine; 266e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private ClientHandler mClientHandler; 267297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills private final IBatteryStats mBatteryStats; 2688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private final AlarmManager mAlarmManager; 269ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius private final WifiMetrics mWifiMetrics; 270ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius private final Clock mClock; 271e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 27294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills WifiScanningServiceImpl(Context context, Looper looper, 273c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiScannerImpl.WifiScannerImplFactory scannerImplFactory, IBatteryStats batteryStats, 274c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiInjector wifiInjector) { 275e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mContext = context; 27694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills mLooper = looper; 27794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills mScannerImplFactory = scannerImplFactory; 27894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills mBatteryStats = batteryStats; 279297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills mClients = new ArrayMap<>(); 2808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 281c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics = wifiInjector.getWifiMetrics(); 282ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius mClock = wifiInjector.getClock(); 283297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 284297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills mPreviousSchedule = null; 285e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 286e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 28718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills public void startService() { 28894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills mClientHandler = new ClientHandler(mLooper); 2898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mBackgroundScanStateMachine = new WifiBackgroundScanStateMachine(mLooper); 29094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills mWifiChangeStateMachine = new WifiChangeStateMachine(mLooper); 2918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mSingleScanStateMachine = new WifiSingleScanStateMachine(mLooper); 292c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mPnoScanStateMachine = new WifiPnoScanStateMachine(mLooper); 293e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 294e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mContext.registerReceiver( 295e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde new BroadcastReceiver() { 296e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 297e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public void onReceive(Context context, Intent intent) { 298e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde int state = intent.getIntExtra( 299e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED); 300716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe if (DBG) localLog("SCAN_AVAILABLE : " + state); 301e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (state == WifiManager.WIFI_STATE_ENABLED) { 3028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mBackgroundScanStateMachine.sendMessage(CMD_DRIVER_LOADED); 3038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mSingleScanStateMachine.sendMessage(CMD_DRIVER_LOADED); 304c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mPnoScanStateMachine.sendMessage(CMD_DRIVER_LOADED); 305e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } else if (state == WifiManager.WIFI_STATE_DISABLED) { 3068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mBackgroundScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED); 3078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mSingleScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED); 308c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mPnoScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED); 309e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 310e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 311e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde }, new IntentFilter(WifiManager.WIFI_SCAN_AVAILABLE)); 312e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 3138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mBackgroundScanStateMachine.start(); 314578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mWifiChangeStateMachine.start(); 3158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mSingleScanStateMachine.start(); 316c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mPnoScanStateMachine.start(); 317e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 318e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 31944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills private static boolean isWorkSourceValid(WorkSource workSource) { 32044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills return workSource != null && workSource.size() > 0 && workSource.get(0) >= 0; 32144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 32244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 323d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills private WorkSource computeWorkSource(ClientInfo ci, WorkSource requestedWorkSource) { 32444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (requestedWorkSource != null) { 32544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (isWorkSourceValid(requestedWorkSource)) { 32648444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills // Wifi currently doesn't use names, so need to clear names out of the 32748444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills // supplied WorkSource to allow future WorkSource combining. 32848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills requestedWorkSource.clearNames(); 32944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills return requestedWorkSource; 33044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } else { 33144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills loge("Got invalid work source request: " + requestedWorkSource.toString() + 33244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills " from " + ci); 33344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 33444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 33544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills WorkSource callingWorkSource = new WorkSource(ci.getUid()); 33644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (isWorkSourceValid(callingWorkSource)) { 33744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills return callingWorkSource; 33844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } else { 33944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills loge("Client has invalid work source: " + callingWorkSource); 34044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills return new WorkSource(); 34144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 34244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 34344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 344d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills private class RequestInfo<T> { 34544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills final ClientInfo clientInfo; 34644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills final int handlerId; 34744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills final WorkSource workSource; 34844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills final T settings; 34944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 35044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills RequestInfo(ClientInfo clientInfo, int handlerId, WorkSource requestedWorkSource, 35144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills T settings) { 35244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills this.clientInfo = clientInfo; 35344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills this.handlerId = handlerId; 35444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills this.settings = settings; 35544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills this.workSource = computeWorkSource(clientInfo, requestedWorkSource); 35644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 35744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 35844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills void reportEvent(int what, int arg1, Object obj) { 35944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills clientInfo.reportEvent(what, arg1, handlerId, obj); 36044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 36144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 36244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 363d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills private class RequestList<T> extends ArrayList<RequestInfo<T>> { 364f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius void addRequest(ClientInfo ci, int handler, WorkSource reqworkSource, T settings) { 365f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius add(new RequestInfo<T>(ci, handler, reqworkSource, settings)); 366f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 367f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius 368f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius T removeRequest(ClientInfo ci, int handlerId) { 369f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius T removed = null; 37044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills Iterator<RequestInfo<T>> iter = iterator(); 37144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills while (iter.hasNext()) { 37244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills RequestInfo<T> entry = iter.next(); 37344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (entry.clientInfo == ci && entry.handlerId == handlerId) { 374f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius removed = entry.settings; 37544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills iter.remove(); 37644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 37744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 378f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius return removed; 379f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 380f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius 381f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Collection<T> getAllSettings() { 382f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ArrayList<T> settingsList = new ArrayList<>(); 383f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Iterator<RequestInfo<T>> iter = iterator(); 384f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius while (iter.hasNext()) { 385f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius RequestInfo<T> entry = iter.next(); 386f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius settingsList.add(entry.settings); 387f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 388f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius return settingsList; 389f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 390f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius 391f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Collection<T> getAllSettingsForClient(ClientInfo ci) { 392f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ArrayList<T> settingsList = new ArrayList<>(); 393f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Iterator<RequestInfo<T>> iter = iterator(); 394f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius while (iter.hasNext()) { 395f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius RequestInfo<T> entry = iter.next(); 396f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius if (entry.clientInfo == ci) { 397f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius settingsList.add(entry.settings); 398f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 399f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 400f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius return settingsList; 40144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 40244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 40344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills void removeAllForClient(ClientInfo ci) { 40444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills Iterator<RequestInfo<T>> iter = iterator(); 40544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills while (iter.hasNext()) { 40644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills RequestInfo<T> entry = iter.next(); 40744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (entry.clientInfo == ci) { 40844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills iter.remove(); 40944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 41044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 41144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 41244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 41344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills WorkSource createMergedWorkSource() { 41444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills WorkSource mergedSource = new WorkSource(); 41544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills for (RequestInfo<T> entry : this) { 41644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills mergedSource.add(entry.workSource); 41744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 41844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills return mergedSource; 41944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 42044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 42144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 4228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills /** 4238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * State machine that holds the state of single scans. Scans should only be active in the 4248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * ScanningState. The pending scans and active scans maps are swaped when entering 4258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * ScanningState. Any requests queued while scanning will be placed in the pending queue and 4268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * executed after transitioning back to IdleState. 4278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills */ 4288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills class WifiSingleScanStateMachine extends StateMachine implements WifiNative.ScanEventHandler { 4298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private final DefaultState mDefaultState = new DefaultState(); 4308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private final DriverStartedState mDriverStartedState = new DriverStartedState(); 4318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private final IdleState mIdleState = new IdleState(); 4328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills private final ScanningState mScanningState = new ScanningState(); 4338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4345751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills private WifiNative.ScanSettings mActiveScanSettings = null; 43544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills private RequestList<ScanSettings> mActiveScans = new RequestList<>(); 43644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills private RequestList<ScanSettings> mPendingScans = new RequestList<>(); 4378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiSingleScanStateMachine(Looper looper) { 4398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills super("WifiSingleScanStateMachine", looper); 4408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills setLogRecSize(128); 4428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills setLogOnlyTransitions(false); 4438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // CHECKSTYLE:OFF IndentationCheck 4458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills addState(mDefaultState); 4468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills addState(mDriverStartedState, mDefaultState); 4478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills addState(mIdleState, mDriverStartedState); 4488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills addState(mScanningState, mDriverStartedState); 4498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // CHECKSTYLE:ON IndentationCheck 4508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills setInitialState(mDefaultState); 4528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 4538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills /** 4558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * Called to indicate a change in state for the current scan. 4568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * Will dispatch a coresponding event to the state machine 4578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills */ 4588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 4598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void onScanStatus(int event) { 4608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (DBG) localLog("onScanStatus event received, event=" + event); 4618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills switch(event) { 4628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE: 4638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS: 4648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT: 4658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills sendMessage(CMD_SCAN_RESULTS_AVAILABLE); 4668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills break; 4678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiNative.WIFI_SCAN_FAILED: 4688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills sendMessage(CMD_SCAN_FAILED); 4698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills break; 4708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills default: 4718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills Log.e(TAG, "Unknown scan status event: " + event); 4728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills break; 4738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 4748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 4758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills /** 4778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * Called for each full scan result if requested 4788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills */ 4798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 480c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) { 4818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (DBG) localLog("onFullScanResult received"); 482c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult); 4838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 4848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 4868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void onScanPaused(ScanData[] scanData) { 4878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // should not happen for single scan 4888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills Log.e(TAG, "Got scan paused for single scan"); 4898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 4908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 4928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void onScanRestarted() { 4938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // should not happen for single scan 4948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills Log.e(TAG, "Got scan restarted for single scan"); 4958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 4968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 4978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills class DefaultState extends State { 4988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 4998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void enter() { 5008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mActiveScans.clear(); 5018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mPendingScans.clear(); 5028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 5048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public boolean processMessage(Message msg) { 5058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills switch (msg.what) { 5068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_DRIVER_LOADED: 5078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills transitionTo(mIdleState); 5088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_DRIVER_UNLOADED: 5108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills transitionTo(mDefaultState); 5118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiScanner.CMD_START_SINGLE_SCAN: 5138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiScanner.CMD_STOP_SINGLE_SCAN: 5148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills replyFailed(msg, WifiScanner.REASON_UNSPECIFIED, "not available"); 5158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_SCAN_RESULTS_AVAILABLE: 5178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (DBG) localLog("ignored scan results available event"); 5188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_FULL_SCAN_RESULTS: 5208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (DBG) localLog("ignored full scan result event"); 5218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills default: 5238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return NOT_HANDLED; 5248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 5268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 5298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills /** 5308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * State representing when the driver is running. This state is not meant to be transitioned 5318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * directly, but is instead indented as a parent state of ScanningState and IdleState 5328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills * to hold common functionality and handle cleaning up scans when the driver is shut down. 5338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills */ 5348adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills class DriverStartedState extends State { 5358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 5368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void exit() { 537c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementScanReturnEntry( 538c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED, 539c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mPendingScans.size()); 5408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills sendOpFailedToAllAndClear(mPendingScans, WifiScanner.REASON_UNSPECIFIED, 5418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills "Scan was interrupted"); 5428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 5448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 5458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public boolean processMessage(Message msg) { 5468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills ClientInfo ci = mClients.get(msg.replyTo); 5478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 5488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills switch (msg.what) { 5498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiScanner.CMD_START_SINGLE_SCAN: 550c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementOneshotScanCount(); 55156820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills int handler = msg.arg2; 5520ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills Bundle scanParams = (Bundle) msg.obj; 553720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills if (scanParams == null) { 55456820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills logCallback("singleScanInvalidRequest", ci, handler, "null params"); 555720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null"); 556720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills return HANDLED; 557720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills } 558720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills scanParams.setDefusable(true); 5590ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills ScanSettings scanSettings = 5600ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills scanParams.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY); 5610ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills WorkSource workSource = 5620ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills scanParams.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY); 5635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (validateScanRequest(ci, handler, scanSettings, workSource)) { 5645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills logScanRequest("addSingleScanRequest", ci, handler, workSource, 5655751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills scanSettings, null); 5668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills replySucceeded(msg); 5675751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 5685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills // If there is an active scan that will fulfill the scan request then 5695751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills // mark this request as an active scan, otherwise mark it pending. 5708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // If were not currently scanning then try to start a scan. Otherwise 5718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // this scan will be scheduled when transitioning back to IdleState 5728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // after finishing the current scan. 5735751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (getCurrentState() == mScanningState) { 5745751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (activeScanSatisfies(scanSettings)) { 5755751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills mActiveScans.addRequest(ci, handler, workSource, scanSettings); 5765751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } else { 5775751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills mPendingScans.addRequest(ci, handler, workSource, scanSettings); 5785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 5795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } else { 5805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills mPendingScans.addRequest(ci, handler, workSource, scanSettings); 5818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills tryToStartNewScan(); 5828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } else { 58456820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills logCallback("singleScanInvalidRequest", ci, handler, "bad request"); 5858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 586c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementScanReturnEntry( 587c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION, 1); 5888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case WifiScanner.CMD_STOP_SINGLE_SCAN: 5918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills removeSingleScanRequest(ci, msg.arg2); 5928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 5938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills default: 5948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return NOT_HANDLED; 5958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 5988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 5998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills class IdleState extends State { 6008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 6018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void enter() { 6028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills tryToStartNewScan(); 6038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 6058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 6068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public boolean processMessage(Message msg) { 6078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return NOT_HANDLED; 6088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 6118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills class ScanningState extends State { 61248444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills private WorkSource mScanWorkSource; 61348444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills 61448444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills @Override 61548444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills public void enter() { 61648444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mScanWorkSource = mActiveScans.createMergedWorkSource(); 61748444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills try { 61848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mBatteryStats.noteWifiScanStartedFromSource(mScanWorkSource); 61948444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills } catch (RemoteException e) { 62048444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills loge(e.toString()); 62148444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills } 62248444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills } 62348444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills 6248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 6258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public void exit() { 6265751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills mActiveScanSettings = null; 62748444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills try { 62848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mBatteryStats.noteWifiScanStoppedFromSource(mScanWorkSource); 62948444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills } catch (RemoteException e) { 63048444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills loge(e.toString()); 63148444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills } 63248444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills 6338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // if any scans are still active (never got results available then indicate failure) 634c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementScanReturnEntry( 635c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiMetricsProto.WifiLog.SCAN_UNKNOWN, 636c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mActiveScans.size()); 6378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills sendOpFailedToAllAndClear(mActiveScans, WifiScanner.REASON_UNSPECIFIED, 6388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills "Scan was interrupted"); 6398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 6418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills @Override 6428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills public boolean processMessage(Message msg) { 6438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills switch (msg.what) { 6448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_SCAN_RESULTS_AVAILABLE: 645c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementScanReturnEntry( 646c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiMetricsProto.WifiLog.SCAN_SUCCESS, 647c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mActiveScans.size()); 6488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills reportScanResults(mScannerImpl.getLatestSingleScanResults()); 6498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mActiveScans.clear(); 6508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills transitionTo(mIdleState); 6518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 6528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_FULL_SCAN_RESULTS: 653c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills reportFullScanResult((ScanResult) msg.obj, /* bucketsScanned */ msg.arg2); 6548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 6558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills case CMD_SCAN_FAILED: 656c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementScanReturnEntry( 657c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiMetricsProto.WifiLog.SCAN_UNKNOWN, mActiveScans.size()); 6588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills sendOpFailedToAllAndClear(mActiveScans, WifiScanner.REASON_UNSPECIFIED, 6598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills "Scan failed"); 6608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills transitionTo(mIdleState); 6618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return HANDLED; 6628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills default: 6638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return NOT_HANDLED; 6648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 6685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills boolean validateScanRequest(ClientInfo ci, int handler, ScanSettings settings, 6690ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills WorkSource workSource) { 6708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (ci == null) { 6718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills Log.d(TAG, "Failing single scan request ClientInfo not found " + handler); 6728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return false; 6738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 6758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (settings.channels == null || settings.channels.length == 0) { 6768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills Log.d(TAG, "Failing single scan because channel list was empty"); 6778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return false; 6788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 6805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills return true; 6815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 6825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 6835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills boolean activeScanSatisfies(ScanSettings settings) { 6845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (mActiveScanSettings == null) { 6855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills return false; 6865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 6875751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 6885751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills // there is always one bucket for a single scan 6895751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills WifiNative.BucketSettings activeBucket = mActiveScanSettings.buckets[0]; 6905751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 6915751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills // validate that all requested channels are being scanned 6925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills ChannelCollection activeChannels = mChannelHelper.createChannelCollection(); 6935751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills activeChannels.addChannels(activeBucket); 6945751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (!activeChannels.containsSettings(settings)) { 6955751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills return false; 6965751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 6975751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 6985751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills // if the request is for a full scan, but there is no ongoing full scan 6995751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0 7005751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills && (activeBucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) 7015751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills == 0) { 7025751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills return false; 7035751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 7045751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 7055751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (settings.hiddenNetworkIds != null) { 706ed70365e5a3a6e2b06c2d4d06603f97596f1124bMitchell Wills if (mActiveScanSettings.hiddenNetworkIds == null) { 707ed70365e5a3a6e2b06c2d4d06603f97596f1124bMitchell Wills return false; 708ed70365e5a3a6e2b06c2d4d06603f97596f1124bMitchell Wills } 7095751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills Set<Integer> activeHiddenNetworkIds = new HashSet<>(); 7105751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills for (int id : mActiveScanSettings.hiddenNetworkIds) { 7115751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills activeHiddenNetworkIds.add(id); 7125751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 7135751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills for (int id : settings.hiddenNetworkIds) { 7145751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills if (!activeHiddenNetworkIds.contains(id)) { 7155751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills return false; 7165751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 7175751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 7185751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills } 7195751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills 7208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return true; 7218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 7238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills void removeSingleScanRequest(ClientInfo ci, int handler) { 7248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (ci != null) { 72544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("removeSingleScanRequest", ci, handler, null, null, null); 726f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mPendingScans.removeRequest(ci, handler); 727f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveScans.removeRequest(ci, handler); 72844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 72944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 73044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills 73144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills void removeSingleScanRequests(ClientInfo ci) { 73244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (ci != null) { 73344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("removeSingleScanRequests", ci, -1, null, null, null); 73444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills mPendingScans.removeAllForClient(ci); 73544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills mActiveScans.removeAllForClient(ci); 7368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 7398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills void tryToStartNewScan() { 7408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (mPendingScans.size() == 0) { // no pending requests 7418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills return; 7428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mChannelHelper.updateChannels(); 7448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // TODO move merging logic to a scheduler 7458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiNative.ScanSettings settings = new WifiNative.ScanSettings(); 7468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills settings.num_buckets = 1; 7478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings(); 7488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills bucketSettings.bucket = 0; 7498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills bucketSettings.period_ms = 0; 75044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills bucketSettings.report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 7518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 7528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills ChannelCollection channels = mChannelHelper.createChannelCollection(); 7538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills HashSet<Integer> hiddenNetworkIdSet = new HashSet<>(); 75444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills for (RequestInfo<ScanSettings> entry : mPendingScans) { 75544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills channels.addChannels(entry.settings); 75644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (entry.settings.hiddenNetworkIds != null) { 75744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills for (int i = 0; i < entry.settings.hiddenNetworkIds.length; i++) { 75844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills hiddenNetworkIdSet.add(entry.settings.hiddenNetworkIds[i]); 7598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 76144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if ((entry.settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) 76244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills != 0) { 76344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills bucketSettings.report_events |= WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; 76444f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 7658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (hiddenNetworkIdSet.size() > 0) { 7678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills settings.hiddenNetworkIds = new int[hiddenNetworkIdSet.size()]; 7688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills int numHiddenNetworks = 0; 7698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills for (Integer hiddenNetworkId : hiddenNetworkIdSet) { 7708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills settings.hiddenNetworkIds[numHiddenNetworks++] = hiddenNetworkId; 7718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 7748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills channels.fillBucketSettings(bucketSettings, Integer.MAX_VALUE); 7758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 7768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills settings.buckets = new WifiNative.BucketSettings[] {bucketSettings}; 7778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills if (mScannerImpl.startSingleScan(settings, this)) { 7785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills // store the active scan settings 7795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills mActiveScanSettings = settings; 7808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // swap pending and active scan requests 78144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills RequestList<ScanSettings> tmp = mActiveScans; 7828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mActiveScans = mPendingScans; 7838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mPendingScans = tmp; 7848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // make sure that the pending list is clear 7858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mPendingScans.clear(); 7868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills transitionTo(mScanningState); 7878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } else { 788c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementScanReturnEntry( 789c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne WifiMetricsProto.WifiLog.SCAN_UNKNOWN, mPendingScans.size()); 7908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // notify and cancel failed scans 7918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills sendOpFailedToAllAndClear(mPendingScans, WifiScanner.REASON_UNSPECIFIED, 7928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills "Failed to start single scan"); 7938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 7958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 79644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills void sendOpFailedToAllAndClear(RequestList<?> clientHandlers, int reason, 7978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills String description) { 79844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills for (RequestInfo<?> entry : clientHandlers) { 79956820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills logCallback("singleScanFailed", entry.clientInfo, entry.handlerId, 80056820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills "reason=" + reason + ", " + description); 80144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills entry.reportEvent(WifiScanner.CMD_OP_FAILED, 0, 8028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills new WifiScanner.OperationResult(reason, description)); 8038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills clientHandlers.clear(); 8058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 807c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills void reportFullScanResult(ScanResult result, int bucketsScanned) { 80844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills for (RequestInfo<ScanSettings> entry : mActiveScans) { 8094e54617758f86acef751bc8588257a58ed985b0fMitchell Wills if (ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper, 81044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills result, bucketsScanned, entry.settings, -1)) { 81144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills entry.reportEvent(WifiScanner.CMD_FULL_SCAN_RESULT, 0, result); 8128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills 8151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills for (RequestInfo<Void> entry : mSingleScanListeners) { 8161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills entry.reportEvent(WifiScanner.CMD_FULL_SCAN_RESULT, 0, result); 8171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills } 8188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 8208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills void reportScanResults(ScanData results) { 821c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne if (results != null && results.getResults() != null) { 822c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne if (results.getResults().length > 0) { 823c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementNonEmptyScanResultCount(); 824c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } else { 825c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementEmptyScanResultCount(); 826c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } 827c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } 8281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills ScanData[] allResults = new ScanData[] {results}; 82944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills for (RequestInfo<ScanSettings> entry : mActiveScans) { 8304e54617758f86acef751bc8588257a58ed985b0fMitchell Wills ScanData[] resultsToDeliver = ScanScheduleUtil.filterResultsForSettings( 8311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills mChannelHelper, allResults, entry.settings, -1); 8321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills WifiScanner.ParcelableScanData parcelableResultsToDeliver = 8338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills new WifiScanner.ParcelableScanData(resultsToDeliver); 83459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills logCallback("singleScanResults", entry.clientInfo, entry.handlerId, 83559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills describeForLog(resultsToDeliver)); 8361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableResultsToDeliver); 8378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // make sure the handler is removed 83844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills entry.reportEvent(WifiScanner.CMD_SINGLE_SCAN_COMPLETED, 0, null); 8398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills 8411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills WifiScanner.ParcelableScanData parcelableAllResults = 8421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills new WifiScanner.ParcelableScanData(allResults); 8431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills for (RequestInfo<Void> entry : mSingleScanListeners) { 8441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills logCallback("singleScanResults", entry.clientInfo, entry.handlerId, 8451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills describeForLog(allResults)); 8461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableAllResults); 8471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills } 8488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 8508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 8518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills class WifiBackgroundScanStateMachine extends StateMachine 852c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius implements WifiNative.ScanEventHandler, WifiNative.HotlistEventHandler { 853e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 854e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private final DefaultState mDefaultState = new DefaultState(); 855e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde private final StartedState mStartedState = new StartedState(); 856b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande private final PausedState mPausedState = new PausedState(); 857e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 858f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius private final RequestList<ScanSettings> mActiveBackgroundScans = new RequestList<>(); 859f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius private final RequestList<WifiScanner.HotlistSettings> mActiveHotlistSettings = 860f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius new RequestList<>(); 8611fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius 8628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiBackgroundScanStateMachine(Looper looper) { 863799f1c026941c9183657ffb99f0fb34ff643a0ddRoshan Pius super("WifiBackgroundScanStateMachine", looper); 864e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 865e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setLogRecSize(512); 866e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setLogOnlyTransitions(false); 867e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 8688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // CHECKSTYLE:OFF IndentationCheck 869e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addState(mDefaultState); 870e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addState(mStartedState, mDefaultState); 871b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande addState(mPausedState, mDefaultState); 8728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // CHECKSTYLE:ON IndentationCheck 873e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 874e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setInitialState(mDefaultState); 875e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 876e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 87719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius public Collection<ScanSettings> getBackgroundScanSettings(ClientInfo ci) { 878f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius return mActiveBackgroundScans.getAllSettingsForClient(ci); 87980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 88080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 88119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius public void removeBackgroundScanSettings(ClientInfo ci) { 882f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveBackgroundScans.removeAllForClient(ci); 88319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius updateSchedule(); 88480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 88580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 88619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius public void removeHotlistSettings(ClientInfo ci) { 887f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveHotlistSettings.removeAllForClient(ci); 88819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius resetHotlist(); 88980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 89080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 891e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 89263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills public void onScanStatus(int event) { 89363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills if (DBG) localLog("onScanStatus event received, event=" + event); 89463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills switch(event) { 89563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE: 89663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS: 89763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT: 89863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills sendMessage(CMD_SCAN_RESULTS_AVAILABLE); 89963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills break; 90063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills case WifiNative.WIFI_SCAN_FAILED: 90163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills sendMessage(CMD_SCAN_FAILED); 90263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills break; 90363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills default: 90463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills Log.e(TAG, "Unknown scan status event: " + event); 90563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills break; 90663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills } 907b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande } 908b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande 909b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande @Override 910c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) { 911297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (DBG) localLog("onFullScanResult received"); 912c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult); 913e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 914e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 915e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 916bb6942c6b6d129fd8904e341c9ce4a4118ed3e0bVinit Deshpande public void onScanPaused(ScanData scanData[]) { 917297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (DBG) localLog("onScanPaused received"); 91883a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande sendMessage(CMD_SCAN_PAUSED, scanData); 919b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande } 920b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande 921b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande @Override 922b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande public void onScanRestarted() { 923297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (DBG) localLog("onScanRestarted received"); 924b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande sendMessage(CMD_SCAN_RESTARTED); 925b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande } 926b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande 927b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande @Override 928e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public void onHotlistApFound(ScanResult[] results) { 929297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (DBG) localLog("onHotlistApFound event received"); 930e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde sendMessage(CMD_HOTLIST_AP_FOUND, 0, 0, results); 931e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 932e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 933e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 934d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande public void onHotlistApLost(ScanResult[] results) { 935297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (DBG) localLog("onHotlistApLost event received"); 936d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande sendMessage(CMD_HOTLIST_AP_LOST, 0, 0, results); 937d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande } 938d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande 939e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde class DefaultState extends State { 940e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 941e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public void enter() { 942716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe if (DBG) localLog("DefaultState"); 94380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius mActiveBackgroundScans.clear(); 944a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mActiveHotlistSettings.clear(); 945e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 946a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 947e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 948e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public boolean processMessage(Message msg) { 949e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde switch (msg.what) { 950e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case CMD_DRIVER_LOADED: 9518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // TODO this should be moved to a common location since it is used outside 952c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne // of this state machine. It is ok right now because the driver loaded event 9538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // is sent to this state machine first. 9549ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mScannerImpl == null) { 955ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius mScannerImpl = mScannerImplFactory.create(mContext, mLooper, mClock); 956017307e0d7133f3b2523090136b919c6f494098eMitchell Wills mChannelHelper = mScannerImpl.getChannelHelper(); 9579ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 958017307e0d7133f3b2523090136b919c6f494098eMitchell Wills 959985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills mBackgroundScheduler = new BackgroundScanScheduler(mChannelHelper); 960017307e0d7133f3b2523090136b919c6f494098eMitchell Wills 96194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills WifiNative.ScanCapabilities capabilities = 96294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills new WifiNative.ScanCapabilities(); 963297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (!mScannerImpl.getScanCapabilities(capabilities)) { 964297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills loge("could not get scan capabilities"); 965297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return HANDLED; 966e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 967985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills mBackgroundScheduler.setMaxBuckets(capabilities.max_scan_buckets); 968985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills mBackgroundScheduler.setMaxApPerScan(capabilities.max_ap_cache_per_scan); 969297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 97094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills Log.i(TAG, "wifi driver loaded with scan capabilities: " 971297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills + "max buckets=" + capabilities.max_scan_buckets); 972297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills 973297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills transitionTo(mStartedState); 974297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return HANDLED; 975297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case CMD_DRIVER_UNLOADED: 976297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills Log.i(TAG, "wifi driver unloaded"); 977297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills transitionTo(mDefaultState); 978e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 979e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_START_BACKGROUND_SCAN: 980e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_STOP_BACKGROUND_SCAN: 98183a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande case WifiScanner.CMD_START_SINGLE_SCAN: 98283a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande case WifiScanner.CMD_STOP_SINGLE_SCAN: 983e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_SET_HOTLIST: 984e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_RESET_HOTLIST: 98514aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann case WifiScanner.CMD_GET_SCAN_RESULTS: 986daac2ad767f6047409987bb22812ab5f295e54dfVinit Deshpande replyFailed(msg, WifiScanner.REASON_UNSPECIFIED, "not available"); 987e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 988e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 989e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case CMD_SCAN_RESULTS_AVAILABLE: 990716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe if (DBG) localLog("ignored scan results available event"); 991e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 992e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 993f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde case CMD_FULL_SCAN_RESULTS: 994716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe if (DBG) localLog("ignored full scan result event"); 995f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde break; 996f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde 997e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde default: 998e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 999e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1000e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1001e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return HANDLED; 1002e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1003e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1004e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1005e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde class StartedState extends State { 1006e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1007e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 1008e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public void enter() { 1009716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe if (DBG) localLog("StartedState"); 1010e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1011e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1012e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 10131fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius public void exit() { 101480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius sendBackgroundScanFailedToAllAndClear( 101580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius WifiScanner.REASON_UNSPECIFIED, "Scan was interrupted"); 1016a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius sendHotlistFailedToAllAndClear( 1017a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius WifiScanner.REASON_UNSPECIFIED, "Scan was interrupted"); 10181e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills mScannerImpl.cleanup(); 10191fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius } 10201fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius 10211fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius @Override 1022e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public boolean processMessage(Message msg) { 1023e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ClientInfo ci = mClients.get(msg.replyTo); 1024e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1025e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde switch (msg.what) { 1026297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case CMD_DRIVER_LOADED: 1027297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return NOT_HANDLED; 1028e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case CMD_DRIVER_UNLOADED: 1029297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return NOT_HANDLED; 10300ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills case WifiScanner.CMD_START_BACKGROUND_SCAN: { 1031c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementBackgroundScanCount(); 10320ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills Bundle scanParams = (Bundle) msg.obj; 1033720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills if (scanParams == null) { 1034720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null"); 1035720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills return HANDLED; 1036720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills } 1037720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills scanParams.setDefusable(true); 10380ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills ScanSettings scanSettings = 10390ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills scanParams.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY); 10400ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills WorkSource workSource = 10410ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills scanParams.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY); 10420ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills if (addBackgroundScanRequest(ci, msg.arg2, scanSettings, workSource)) { 104383a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande replySucceeded(msg); 104412836d34cc6c4497c1fa5adbb956684ecec7578eVinit Deshpande } else { 104512836d34cc6c4497c1fa5adbb956684ecec7578eVinit Deshpande replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 104612836d34cc6c4497c1fa5adbb956684ecec7578eVinit Deshpande } 1047e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 10480ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills } 1049e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_STOP_BACKGROUND_SCAN: 10508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills removeBackgroundScanRequest(ci, msg.arg2); 1051e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 105214aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann case WifiScanner.CMD_GET_SCAN_RESULTS: 1053297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills reportScanResults(mScannerImpl.getLatestBatchedScanResults(true)); 105414aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann replySucceeded(msg); 105514aadf3997f007f53f12e8bec3efaea1a66b44bdNavtej Singh Mann break; 1056e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_SET_HOTLIST: 10575382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (addHotlist(ci, msg.arg2, (WifiScanner.HotlistSettings) msg.obj)) { 10585382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replySucceeded(msg); 10595382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } else { 10605382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 10615382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 1062e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 1063e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde case WifiScanner.CMD_RESET_HOTLIST: 106419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius removeHotlist(ci, msg.arg2); 1065578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 1066297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case CMD_SCAN_RESULTS_AVAILABLE: 1067297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills reportScanResults(mScannerImpl.getLatestBatchedScanResults(true)); 1068e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde break; 1069297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case CMD_FULL_SCAN_RESULTS: 1070c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills reportFullScanResult((ScanResult) msg.obj, /* bucketsScanned */ msg.arg2); 1071f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde break; 107219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case CMD_HOTLIST_AP_FOUND: 107319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius reportHotlistResults(WifiScanner.CMD_AP_FOUND, (ScanResult[]) msg.obj); 1074578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 107519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case CMD_HOTLIST_AP_LOST: 107619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius reportHotlistResults(WifiScanner.CMD_AP_LOST, (ScanResult[]) msg.obj); 1077578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 1078297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills case CMD_SCAN_PAUSED: 1079297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills reportScanResults((ScanData[]) msg.obj); 1080297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills transitionTo(mPausedState); 108183a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande break; 108263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills case CMD_SCAN_FAILED: 10838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills Log.e(TAG, "WifiScanner background scan gave CMD_SCAN_FAILED"); 108480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius sendBackgroundScanFailedToAllAndClear( 108580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius WifiScanner.REASON_UNSPECIFIED, "Background Scan failed"); 108663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills break; 1087e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde default: 1088e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return NOT_HANDLED; 1089e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1090e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1091e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return HANDLED; 1092e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1093e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1094e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1095b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande class PausedState extends State { 1096b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande @Override 1097b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande public void enter() { 1098716921f71ceeda2dc00bdd997f54fe7010b3ed0axinhe if (DBG) localLog("PausedState"); 1099b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande } 1100b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande 1101b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande @Override 1102b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande public boolean processMessage(Message msg) { 1103b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande switch (msg.what) { 1104b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande case CMD_SCAN_RESTARTED: 1105b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande transitionTo(mStartedState); 1106b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande break; 1107b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande default: 1108b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande deferMessage(msg); 1109b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande break; 1110b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande } 1111b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande return HANDLED; 1112b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande } 1113b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande } 11141fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius 111580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius private boolean addBackgroundScanRequest(ClientInfo ci, int handler, 11160ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills ScanSettings settings, WorkSource workSource) { 111780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius // sanity check the input 111880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (ci == null) { 111980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius Log.d(TAG, "Failing scan request ClientInfo not found " + handler); 112080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 112180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 112280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.periodInMs < WifiScanner.MIN_SCAN_PERIOD_MS) { 112380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("Failing scan request because periodInMs is " + settings.periodInMs 112480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius + ", min scan period is: " + WifiScanner.MIN_SCAN_PERIOD_MS); 112580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 112680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 112780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 112880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED && settings.channels == null) { 112980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("Channels was null with unspecified band"); 113080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 113180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 113280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 113380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED 113480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius && settings.channels.length == 0) { 113580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("No channels specified"); 113680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 113780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 113880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 113980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius int minSupportedPeriodMs = mChannelHelper.estimateScanDuration(settings); 114080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.periodInMs < minSupportedPeriodMs) { 114180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("Failing scan request because minSupportedPeriodMs is " 114280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius + minSupportedPeriodMs + " but the request wants " + settings.periodInMs); 114380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 114480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 114580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 114680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius // check truncated binary exponential back off scan settings 114780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.maxPeriodInMs != 0 && settings.maxPeriodInMs != settings.periodInMs) { 114880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.maxPeriodInMs < settings.periodInMs) { 114980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("Failing scan request because maxPeriodInMs is " + settings.maxPeriodInMs 115080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius + " but less than periodInMs " + settings.periodInMs); 115180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 115280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 115380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.maxPeriodInMs > WifiScanner.MAX_SCAN_PERIOD_MS) { 115480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("Failing scan request because maxSupportedPeriodMs is " 115580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius + WifiScanner.MAX_SCAN_PERIOD_MS + " but the request wants " 115680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius + settings.maxPeriodInMs); 115780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 115880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 115980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (settings.stepCount < 1) { 116080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius loge("Failing scan request because stepCount is " + settings.stepCount 116180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius + " which is less than 1"); 116280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 116380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 116480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 116580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 116644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("addBackgroundScanRequest", ci, handler, null, settings, null); 1167f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveBackgroundScans.addRequest(ci, handler, workSource, settings); 116880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 116980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (updateSchedule()) { 117080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return true; 117180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } else { 1172f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveBackgroundScans.removeRequest(ci, handler); 117380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius localLog("Failing scan request because failed to reset scan"); 117480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius return false; 117580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 117680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 117780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 117819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private boolean updateSchedule() { 11793040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills if (mChannelHelper == null || mBackgroundScheduler == null || mScannerImpl == null) { 11803040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills loge("Failed to update schedule because WifiScanningService is not initialized"); 11813040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills return false; 11823040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills } 118319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mChannelHelper.updateChannels(); 1184f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Collection<ScanSettings> settings = mActiveBackgroundScans.getAllSettings(); 118519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 1186985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills mBackgroundScheduler.updateSchedule(settings); 1187985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills WifiNative.ScanSettings schedule = mBackgroundScheduler.getSchedule(); 118819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 118919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (ScanScheduleUtil.scheduleEquals(mPreviousSchedule, schedule)) { 119019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) Log.d(TAG, "schedule updated with no change"); 119119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius return true; 119219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 119319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 119419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mPreviousSchedule = schedule; 119519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 119619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (schedule.num_buckets == 0) { 119719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mScannerImpl.stopBatchedScan(); 119819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) Log.d(TAG, "scan stopped"); 119919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius return true; 120019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } else { 12019e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills localLog("starting scan: " 120219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + "base period=" + schedule.base_period_ms 120319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + ", max ap per scan=" + schedule.max_ap_per_scan 120419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + ", batched scans=" + schedule.report_threshold_num_scans); 120519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (int b = 0; b < schedule.num_buckets; b++) { 120619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiNative.BucketSettings bucket = schedule.buckets[b]; 12079e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills localLog("bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)" 120819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + "[" + bucket.report_events + "]: " 120919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + ChannelHelper.toString(bucket)); 121019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 121119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 121219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (mScannerImpl.startBatchedScan(schedule, this)) { 121319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) { 121419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Log.d(TAG, "scan restarted with " + schedule.num_buckets 121519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + " bucket(s) and base period: " + schedule.base_period_ms); 121619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 121719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius return true; 121819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } else { 121919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mPreviousSchedule = null; 122019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius loge("error starting scan: " 122119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + "base period=" + schedule.base_period_ms 122219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + ", max ap per scan=" + schedule.max_ap_per_scan 122319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + ", batched scans=" + schedule.report_threshold_num_scans); 122419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (int b = 0; b < schedule.num_buckets; b++) { 122519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiNative.BucketSettings bucket = schedule.buckets[b]; 122619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius loge("bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)" 122719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + "[" + bucket.report_events + "]: " 122819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius + ChannelHelper.toString(bucket)); 122919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 123019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius return false; 123119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 123219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 123319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 123419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 123580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius private void removeBackgroundScanRequest(ClientInfo ci, int handler) { 123680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (ci != null) { 1237f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ScanSettings settings = mActiveBackgroundScans.removeRequest(ci, handler); 123844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("removeBackgroundScanRequest", ci, handler, null, settings, null); 123980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius updateSchedule(); 124080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 124180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 124280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 1243c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills private void reportFullScanResult(ScanResult result, int bucketsScanned) { 1244f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<ScanSettings> entry : mActiveBackgroundScans) { 1245f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1246f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 1247f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ScanSettings settings = entry.settings; 1248985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills if (mBackgroundScheduler.shouldReportFullScanResultForSettings( 1249c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills result, bucketsScanned, settings)) { 125080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius ScanResult newResult = new ScanResult(result); 125180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (result.informationElements != null) { 125280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius newResult.informationElements = result.informationElements.clone(); 125380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 125480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius else { 125580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius newResult.informationElements = null; 125680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 1257a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ci.reportEvent(WifiScanner.CMD_FULL_SCAN_RESULT, 0, handler, newResult); 125880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 125980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 126080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 126180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 126280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius private void reportScanResults(ScanData[] results) { 1263c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne for (ScanData result : results) { 1264c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne if (result != null && result.getResults() != null) { 1265c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne if (result.getResults().length > 0) { 1266c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementNonEmptyScanResultCount(); 1267c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } else { 1268c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne mWifiMetrics.incrementEmptyScanResultCount(); 1269c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } 1270c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } 1271c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne } 1272f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<ScanSettings> entry : mActiveBackgroundScans) { 1273f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1274f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 1275f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ScanSettings settings = entry.settings; 127680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius ScanData[] resultsToDeliver = 1277985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills mBackgroundScheduler.filterResultsForSettings(results, settings); 127880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (resultsToDeliver != null) { 127959298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills logCallback("backgroundScanResults", ci, handler, 128059298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills describeForLog(resultsToDeliver)); 1281c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.ParcelableScanData parcelableScanData = 1282c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius new WifiScanner.ParcelableScanData(resultsToDeliver); 1283c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ci.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, handler, parcelableScanData); 128480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 128580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 128680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 128780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 128880640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius private void sendBackgroundScanFailedToAllAndClear(int reason, String description) { 1289f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<ScanSettings> entry : mActiveBackgroundScans) { 1290f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1291f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 1292a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ci.reportEvent(WifiScanner.CMD_OP_FAILED, 0, handler, 12931fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius new WifiScanner.OperationResult(reason, description)); 12941fa40005d82db21b2cc1c7e06d249b09c674ab8bRoshan Pius } 129580640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius mActiveBackgroundScans.clear(); 129680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius } 129780640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius 12985382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius private boolean addHotlist(ClientInfo ci, int handler, 12995382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius WifiScanner.HotlistSettings settings) { 13005382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (ci == null) { 13015382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius Log.d(TAG, "Failing hotlist request ClientInfo not found " + handler); 13025382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius return false; 13035382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 1304f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveHotlistSettings.addRequest(ci, handler, null, settings); 130519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius resetHotlist(); 13065382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius return true; 130719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 130819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 130919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void removeHotlist(ClientInfo ci, int handler) { 13105382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (ci != null) { 13115382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius mActiveHotlistSettings.removeRequest(ci, handler); 13125382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius resetHotlist(); 13135382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 131419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 131519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 131619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void resetHotlist() { 13173040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills if (mScannerImpl == null) { 13183040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills loge("Failed to update hotlist because WifiScanningService is not initialized"); 13193040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills return; 13203040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills } 13213040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills 1322f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Collection<WifiScanner.HotlistSettings> settings = 1323f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActiveHotlistSettings.getAllSettings(); 132419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int num_hotlist_ap = 0; 132519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 132619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (WifiScanner.HotlistSettings s : settings) { 132719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius num_hotlist_ap += s.bssidInfos.length; 132819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 132919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 133019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (num_hotlist_ap == 0) { 133119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mScannerImpl.resetHotlist(); 133219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } else { 133319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius BssidInfo[] bssidInfos = new BssidInfo[num_hotlist_ap]; 133419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int apLostThreshold = Integer.MAX_VALUE; 133519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int index = 0; 133619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (WifiScanner.HotlistSettings s : settings) { 133719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (int i = 0; i < s.bssidInfos.length; i++, index++) { 133819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius bssidInfos[index] = s.bssidInfos[i]; 133919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 134019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (s.apLostThreshold < apLostThreshold) { 134119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius apLostThreshold = s.apLostThreshold; 134219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 134319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 134419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 134519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiScanner.HotlistSettings mergedSettings = new WifiScanner.HotlistSettings(); 134619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mergedSettings.bssidInfos = bssidInfos; 134719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mergedSettings.apLostThreshold = apLostThreshold; 134819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mScannerImpl.setHotlist(mergedSettings, this); 134919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 135019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 135119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 135219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void reportHotlistResults(int what, ScanResult[] results) { 135319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) localLog("reportHotlistResults " + what + " results " + results.length); 1354f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<WifiScanner.HotlistSettings> entry : mActiveHotlistSettings) { 1355f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1356f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 1357f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius WifiScanner.HotlistSettings settings = entry.settings; 135819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int num_results = 0; 135919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (ScanResult result : results) { 136019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (BssidInfo BssidInfo : settings.bssidInfos) { 136119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (result.BSSID.equalsIgnoreCase(BssidInfo.bssid)) { 136219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius num_results++; 136319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius break; 136419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 136519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 136619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 136719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (num_results == 0) { 136819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius // nothing to report 136919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius return; 137019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 137119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius ScanResult[] results2 = new ScanResult[num_results]; 137219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int index = 0; 137319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (ScanResult result : results) { 137419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius for (BssidInfo BssidInfo : settings.bssidInfos) { 137519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (result.BSSID.equalsIgnoreCase(BssidInfo.bssid)) { 137619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius results2[index] = result; 137719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius index++; 137819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 137919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 138019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 138119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiScanner.ParcelableScanResults parcelableScanResults = 138219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius new WifiScanner.ParcelableScanResults(results2); 138319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 1384a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ci.reportEvent(what, 0, handler, parcelableScanResults); 138519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 138619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 1387a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 1388a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private void sendHotlistFailedToAllAndClear(int reason, String description) { 1389f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<WifiScanner.HotlistSettings> entry : mActiveHotlistSettings) { 1390f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1391f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 1392a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ci.reportEvent(WifiScanner.CMD_OP_FAILED, 0, handler, 1393a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius new WifiScanner.OperationResult(reason, description)); 1394a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 1395a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mActiveHotlistSettings.clear(); 1396a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 1397e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1398e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1399c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius /** 1400c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * PNO scan state machine has 5 states: 1401c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * -Default State 1402c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * -Started State 1403c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * -Hw Pno Scan state 1404c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * -Single Scan state 1405c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * -Sw Pno Scan state 1406c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * 1407c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * These are the main state transitions: 1408c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * 1. Start at |Default State| 1409c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * 2. Move to |Started State| when we get the |WIFI_SCAN_AVAILABLE| broadcast from WifiManager. 1410c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * 3. When a new PNO scan request comes in: 1411c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * a.1. Switch to |Hw Pno Scan state| when the device supports HW PNO 1412c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * (This could either be HAL based ePNO or supplicant based PNO). 1413c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * a.2. In |Hw Pno Scan state| when PNO scan results are received, check if the result 1414c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * contains IE (information elements). If yes, send the results to the client, else 1415c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * switch to |Single Scan state| and send the result to the client when the scan result 1416c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * is obtained. 1417c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * b.1. Switch to |Sw Pno Scan state| when the device does not supports HW PNO 1418c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * (This is for older devices which do not support HW PNO and for connected PNO on 1419c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * devices which support supplicant based PNO) 1420c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * b.2. In |Sw Pno Scan state| send the result to the client when the background scan result 1421c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * is obtained 1422c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * 1423c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * Note: PNO scans only work for a single client today. We don't have support in HW to support 1424c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * multiple requests at the same time, so will need non-trivial changes to support (if at all 1425c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * possible) in WifiScanningService. 1426c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius */ 1427c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius class WifiPnoScanStateMachine extends StateMachine implements WifiNative.PnoEventHandler { 1428c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1429c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private final DefaultState mDefaultState = new DefaultState(); 1430c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private final StartedState mStartedState = new StartedState(); 1431c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private final HwPnoScanState mHwPnoScanState = new HwPnoScanState(); 1432c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private final SwPnoScanState mSwPnoScanState = new SwPnoScanState(); 1433c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private final SingleScanState mSingleScanState = new SingleScanState(); 1434c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private InternalClientInfo mInternalClientInfo; 1435c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1436f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius private final RequestList<Pair<PnoSettings, ScanSettings>> mActivePnoScans = 1437f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius new RequestList<>(); 1438c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1439c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiPnoScanStateMachine(Looper looper) { 1440799f1c026941c9183657ffb99f0fb34ff643a0ddRoshan Pius super("WifiPnoScanStateMachine", looper); 1441c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1442c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius setLogRecSize(512); 1443c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius setLogOnlyTransitions(false); 1444c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1445c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // CHECKSTYLE:OFF IndentationCheck 1446c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addState(mDefaultState); 1447c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addState(mStartedState, mDefaultState); 1448c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addState(mHwPnoScanState, mStartedState); 1449c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addState(mSingleScanState, mHwPnoScanState); 1450c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addState(mSwPnoScanState, mStartedState); 1451c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // CHECKSTYLE:ON IndentationCheck 1452c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1453c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius setInitialState(mDefaultState); 1454c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1455c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1456c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void removePnoSettings(ClientInfo ci) { 1457f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActivePnoScans.removeAllForClient(ci); 1458c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1459c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1460c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1461c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1462c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void onPnoNetworkFound(ScanResult[] results) { 1463c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("onWifiPnoNetworkFound event received"); 1464c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius sendMessage(CMD_PNO_NETWORK_FOUND, 0, 0, results); 1465c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1466c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1467c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1468c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void onPnoScanFailed() { 1469c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("onWifiPnoScanFailed event received"); 1470c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius sendMessage(CMD_PNO_SCAN_FAILED, 0, 0, null); 1471c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1472c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1473c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius class DefaultState extends State { 1474c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1475c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void enter() { 1476c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("DefaultState"); 1477c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1478c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1479c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1480c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public boolean processMessage(Message msg) { 1481c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius switch (msg.what) { 1482c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case CMD_DRIVER_LOADED: 1483c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1484c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1485c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case CMD_DRIVER_UNLOADED: 1486c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mDefaultState); 1487c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1488c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_START_PNO_SCAN: 1489c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_STOP_PNO_SCAN: 1490c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius replyFailed(msg, WifiScanner.REASON_UNSPECIFIED, "not available"); 1491c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1492c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case CMD_PNO_NETWORK_FOUND: 1493c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case CMD_PNO_SCAN_FAILED: 1494c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_SCAN_RESULT: 1495c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_OP_FAILED: 1496c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius loge("Unexpected message " + msg.what); 1497c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1498c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius default: 1499c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return NOT_HANDLED; 1500c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1501c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return HANDLED; 1502c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1503c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1504c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1505c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius class StartedState extends State { 1506c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1507c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void enter() { 1508c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("StartedState"); 1509c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1510c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1511c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1512c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void exit() { 1513c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius sendPnoScanFailedToAllAndClear( 1514c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.REASON_UNSPECIFIED, "Scan was interrupted"); 1515c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1516c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1517c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1518c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public boolean processMessage(Message msg) { 1519c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 1520c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius switch (msg.what) { 1521c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_START_PNO_SCAN: 1522c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Bundle pnoParams = (Bundle) msg.obj; 1523720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills if (pnoParams == null) { 1524720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null"); 1525720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills return HANDLED; 1526720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills } 1527720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills pnoParams.setDefusable(true); 1528c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius PnoSettings pnoSettings = 1529c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY); 1530c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // This message is handled after the transition to SwPnoScan/HwPnoScan state 1531c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius deferMessage(msg); 1532c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (mScannerImpl.isHwPnoSupported(pnoSettings.isConnected)) { 1533c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mHwPnoScanState); 1534c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } else { 1535c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mSwPnoScanState); 1536c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1537c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1538c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_STOP_PNO_SCAN: 1539c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius replyFailed(msg, WifiScanner.REASON_UNSPECIFIED, "no scan running"); 1540c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1541c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius default: 1542c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return NOT_HANDLED; 1543c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1544c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return HANDLED; 1545c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1546c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1547c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1548c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius class HwPnoScanState extends State { 1549c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1550c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void enter() { 1551c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("HwPnoScanState"); 1552c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1553c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1554c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 15550e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius public void exit() { 15560e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius // Reset PNO scan in ScannerImpl before we exit. 15570e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius mScannerImpl.resetHwPnoList(); 15580e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius removeInternalClient(); 15590e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius } 15600e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius 15610e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius @Override 1562c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public boolean processMessage(Message msg) { 1563c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 1564c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius switch (msg.what) { 1565c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_START_PNO_SCAN: 1566c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Bundle pnoParams = (Bundle) msg.obj; 1567720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills if (pnoParams == null) { 1568720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null"); 1569720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills return HANDLED; 1570720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills } 1571720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills pnoParams.setDefusable(true); 1572c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius PnoSettings pnoSettings = 1573c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY); 1574c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ScanSettings scanSettings = 1575c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius pnoParams.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY); 1576c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (addHwPnoScanRequest(ci, msg.arg2, scanSettings, pnoSettings)) { 1577c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius replySucceeded(msg); 1578c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } else { 1579c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 1580c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1581c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1582c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1583c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_STOP_PNO_SCAN: 1584c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius removeHwPnoScanRequest(ci, msg.arg2); 1585c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1586c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1587c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case CMD_PNO_NETWORK_FOUND: 1588c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ScanResult[] scanResults = ((ScanResult[]) msg.obj); 1589c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (isSingleScanNeeded(scanResults)) { 1590f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ScanSettings activeScanSettings = getScanSettings(); 1591f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius if (activeScanSettings == null) { 1592f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius sendPnoScanFailedToAllAndClear( 1593f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius WifiScanner.REASON_UNSPECIFIED, 1594f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius "couldn't retrieve setting"); 1595f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius transitionTo(mStartedState); 1596f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } else { 1597f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius addSingleScanRequest(activeScanSettings); 1598f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius transitionTo(mSingleScanState); 1599f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 1600c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } else { 1601c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius reportPnoNetworkFound((ScanResult[]) msg.obj); 1602c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1603c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1604c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case CMD_PNO_SCAN_FAILED: 1605c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius sendPnoScanFailedToAllAndClear( 1606c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.REASON_UNSPECIFIED, "pno scan failed"); 1607c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1608c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1609c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius default: 1610c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return NOT_HANDLED; 1611c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1612c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return HANDLED; 1613c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1614c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1615c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1616c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius class SingleScanState extends State { 1617c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1618c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void enter() { 1619c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("SingleScanState"); 1620c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1621c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1622c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1623c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public boolean processMessage(Message msg) { 1624c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 1625c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius switch (msg.what) { 1626c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_SCAN_RESULT: 1627c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.ParcelableScanData parcelableScanData = 1628c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius (WifiScanner.ParcelableScanData) msg.obj; 1629c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ScanData[] scanDatas = parcelableScanData.getResults(); 1630c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ScanData lastScanData = scanDatas[scanDatas.length - 1]; 1631c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius reportPnoNetworkFound(lastScanData.getResults()); 1632c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mHwPnoScanState); 1633c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1634c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_OP_FAILED: 1635c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius sendPnoScanFailedToAllAndClear( 1636c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.REASON_UNSPECIFIED, "single scan failed"); 1637c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1638c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1639c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius default: 1640c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return NOT_HANDLED; 1641c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1642c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return HANDLED; 1643c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1644c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1645c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1646c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius class SwPnoScanState extends State { 1647c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private final ArrayList<ScanResult> mSwPnoFullScanResults = new ArrayList<>(); 1648c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1649c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 1650c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public void enter() { 1651c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("SwPnoScanState"); 1652c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mSwPnoFullScanResults.clear(); 1653c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1654c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1655c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius @Override 16560e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius public void exit() { 16570e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius removeInternalClient(); 16580e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius } 16590e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius 16600e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius @Override 1661c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius public boolean processMessage(Message msg) { 1662c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 1663c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius switch (msg.what) { 1664c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_START_PNO_SCAN: 1665c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Bundle pnoParams = (Bundle) msg.obj; 1666720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills if (pnoParams == null) { 1667720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null"); 1668720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills return HANDLED; 1669720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills } 1670720aba804a5c7fa5e4cc92af60b129e3e0013666Mitchell Wills pnoParams.setDefusable(true); 1671c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius PnoSettings pnoSettings = 1672c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY); 1673c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ScanSettings scanSettings = 1674c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius pnoParams.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY); 1675c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (addSwPnoScanRequest(ci, msg.arg2, scanSettings, pnoSettings)) { 1676c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius replySucceeded(msg); 1677c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } else { 1678c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 1679c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1680c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1681c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1682c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_STOP_PNO_SCAN: 1683c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius removeSwPnoScanRequest(ci, msg.arg2); 1684c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1685c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1686c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_FULL_SCAN_RESULT: 1687c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // Aggregate full scan results until we get the |CMD_SCAN_RESULT| message 1688c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mSwPnoFullScanResults.add((ScanResult) msg.obj); 1689c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1690c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_SCAN_RESULT: 1691c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ScanResult[] scanResults = mSwPnoFullScanResults.toArray( 1692c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius new ScanResult[mSwPnoFullScanResults.size()]); 1693c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius reportPnoNetworkFound(scanResults); 1694c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mSwPnoFullScanResults.clear(); 1695c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1696c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius case WifiScanner.CMD_OP_FAILED: 1697c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius sendPnoScanFailedToAllAndClear( 1698c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.REASON_UNSPECIFIED, "background scan failed"); 1699c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius transitionTo(mStartedState); 1700c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius break; 1701c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius default: 1702c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return NOT_HANDLED; 1703c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1704c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return HANDLED; 1705c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1706c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1707c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1708c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private WifiNative.PnoSettings convertPnoSettingsToNative(PnoSettings pnoSettings) { 1709c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiNative.PnoSettings nativePnoSetting = new WifiNative.PnoSettings(); 1710c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.min5GHzRssi = pnoSettings.min5GHzRssi; 1711c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.min24GHzRssi = pnoSettings.min24GHzRssi; 1712c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.initialScoreMax = pnoSettings.initialScoreMax; 1713c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.currentConnectionBonus = pnoSettings.currentConnectionBonus; 1714c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.sameNetworkBonus = pnoSettings.sameNetworkBonus; 1715c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.secureBonus = pnoSettings.secureBonus; 1716c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.band5GHzBonus = pnoSettings.band5GHzBonus; 1717c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.isConnected = pnoSettings.isConnected; 1718c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList = 1719c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius new WifiNative.PnoNetwork[pnoSettings.networkList.length]; 1720c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius for (int i = 0; i < pnoSettings.networkList.length; i++) { 1721c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList[i] = new WifiNative.PnoNetwork(); 1722c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList[i].ssid = pnoSettings.networkList[i].ssid; 1723c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList[i].networkId = pnoSettings.networkList[i].networkId; 1724c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList[i].priority = pnoSettings.networkList[i].priority; 1725c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList[i].flags = pnoSettings.networkList[i].flags; 1726c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius nativePnoSetting.networkList[i].auth_bit_field = 1727c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius pnoSettings.networkList[i].authBitField; 1728c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1729c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return nativePnoSetting; 1730c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1731c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1732f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius // Retrieve the only active scan settings. 1733c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private ScanSettings getScanSettings() { 1734f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (Pair<PnoSettings, ScanSettings> settingsPair : mActivePnoScans.getAllSettings()) { 1735f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius return settingsPair.second; 1736f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius } 1737f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius return null; 1738c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1739c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 17400e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius private void removeInternalClient() { 17410e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius if (mInternalClientInfo != null) { 17420e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius mInternalClientInfo.cleanup(); 17430e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius mInternalClientInfo = null; 17440e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius } else { 17450e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius Log.w(TAG, "No Internal client for PNO"); 1746c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1747c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1748c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1749c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void addInternalClient(ClientInfo ci) { 1750c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (mInternalClientInfo == null) { 1751c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mInternalClientInfo = 1752c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius new InternalClientInfo(ci.getUid(), new Messenger(this.getHandler())); 1753c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mInternalClientInfo.register(); 1754c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } else { 17550e4f6ab00e1f2bd64f17302dae279c77c4cf7d8eRoshan Pius Log.w(TAG, "Internal client for PNO already exists"); 1756c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1757c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1758c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1759c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void addPnoScanRequest(ClientInfo ci, int handler, ScanSettings scanSettings, 1760c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius PnoSettings pnoSettings) { 1761f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius mActivePnoScans.addRequest(ci, handler, WifiStateMachine.WIFI_WORK_SOURCE, 1762f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Pair.create(pnoSettings, scanSettings)); 1763c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addInternalClient(ci); 1764c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1765c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1766c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private Pair<PnoSettings, ScanSettings> removePnoScanRequest(ClientInfo ci, int handler) { 1767f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius Pair<PnoSettings, ScanSettings> settings = mActivePnoScans.removeRequest(ci, handler); 1768c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return settings; 1769c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1770c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1771c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private boolean addHwPnoScanRequest(ClientInfo ci, int handler, ScanSettings scanSettings, 1772c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius PnoSettings pnoSettings) { 1773c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (ci == null) { 1774c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Log.d(TAG, "Failing scan request ClientInfo not found " + handler); 1775c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return false; 1776c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1777c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (!mActivePnoScans.isEmpty()) { 1778c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius loge("Failing scan request because there is already an active scan"); 1779c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return false; 1780c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1781c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiNative.PnoSettings nativePnoSettings = convertPnoSettingsToNative(pnoSettings); 1782c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (!mScannerImpl.setHwPnoList(nativePnoSettings, mPnoScanStateMachine)) { 1783c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return false; 1784c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 178544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("addHwPnoScanRequest", ci, handler, null, scanSettings, pnoSettings); 1786c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addPnoScanRequest(ci, handler, scanSettings, pnoSettings); 1787c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // HW PNO is supported, check if we need a background scan running for this. 1788c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (mScannerImpl.shouldScheduleBackgroundScanForHwPno()) { 1789c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addBackgroundScanRequest(scanSettings); 1790c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1791c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return true; 1792c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1793c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1794c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void removeHwPnoScanRequest(ClientInfo ci, int handler) { 1795c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (ci != null) { 1796c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Pair<PnoSettings, ScanSettings> settings = removePnoScanRequest(ci, handler); 179744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("removeHwPnoScanRequest", ci, handler, null, 179844f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills settings.second, settings.first); 1799c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1800c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1801c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1802c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private boolean addSwPnoScanRequest(ClientInfo ci, int handler, ScanSettings scanSettings, 1803c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius PnoSettings pnoSettings) { 1804c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (ci == null) { 1805c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Log.d(TAG, "Failing scan request ClientInfo not found " + handler); 1806c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return false; 1807c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1808c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (!mActivePnoScans.isEmpty()) { 1809c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius loge("Failing scan request because there is already an active scan"); 1810c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return false; 1811c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 181244f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("addSwPnoScanRequest", ci, handler, null, scanSettings, pnoSettings); 1813c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addPnoScanRequest(ci, handler, scanSettings, pnoSettings); 1814c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // HW PNO is not supported, we need to revert to normal background scans and 1815c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius // report events after each scan and we need full scan results to get the IE information 1816c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius scanSettings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 1817c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; 1818c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius addBackgroundScanRequest(scanSettings); 1819c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return true; 1820c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1821c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1822c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void removeSwPnoScanRequest(ClientInfo ci, int handler) { 1823c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (ci != null) { 1824c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius Pair<PnoSettings, ScanSettings> settings = removePnoScanRequest(ci, handler); 182544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills logScanRequest("removeSwPnoScanRequest", ci, handler, null, 182644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills settings.second, settings.first); 1827c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1828c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1829c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1830c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void reportPnoNetworkFound(ScanResult[] results) { 1831c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.ParcelableScanResults parcelableScanResults = 1832c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius new WifiScanner.ParcelableScanResults(results); 1833f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<Pair<PnoSettings, ScanSettings>> entry : mActivePnoScans) { 1834f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1835f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 183659298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills logCallback("pnoNetworkFound", ci, handler, describeForLog(results)); 1837c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ci.reportEvent( 1838c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius WifiScanner.CMD_PNO_NETWORK_FOUND, 0, handler, parcelableScanResults); 1839c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1840c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1841c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1842c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void sendPnoScanFailedToAllAndClear(int reason, String description) { 1843f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius for (RequestInfo<Pair<PnoSettings, ScanSettings>> entry : mActivePnoScans) { 1844f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius ClientInfo ci = entry.clientInfo; 1845f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius int handler = entry.handlerId; 1846c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius ci.reportEvent(WifiScanner.CMD_OP_FAILED, 0, handler, 1847c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius new WifiScanner.OperationResult(reason, description)); 1848c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1849c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mActivePnoScans.clear(); 1850c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1851c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1852c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void addBackgroundScanRequest(ScanSettings settings) { 1853c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("Starting background scan"); 1854c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (mInternalClientInfo != null) { 185548444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mInternalClientInfo.sendRequestToClientHandler( 185648444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills WifiScanner.CMD_START_BACKGROUND_SCAN, settings, 185748444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills WifiStateMachine.WIFI_WORK_SOURCE); 1858c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1859c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1860c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1861c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private void addSingleScanRequest(ScanSettings settings) { 1862c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (DBG) localLog("Starting single scan"); 1863c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (mInternalClientInfo != null) { 186448444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mInternalClientInfo.sendRequestToClientHandler( 186548444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills WifiScanner.CMD_START_SINGLE_SCAN, settings, 186648444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills WifiStateMachine.WIFI_WORK_SOURCE); 1867c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1868c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1869c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1870c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius /** 1871c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * Checks if IE are present in scan data, if no single scan is needed to report event to 1872c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius * client 1873c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius */ 1874c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius private boolean isSingleScanNeeded(ScanResult[] scanResults) { 1875c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius for (ScanResult scanResult : scanResults) { 1876c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius if (scanResult.informationElements != null 1877c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius && scanResult.informationElements.length > 0) { 1878c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return false; 1879c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1880c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1881c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius return true; 1882c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1883c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius } 1884c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius 1885a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private abstract class ClientInfo { 1886fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande private final int mUid; 1887fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande private final WorkSource mWorkSource; 1888fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande private boolean mScanWorkReported = false; 1889a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius protected final Messenger mMessenger; 1890e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1891a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ClientInfo(int uid, Messenger messenger) { 1892fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande mUid = uid; 1893a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mMessenger = messenger; 1894297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills mWorkSource = new WorkSource(uid); 1895e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 1896e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1897a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 1898a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * Register this client to main client map. 1899a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 1900a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void register() { 1901a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mClients.put(mMessenger, this); 19028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 19038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 1904a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 1905a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * Unregister this client from main client map. 1906a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 1907a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private void unregister() { 1908a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mClients.remove(mMessenger); 19098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills } 19108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills 1911a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void cleanup() { 19121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills mSingleScanListeners.removeAllForClient(this); 191344f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills mSingleScanStateMachine.removeSingleScanRequests(this); 1914a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mBackgroundScanStateMachine.removeBackgroundScanSettings(this); 1915a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mBackgroundScanStateMachine.removeHotlistSettings(this); 1916a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius unregister(); 1917a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius localLog("Successfully stopped all requests for client " + this); 1918a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 1919a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 1920a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public int getUid() { 1921a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius return mUid; 1922a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 1923a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 1924a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void reportEvent(int what, int arg1, int arg2) { 1925a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius reportEvent(what, arg1, arg2, null); 1926a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 1927a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 1928a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // This has to be implemented by subclasses to report events back to clients. 1929a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public abstract void reportEvent(int what, int arg1, int arg2, Object obj); 1930a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 1931f8f5cb07ca2ead74f7f8bb03621fe0157aeba373Roshan Pius // TODO(b/27903217): Blame scan on provided work source 1932a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private void reportBatchedScanStart() { 1933fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande if (mUid == 0) 1934fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande return; 1935fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 1936fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande int csph = getCsph(); 1937fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 1938fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande try { 1939fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande mBatteryStats.noteWifiBatchedScanStartedFromSource(mWorkSource, csph); 1940fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } catch (RemoteException e) { 1941d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande logw("failed to report scan work: " + e.toString()); 1942fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1943fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1944fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 1945a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private void reportBatchedScanStop() { 1946fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande if (mUid == 0) 1947fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande return; 1948fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 1949fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande try { 1950fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande mBatteryStats.noteWifiBatchedScanStoppedFromSource(mWorkSource); 1951fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } catch (RemoteException e) { 1952d7cbebf7fa9081e294ecab38cfe82709f381e1c9Vinit Deshpande logw("failed to cleanup scan work: " + e.toString()); 1953fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1954fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1955fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 19567e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills // TODO migrate batterystats to accept scan duration per hour instead of csph 1957a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private int getCsph() { 19587e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills int totalScanDurationPerHour = 0; 195980640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius Collection<ScanSettings> settingsList = 196080640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius mBackgroundScanStateMachine.getBackgroundScanSettings(this); 196180640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius for (ScanSettings settings : settingsList) { 19627e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills int scanDurationMs = mChannelHelper.estimateScanDuration(settings); 1963297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills int scans_per_Hour = settings.periodInMs == 0 ? 1 : (3600 * 1000) / 1964297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills settings.periodInMs; 19657e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills totalScanDurationPerHour += scanDurationMs * scans_per_Hour; 1966fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1967fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 19687e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills return totalScanDurationPerHour / ChannelHelper.SCAN_PERIOD_PER_CHANNEL_MS; 1969fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1970fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 1971a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void reportScanWorkUpdate() { 1972fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande if (mScanWorkReported) { 1973fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande reportBatchedScanStop(); 1974fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande mScanWorkReported = false; 1975fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 197680640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius if (mBackgroundScanStateMachine.getBackgroundScanSettings(this).isEmpty()) { 1977fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande reportBatchedScanStart(); 1978fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande mScanWorkReported = true; 1979fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1980fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande } 1981fc42a2cd2d461dc39b6853c130bae7dc69ed68e3Vinit Deshpande 1982e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde @Override 1983e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde public String toString() { 19849e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills return "ClientInfo[uid=" + mUid + "," + mMessenger + "]"; 198584e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande } 1986a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 1987e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 1988a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 1989a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * This class is used to represent external clients to the WifiScanning Service. 1990a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 1991a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private class ExternalClientInfo extends ClientInfo { 1992a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private final AsyncChannel mChannel; 1993a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 1994a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * Indicates if the client is still connected 1995a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * If the client is no longer connected then messages to it will be silently dropped 1996a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 1997a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private boolean mDisconnected = false; 1998a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 1999a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ExternalClientInfo(int uid, Messenger messenger, AsyncChannel c) { 2000a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius super(uid, messenger); 2001a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mChannel = c; 2002a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (DBG) localLog("New client, channel: " + c); 2003e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2004e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 2005a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius @Override 2006a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void reportEvent(int what, int arg1, int arg2, Object obj) { 2007a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (!mDisconnected) { 2008a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mChannel.sendMessage(what, arg1, arg2, obj); 2009a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2010a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2011a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 2012a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius @Override 2013a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void cleanup() { 20148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills mDisconnected = true; 2015a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // Internal clients should not have any wifi change requests. So, keeping this cleanup 2016a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // only for external client because this will otherwise cause an infinite recursion 2017a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // when the internal client in WifiChangeStateMachine is cleaned up. 201819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mWifiChangeStateMachine.removeWifiChangeHandler(this); 2019c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius mPnoScanStateMachine.removePnoSettings(this); 2020a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius super.cleanup(); 2021a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2022a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2023daac2ad767f6047409987bb22812ab5f295e54dfVinit Deshpande 2024a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 2025a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * This class is used to represent internal clients to the WifiScanning Service. This is needed 2026a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * for communicating between State Machines. 2027a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * This leaves the onReportEvent method unimplemented, so that the clients have the freedom 2028a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * to handle the events as they need. 2029a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 2030a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private class InternalClientInfo extends ClientInfo { 2031a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private static final int INTERNAL_CLIENT_HANDLER = 0; 2032a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 2033a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 2034a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * The UID here is used to proxy the original external requester UID. 2035a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 2036a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius InternalClientInfo(int requesterUid, Messenger messenger) { 2037a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius super(requesterUid, messenger); 2038a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2039a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 2040a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius @Override 2041a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius public void reportEvent(int what, int arg1, int arg2, Object obj) { 2042a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius Message message = Message.obtain(); 2043a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius message.what = what; 2044a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius message.arg1 = arg1; 2045a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius message.arg2 = arg2; 2046a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius message.obj = obj; 2047a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius try { 2048a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mMessenger.send(message); 2049a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } catch (RemoteException e) { 2050a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius loge("Failed to send message: " + what); 2051a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2052a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2053a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 2054a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 2055a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * Send a message to the client handler which should reroute the message to the appropriate 2056a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * state machine. 2057a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 205848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills public void sendRequestToClientHandler(int what, ScanSettings settings, 205948444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills WorkSource workSource) { 2060a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius Message msg = Message.obtain(); 2061a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius msg.what = what; 2062a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius msg.arg2 = INTERNAL_CLIENT_HANDLER; 2063a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (settings != null) { 2064a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius Bundle bundle = new Bundle(); 2065a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius bundle.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); 206648444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills bundle.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource); 2067a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius msg.obj = bundle; 2068a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2069a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius msg.replyTo = mMessenger; 2070c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius msg.sendingUid = getUid(); 2071a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mClientHandler.sendMessage(msg); 2072a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2073a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius 2074a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 2075a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * Send a message to the client handler which should reroute the message to the appropriate 2076a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * state machine. 2077a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 207848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills public void sendRequestToClientHandler(int what) { 207948444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills sendRequestToClientHandler(what, null, null); 2080daac2ad767f6047409987bb22812ab5f295e54dfVinit Deshpande } 20819e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills 20829e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills @Override 20839e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills public String toString() { 20849e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills return "InternalClientInfo[]"; 20859e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills } 2086e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2087e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 208883a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande void replySucceeded(Message msg) { 2089e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (msg.replyTo != null) { 2090e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde Message reply = Message.obtain(); 2091e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde reply.what = WifiScanner.CMD_OP_SUCCEEDED; 2092e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde reply.arg2 = msg.arg2; 2093e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde try { 2094e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde msg.replyTo.send(reply); 2095e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } catch (RemoteException e) { 2096e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde // There's not much we can do if reply can't be sent! 2097e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2098e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } else { 2099e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde // locally generated message; doesn't need a reply! 2100e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2101e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2102e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 2103daac2ad767f6047409987bb22812ab5f295e54dfVinit Deshpande void replyFailed(Message msg, int reason, String description) { 21041814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande if (msg.replyTo != null) { 21051814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande Message reply = Message.obtain(); 21061814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande reply.what = WifiScanner.CMD_OP_FAILED; 21071814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande reply.arg2 = msg.arg2; 21081814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande reply.obj = new WifiScanner.OperationResult(reason, description); 21091814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande try { 21101814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande msg.replyTo.send(reply); 21111814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande } catch (RemoteException e) { 21121814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande // There's not much we can do if reply can't be sent! 21131814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande } 21141814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande } else { 21151814928371a30b11af31e2bbe5210c4337ed16f3Vinit Deshpande // locally generated message; doesn't need a reply! 2116e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2117e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2118e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 2119a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius /** 2120a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * Wifi Change state machine is used to handle any wifi change tracking requests. 2121a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius * TODO: This state machine doesn't handle driver loading/unloading yet. 2122a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius */ 2123578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills class WifiChangeStateMachine extends StateMachine 2124578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills implements WifiNative.SignificantWifiChangeEventHandler { 2125578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2126578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills private static final int MAX_APS_TO_TRACK = 3; 2127578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills private static final int MOVING_SCAN_PERIOD_MS = 10000; 2128578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills private static final int STATIONARY_SCAN_PERIOD_MS = 5000; 2129578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills private static final int MOVING_STATE_TIMEOUT_MS = 30000; 2130578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2131578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills State mDefaultState = new DefaultState(); 2132578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills State mStationaryState = new StationaryState(); 2133578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills State mMovingState = new MovingState(); 2134578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2135578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills private static final String ACTION_TIMEOUT = 2136578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills "com.android.server.WifiScanningServiceImpl.action.TIMEOUT"; 2137a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private PendingIntent mTimeoutIntent; 2138a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private ScanResult[] mCurrentBssids; 2139a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius private InternalClientInfo mInternalClientInfo; 2140578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 214119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private final Set<Pair<ClientInfo, Integer>> mActiveWifiChangeHandlers = new HashSet<>(); 214219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 2143578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills WifiChangeStateMachine(Looper looper) { 2144578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills super("SignificantChangeStateMachine", looper); 2145578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 21468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // CHECKSTYLE:OFF IndentationCheck 2147578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills addState(mDefaultState); 21488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills addState(mStationaryState, mDefaultState); 21498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills addState(mMovingState, mDefaultState); 21508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills // CHECKSTYLE:ON IndentationCheck 2151578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2152578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills setInitialState(mDefaultState); 2153578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2154578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 215519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius public void removeWifiChangeHandler(ClientInfo ci) { 215619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Iterator<Pair<ClientInfo, Integer>> iter = mActiveWifiChangeHandlers.iterator(); 215719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius while (iter.hasNext()) { 215819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Pair<ClientInfo, Integer> entry = iter.next(); 215919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (entry.first == ci) { 216019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius iter.remove(); 216119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 2162578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 216319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius untrackSignificantWifiChangeOnEmpty(); 2164578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2165578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2166578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills class DefaultState extends State { 2167578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2168578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public void enter() { 2169578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Entering IdleState"); 2170578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2171578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2172578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2173578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public boolean processMessage(Message msg) { 2174578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("DefaultState state got " + msg); 217519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 2176578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills switch (msg.what) { 217719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_START_TRACKING_CHANGE: 21785382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (addWifiChangeHandler(ci, msg.arg2)) { 21795382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replySucceeded(msg); 21805382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius transitionTo(mMovingState); 21815382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } else { 21825382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 21835382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 2184578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 218519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_STOP_TRACKING_CHANGE: 2186578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // nothing to do 2187578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 218819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: 2189578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills /* save configuration till we transition to moving state */ 2190578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills deferMessage(msg); 2191578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 2192a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius case WifiScanner.CMD_SCAN_RESULT: 219319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius // nothing to do 219419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius break; 2195578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills default: 2196578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return NOT_HANDLED; 2197578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2198578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return HANDLED; 2199578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2200578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2201578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2202578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills class StationaryState extends State { 2203578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2204578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public void enter() { 2205578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Entering StationaryState"); 2206578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills reportWifiStabilized(mCurrentBssids); 2207578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2208578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2209578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2210578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public boolean processMessage(Message msg) { 2211578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Stationary state got " + msg); 221219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 2213578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills switch (msg.what) { 221419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_START_TRACKING_CHANGE: 22155382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (addWifiChangeHandler(ci, msg.arg2)) { 22165382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replySucceeded(msg); 22175382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } else { 22185382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 22195382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 2220578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 222119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_STOP_TRACKING_CHANGE: 222219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius removeWifiChangeHandler(ci, msg.arg2); 2223578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 222419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: 2225578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills /* save configuration till we transition to moving state */ 2226578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills deferMessage(msg); 2227578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 222819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case CMD_WIFI_CHANGE_DETECTED: 222919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) localLog("Got wifi change detected"); 223019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius reportWifiChanged((ScanResult[]) msg.obj); 223119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius transitionTo(mMovingState); 223219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius break; 2233a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius case WifiScanner.CMD_SCAN_RESULT: 2234a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // nothing to do 2235a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius break; 2236578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills default: 2237578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return NOT_HANDLED; 2238578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2239578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return HANDLED; 2240578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2241578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2242578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2243578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills class MovingState extends State { 2244578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills boolean mWifiChangeDetected = false; 2245578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills boolean mScanResultsPending = false; 2246578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2247578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2248578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public void enter() { 2249578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Entering MovingState"); 225019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (mTimeoutIntent == null) { 225119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Intent intent = new Intent(ACTION_TIMEOUT, null); 225219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); 225319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 225419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mContext.registerReceiver( 225519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius new BroadcastReceiver() { 225619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius @Override 225719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius public void onReceive(Context context, Intent intent) { 225819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius sendMessage(CMD_WIFI_CHANGE_TIMEOUT); 225919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 226019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius }, new IntentFilter(ACTION_TIMEOUT)); 226119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 2262578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills issueFullScan(); 2263578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2264578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2265578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2266578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public boolean processMessage(Message msg) { 2267578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("MovingState state got " + msg); 226819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius ClientInfo ci = mClients.get(msg.replyTo); 2269578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills switch (msg.what) { 227019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_START_TRACKING_CHANGE: 22715382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (addWifiChangeHandler(ci, msg.arg2)) { 22725382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replySucceeded(msg); 22735382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } else { 22745382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); 22755382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 2276578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 227719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_STOP_TRACKING_CHANGE: 227819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius removeWifiChangeHandler(ci, msg.arg2); 2279578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 228019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: 228119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) localLog("Got configuration from app"); 228219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiScanner.WifiChangeSettings settings = 228319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius (WifiScanner.WifiChangeSettings) msg.obj; 228419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius reconfigureScan(settings); 228519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mWifiChangeDetected = false; 228619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius long unchangedDelay = settings.unchangedSampleSize * settings.periodInMs; 228719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mAlarmManager.cancel(mTimeoutIntent); 2288ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2289ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius mClock.elapsedRealtime() + unchangedDelay, 229019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mTimeoutIntent); 229119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius break; 2292a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius case WifiScanner.CMD_SCAN_RESULT: 2293578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Got scan results"); 2294578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (mScanResultsPending) { 2295578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("reconfiguring scan"); 2296578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills reconfigureScan((ScanData[])msg.obj, 2297578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills STATIONARY_SCAN_PERIOD_MS); 2298578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mWifiChangeDetected = false; 2299ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2300ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius mClock.elapsedRealtime() + MOVING_STATE_TIMEOUT_MS, 2301578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mTimeoutIntent); 2302578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mScanResultsPending = false; 2303578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2304578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 230519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case CMD_WIFI_CHANGE_DETECTED: 2306578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Change detected"); 2307578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mAlarmManager.cancel(mTimeoutIntent); 2308578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills reportWifiChanged((ScanResult[])msg.obj); 2309578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mWifiChangeDetected = true; 2310578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills issueFullScan(); 2311578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 231219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius case CMD_WIFI_CHANGE_TIMEOUT: 2313578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Got timeout event"); 2314578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (mWifiChangeDetected == false) { 2315578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills transitionTo(mStationaryState); 2316578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2317578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 2318578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills default: 2319578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return NOT_HANDLED; 2320578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2321578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return HANDLED; 2322578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2323578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2324578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2325578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public void exit() { 2326578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mAlarmManager.cancel(mTimeoutIntent); 2327578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2328578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2329578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills void issueFullScan() { 2330578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Issuing full scan"); 2331578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ScanSettings settings = new ScanSettings(); 2332578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.band = WifiScanner.WIFI_BAND_BOTH; 2333578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.periodInMs = MOVING_SCAN_PERIOD_MS; 2334578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 2335578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills addScanRequest(settings); 2336578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mScanResultsPending = true; 2337578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2338578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2339578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2340578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 234119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void reconfigureScan(ScanData[] results, int period) { 2342578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // find brightest APs and set them as sentinels 2343578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (results.length < MAX_APS_TO_TRACK) { 2344578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills localLog("too few APs (" + results.length + ") available to track wifi change"); 2345578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return; 2346578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2347578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2348578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills removeScanRequest(); 2349578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2350578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // remove duplicate BSSIDs 2351578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills HashMap<String, ScanResult> bssidToScanResult = new HashMap<String, ScanResult>(); 2352578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (ScanResult result : results[0].getResults()) { 2353578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ScanResult saved = bssidToScanResult.get(result.BSSID); 2354578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (saved == null) { 2355578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills bssidToScanResult.put(result.BSSID, result); 2356578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } else if (saved.level > result.level) { 2357578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills bssidToScanResult.put(result.BSSID, result); 2358578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2359578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2360578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2361578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // find brightest BSSIDs 2362578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ScanResult brightest[] = new ScanResult[MAX_APS_TO_TRACK]; 2363578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills Collection<ScanResult> results2 = bssidToScanResult.values(); 2364578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (ScanResult result : results2) { 2365578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int j = 0; j < brightest.length; j++) { 2366578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (brightest[j] == null 2367578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills || (brightest[j].level < result.level)) { 2368578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int k = brightest.length; k > (j + 1); k--) { 2369578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills brightest[k - 1] = brightest[k - 2]; 2370578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2371578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills brightest[j] = result; 2372578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills break; 2373578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2374578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2375578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2376578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2377578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // Get channels to scan for 2378578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ArrayList<Integer> channels = new ArrayList<Integer>(); 2379578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int i = 0; i < brightest.length; i++) { 2380578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills boolean found = false; 2381578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int j = i + 1; j < brightest.length; j++) { 2382578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (brightest[j].frequency == brightest[i].frequency) { 2383578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills found = true; 2384578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2385578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2386578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (!found) { 2387578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills channels.add(brightest[i].frequency); 2388578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2389578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2390578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2391578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Found " + channels.size() + " channels"); 2392578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2393578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // set scanning schedule 2394578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ScanSettings settings = new ScanSettings(); 2395578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 2396578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.channels = new ChannelSpec[channels.size()]; 2397578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int i = 0; i < channels.size(); i++) { 2398578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.channels[i] = new ChannelSpec(channels.get(i)); 2399578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2400578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2401578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings.periodInMs = period; 2402578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills addScanRequest(settings); 2403578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2404578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills WifiScanner.WifiChangeSettings settings2 = new WifiScanner.WifiChangeSettings(); 2405578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.rssiSampleSize = 3; 2406578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.lostApSampleSize = 3; 2407578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.unchangedSampleSize = 3; 2408578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.minApsBreachingThreshold = 2; 2409578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.bssidInfos = new BssidInfo[brightest.length]; 2410578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2411578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int i = 0; i < brightest.length; i++) { 2412578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills BssidInfo BssidInfo = new BssidInfo(); 2413578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills BssidInfo.bssid = brightest[i].BSSID; 2414578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills int threshold = (100 + brightest[i].level) / 32 + 2; 2415578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills BssidInfo.low = brightest[i].level - threshold; 2416578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills BssidInfo.high = brightest[i].level + threshold; 2417578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.bssidInfos[i] = BssidInfo; 2418578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2419578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Setting bssid=" + BssidInfo.bssid + ", " + 2420578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills "low=" + BssidInfo.low + ", high=" + BssidInfo.high); 2421578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2422578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2423578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills trackSignificantWifiChange(settings2); 2424578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mCurrentBssids = brightest; 2425578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2426578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 242719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void reconfigureScan(WifiScanner.WifiChangeSettings settings) { 2428578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2429578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (settings.bssidInfos.length < MAX_APS_TO_TRACK) { 2430578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills localLog("too few APs (" + settings.bssidInfos.length 2431578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills + ") available to track wifi change"); 2432578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills return; 2433578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2434578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2435578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Setting configuration specified by app"); 2436578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2437578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mCurrentBssids = new ScanResult[settings.bssidInfos.length]; 2438578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills HashSet<Integer> channels = new HashSet<Integer>(); 2439578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2440578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (int i = 0; i < settings.bssidInfos.length; i++) { 2441578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ScanResult result = new ScanResult(); 2442578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills result.BSSID = settings.bssidInfos[i].bssid; 2443578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills mCurrentBssids[i] = result; 2444578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills channels.add(settings.bssidInfos[i].frequencyHint); 2445578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2446578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2447578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // cancel previous scan 2448578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills removeScanRequest(); 2449578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2450578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // set new scanning schedule 2451578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills ScanSettings settings2 = new ScanSettings(); 2452578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 2453578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.channels = new ChannelSpec[channels.size()]; 2454578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills int i = 0; 2455578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills for (Integer channel : channels) { 2456578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.channels[i++] = new ChannelSpec(channel); 2457578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2458578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2459578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills settings2.periodInMs = settings.periodInMs; 2460578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills addScanRequest(settings2); 2461578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2462578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills // start tracking new APs 2463578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills trackSignificantWifiChange(settings); 2464578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2465578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2466578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2467578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills @Override 2468578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills public void onChangesFound(ScanResult results[]) { 246919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius sendMessage(CMD_WIFI_CHANGE_DETECTED, 0, 0, results); 2470578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2471578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 247219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void addScanRequest(ScanSettings settings) { 2473578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Starting scans"); 2474a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (mInternalClientInfo != null) { 247548444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mInternalClientInfo.sendRequestToClientHandler( 247648444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills WifiScanner.CMD_START_BACKGROUND_SCAN, settings, null); 2477a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2478578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2479578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 248019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void removeScanRequest() { 2481578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills if (DBG) localLog("Stopping scans"); 2482a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (mInternalClientInfo != null) { 248348444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills mInternalClientInfo.sendRequestToClientHandler( 2484a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius WifiScanner.CMD_STOP_BACKGROUND_SCAN); 2485a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 2486578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2487578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 248819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void trackSignificantWifiChange(WifiScanner.WifiChangeSettings settings) { 248911bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills if (mScannerImpl != null) { 249011bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills mScannerImpl.untrackSignificantWifiChange(); 249111bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills mScannerImpl.trackSignificantWifiChange(settings, this); 249211bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills } 2493578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2494578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 249519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void untrackSignificantWifiChange() { 249611bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills if (mScannerImpl != null) { 249711bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills mScannerImpl.untrackSignificantWifiChange(); 249811bb0926a6cc3380f2217532fefb9605a1fdc9e8Mitchell Wills } 2499578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2500578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 25015382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius private boolean addWifiChangeHandler(ClientInfo ci, int handler) { 25025382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (ci == null) { 25035382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius Log.d(TAG, "Failing wifi change request ClientInfo not found " + handler); 25045382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius return false; 25055382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 250619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mActiveWifiChangeHandlers.add(Pair.create(ci, handler)); 2507a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // Add an internal client to make background scan requests. 2508a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (mInternalClientInfo == null) { 2509a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mInternalClientInfo = 2510a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius new InternalClientInfo(ci.getUid(), new Messenger(this.getHandler())); 2511a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mInternalClientInfo.register(); 2512a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 25135382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius return true; 251419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 251519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 251619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void removeWifiChangeHandler(ClientInfo ci, int handler) { 25175382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius if (ci != null) { 25185382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius mActiveWifiChangeHandlers.remove(Pair.create(ci, handler)); 25195382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius untrackSignificantWifiChangeOnEmpty(); 25205382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius } 252119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 252219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 252319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void untrackSignificantWifiChangeOnEmpty() { 252419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (mActiveWifiChangeHandlers.isEmpty()) { 252519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius if (DBG) localLog("Got Disable Wifi Change"); 252619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius mCurrentBssids = null; 252719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius untrackSignificantWifiChange(); 2528a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius // Remove the internal client when there are no more external clients. 2529a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius if (mInternalClientInfo != null) { 2530a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mInternalClientInfo.cleanup(); 2531a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius mInternalClientInfo = null; 2532a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius } 253319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius transitionTo(mDefaultState); 253419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 253519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 253619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 253719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void reportWifiChanged(ScanResult[] results) { 253819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiScanner.ParcelableScanResults parcelableScanResults = 253919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius new WifiScanner.ParcelableScanResults(results); 254019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Iterator<Pair<ClientInfo, Integer>> it = mActiveWifiChangeHandlers.iterator(); 254119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius while (it.hasNext()) { 254219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Pair<ClientInfo, Integer> entry = it.next(); 254319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius ClientInfo ci = entry.first; 254419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int handler = entry.second; 2545a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ci.reportEvent(WifiScanner.CMD_WIFI_CHANGE_DETECTED, 0, handler, 254619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius parcelableScanResults); 254719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 254819a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 254919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius 255019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius private void reportWifiStabilized(ScanResult[] results) { 255119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius WifiScanner.ParcelableScanResults parcelableScanResults = 255219a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius new WifiScanner.ParcelableScanResults(results); 255319a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Iterator<Pair<ClientInfo, Integer>> it = mActiveWifiChangeHandlers.iterator(); 255419a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius while (it.hasNext()) { 255519a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius Pair<ClientInfo, Integer> entry = it.next(); 255619a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius ClientInfo ci = entry.first; 255719a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius int handler = entry.second; 2558a91494208927643d011b4fa62db2064d9e8228c1Roshan Pius ci.reportEvent(WifiScanner.CMD_WIFI_CHANGES_STABILIZED, 0, handler, 255919a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius parcelableScanResults); 256019a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 256119a7b07a44c1ce4cf2500d277ef31e3344868142Roshan Pius } 2562578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills } 2563578f7a33d0085559485bccfe7d1e26f813dc081dMitchell Wills 2564297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills private static String toString(int uid, ScanSettings settings) { 2565297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills StringBuilder sb = new StringBuilder(); 2566297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills sb.append("ScanSettings[uid=").append(uid); 2567297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills sb.append(", period=").append(settings.periodInMs); 2568297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills sb.append(", report=").append(settings.reportEvents); 2569297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills if (settings.reportEvents == WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL 2570297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills && settings.numBssidsPerScan > 0 2571297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills && settings.maxScansToCache > 1) { 2572297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills sb.append(", batch=").append(settings.maxScansToCache); 2573297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills sb.append(", numAP=").append(settings.numBssidsPerScan); 2574297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 257554e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills sb.append(", ").append(ChannelHelper.toString(settings)); 2576297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills sb.append("]"); 2577c3bf77a2810b67fcaeda388f094141080b2b3970Mitchell Wills 2578297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills return sb.toString(); 2579e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 2580e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 2581a879e0a04ca77d37e976e1de8e03c5d8e26b3a1bVinit Deshpande @Override 2582a879e0a04ca77d37e976e1de8e03c5d8e26b3a1bVinit Deshpande protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2583cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2584cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman != PackageManager.PERMISSION_GRANTED) { 2585cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman pw.println("Permission Denial: can't dump WifiScanner from from pid=" 2586cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman + Binder.getCallingPid() 2587cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman + ", uid=" + Binder.getCallingUid() 2588cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman + " without permission " 2589cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman + android.Manifest.permission.DUMP); 2590cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman return; 2591cbf5c1792df8509c1b0de0a1b73d1c004a83e4bfdcashman } 259265b752f1da25f028a204a88264380c610866c027Mitchell Wills pw.println("WifiScanningService - Log Begin ----"); 2593297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills mLocalLog.dump(fd, pw, args); 259465b752f1da25f028a204a88264380c610866c027Mitchell Wills pw.println("WifiScanningService - Log End ----"); 2595297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills pw.println(); 2596297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills pw.println("clients:"); 2597297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills for (ClientInfo client : mClients.values()) { 2598297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills pw.println(" " + client); 2599297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 2600297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills pw.println("listeners:"); 2601297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills for (ClientInfo client : mClients.values()) { 260280640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius Collection<ScanSettings> settingsList = 260380640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius mBackgroundScanStateMachine.getBackgroundScanSettings(client); 260480640ff4d13e252f0a5637ec16ca2d626070e751Roshan Pius for (ScanSettings settings : settingsList) { 2605297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills pw.println(" " + toString(client.mUid, settings)); 2606297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 2607297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 2608985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills if (mBackgroundScheduler != null) { 2609985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills WifiNative.ScanSettings schedule = mBackgroundScheduler.getSchedule(); 2610985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills if (schedule != null) { 2611985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills pw.println("schedule:"); 2612985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills pw.println(" base period: " + schedule.base_period_ms); 2613985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills pw.println(" max ap per scan: " + schedule.max_ap_per_scan); 2614985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills pw.println(" batched scans: " + schedule.report_threshold_num_scans); 2615985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills pw.println(" buckets:"); 2616985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills for (int b = 0; b < schedule.num_buckets; b++) { 2617985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills WifiNative.BucketSettings bucket = schedule.buckets[b]; 2618985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills pw.println(" bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)[" 2619985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills + bucket.report_events + "]: " 2620985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills + ChannelHelper.toString(bucket)); 2621985df17909a5703a86f3e665abc9dd964d9623d9Mitchell Wills } 2622297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 2623297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills } 2624d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills if (mPnoScanStateMachine != null) { 2625d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills mPnoScanStateMachine.dump(fd, pw, args); 2626d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills } 2627a879e0a04ca77d37e976e1de8e03c5d8e26b3a1bVinit Deshpande } 262884e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande 262944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills void logScanRequest(String request, ClientInfo ci, int id, WorkSource workSource, 263044f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills ScanSettings settings, PnoSettings pnoSettings) { 263184e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande StringBuilder sb = new StringBuilder(); 263217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius sb.append(request) 263348444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills .append(": ") 26345382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius .append((ci == null) ? "ClientInfo[unknown]" : ci.toString()) 263544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills .append(",Id=") 263644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills .append(id); 263744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills if (workSource != null) { 263848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills sb.append(",").append(workSource); 263944f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills } 264017ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius if (settings != null) { 264144f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills sb.append(", "); 264217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius describeTo(sb, settings); 264317ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 264417ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius if (pnoSettings != null) { 264544f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills sb.append(", "); 264617ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius describeTo(sb, pnoSettings); 264717ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 264817ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius localLog(sb.toString()); 264917ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 265084e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande 265159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills void logCallback(String callback, ClientInfo ci, int id, String extra) { 265217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius StringBuilder sb = new StringBuilder(); 265317ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius sb.append(callback) 265448444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills .append(": ") 26555382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius .append((ci == null) ? "ClientInfo[unknown]" : ci.toString()) 265644f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills .append(",Id=") 265744f8fc30974fa61a5a64be81874f6002ca0368f3Mitchell Wills .append(id); 265859298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills if (extra != null) { 265959298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills sb.append(",").append(extra); 266059298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills } 266117ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius localLog(sb.toString()); 266217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 266384e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande 266459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills static String describeForLog(ScanData[] results) { 266559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills StringBuilder sb = new StringBuilder(); 266659298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills sb.append("results="); 266759298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills for (int i = 0; i < results.length; ++i) { 266859298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills if (i > 0) sb.append(";"); 266959298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills sb.append(results[i].getResults().length); 267059298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills } 267159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills return sb.toString(); 267259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills } 267359298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills 267459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills static String describeForLog(ScanResult[] results) { 267559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills return "results=" + results.length; 267659298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills } 267759298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills 267817ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius static String describeTo(StringBuilder sb, ScanSettings scanSettings) { 267948444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills sb.append("ScanSettings { ") 268017ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" band:").append(scanSettings.band) 268117ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" period:").append(scanSettings.periodInMs) 268217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" reportEvents:").append(scanSettings.reportEvents) 268317ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" numBssidsPerScan:").append(scanSettings.numBssidsPerScan) 268417ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" maxScansToCache:").append(scanSettings.maxScansToCache) 268517ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" channels:[ "); 268684e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande if (scanSettings.channels != null) { 268784e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande for (int i = 0; i < scanSettings.channels.length; i++) { 268817ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius sb.append(scanSettings.channels[i].frequency) 268917ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" "); 269084e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande } 269184e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande } 269217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius sb.append(" ] ") 269317ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" } "); 269484e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande return sb.toString(); 269584e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande } 269684e718d76c7412121b64ed9ac497c8071f0ef5e9Vinit Deshpande 269717ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius static String describeTo(StringBuilder sb, PnoSettings pnoSettings) { 269848444cb4214a48a3a0bf4bbb93945c2aa68c9980Mitchell Wills sb.append("PnoSettings { ") 269917ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" min5GhzRssi:").append(pnoSettings.min5GHzRssi) 270017ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" min24GhzRssi:").append(pnoSettings.min24GHzRssi) 270117ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" initialScoreMax:").append(pnoSettings.initialScoreMax) 270217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" currentConnectionBonus:").append(pnoSettings.currentConnectionBonus) 270317ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" sameNetworkBonus:").append(pnoSettings.sameNetworkBonus) 270417ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" secureBonus:").append(pnoSettings.secureBonus) 270517ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" band5GhzBonus:").append(pnoSettings.band5GHzBonus) 27062c9840a1063fd74eae131260fda2841566fc6d62Roshan Pius .append(" isConnected:").append(pnoSettings.isConnected) 270717ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" networks:[ "); 270817ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius if (pnoSettings.networkList != null) { 270917ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius for (int i = 0; i < pnoSettings.networkList.length; i++) { 271017ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius sb.append(pnoSettings.networkList[i].ssid) 271117ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(",") 271217ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(pnoSettings.networkList[i].networkId) 271317ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" "); 271417ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 271517ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 271617ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius sb.append(" ] ") 271717ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius .append(" } "); 271817ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius return sb.toString(); 271917ada7f5241dfbc44eecc6db43105709f2dbf04fRoshan Pius } 2720e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 2721