/* Tracks the persisted states for wi-fi & airplane mode */
final WifiSettingsStore mSettingsStore;
- /* The work source (UID) that triggered the current WIFI scan, synchronized
- * on this */
- private WorkSource mScanWorkSource;
-
/**
* Asynchronous channel to WifiStateMachine
*/
},
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
- mContext.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(
- WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
- noteScanEnd();
- }
- }
- }, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
-
// Adding optimizations of only receiving broadcasts when wifi is enabled
// can result in race conditions when apps toggle wifi in the background
// without active user involvement. Always receive broadcasts.
private WifiController mWifiController;
- /** Tell battery stats about a new WIFI scan */
- private void noteScanStart() {
- WorkSource scanWorkSource = null;
- synchronized (WifiService.this) {
- if (mScanWorkSource != null) {
- // Scan already in progress, don't add this one to battery stats
- return;
- }
- scanWorkSource = new WorkSource(Binder.getCallingUid());
- mScanWorkSource = scanWorkSource;
- }
-
- long id = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteWifiScanStartedFromSource(scanWorkSource);
- } catch (RemoteException e) {
- Log.w(TAG, e);
- } finally {
- Binder.restoreCallingIdentity(id);
- }
- }
-
- /** Tell battery stats that the current WIFI scan has completed */
- private void noteScanEnd() {
- WorkSource scanWorkSource = null;
- synchronized (WifiService.this) {
- scanWorkSource = mScanWorkSource;
- mScanWorkSource = null;
- }
- if (scanWorkSource != null) {
- try {
- mBatteryStats.noteWifiScanStoppedFromSource(scanWorkSource);
- } catch (RemoteException e) {
- Log.w(TAG, e);
- }
- }
- }
-
/**
* Check if Wi-Fi needs to be enabled and start
* if needed
*/
public void startScan() {
enforceChangePermission();
- mWifiStateMachine.startScan();
- noteScanStart();
+ mWifiStateMachine.startScan(Binder.getCallingUid());
}
private void enforceAccessPermission() {
*/
private int mOperationalMode = CONNECT_MODE;
private boolean mScanResultIsPending = false;
+ private WorkSource mScanWorkSource = null;
+ private static final int UNKNOWN_SCAN_SOURCE = -1;
/* Tracks if state machine has received any screen state change broadcast yet.
* We can miss one of these at boot.
*/
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- startScan();
+ startScan(UNKNOWN_SCAN_SOURCE);
}
},
new IntentFilter(ACTION_START_SCAN));
//start the state machine
start();
+
+ final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
/*********************************************************
/**
* TODO: doc
*/
- public void startScan() {
- sendMessage(CMD_START_SCAN);
+ public void startScan(int callingUid) {
+ sendMessage(CMD_START_SCAN, callingUid);
+ }
+
+ private void noteScanStart(int callingUid) {
+ if (mScanWorkSource == null && callingUid != UNKNOWN_SCAN_SOURCE) {
+ mScanWorkSource = new WorkSource(callingUid);
+ try {
+ mBatteryStats.noteWifiScanStartedFromSource(mScanWorkSource);
+ } catch (RemoteException e) {
+ log(e.toString());
+ }
+ }
+ }
+
+ private void noteScanEnd() {
+ if (mScanWorkSource != null) {
+ try {
+ mBatteryStats.noteWifiScanStoppedFromSource(mScanWorkSource);
+ } catch (RemoteException e) {
+ log(e.toString());
+ } finally {
+ mScanWorkSource = null;
+ }
+ }
}
private void startScanNative(int type) {
}
private void sendScanResultsAvailableBroadcast() {
+ noteScanEnd();
Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
break;
/* Discard */
+ case CMD_START_SCAN:
case CMD_START_SUPPLICANT:
case CMD_STOP_SUPPLICANT:
case CMD_STOP_SUPPLICANT_FAILED:
case CMD_STOP_AP:
case CMD_TETHER_STATE_CHANGE:
case CMD_TETHER_NOTIFICATION_TIMED_OUT:
- case CMD_START_SCAN:
case CMD_DISCONNECT:
case CMD_RECONNECT:
case CMD_REASSOCIATE:
mWifiNative.setPowerSave(true);
if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
+
+ final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_ENABLED);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
+
@Override
public boolean processMessage(Message message) {
switch(message.what) {
case CMD_START_SCAN:
+ noteScanStart(message.arg1);
startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
break;
case CMD_SET_COUNTRY_CODE:
mIsRunning = false;
updateBatteryWorkSource(null);
mScanResults = new ArrayList<ScanResult>();
+
+ final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ noteScanEnd(); // wrap up any pending request.
}
}
// Handle scan. All the connection related commands are
// handled only in ConnectModeState
case CMD_START_SCAN:
+ noteScanStart(message.arg1);
startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP);
break;
default:
break;
case CMD_START_SCAN:
/* Do not attempt to connect when we are already connected */
+ noteScanStart(message.arg1);
startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP);
break;
/* Ignore connection to same network */
if (mP2pConnected.get()) break;
if (message.arg1 == mPeriodicScanToken &&
mWifiConfigStore.getConfiguredNetworks().size() == 0) {
- sendMessage(CMD_START_SCAN);
+ sendMessage(CMD_START_SCAN, UNKNOWN_SCAN_SOURCE);
sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
}