am 65f7a95f: am 2f50097a: Merge "Fix power issues around wifi scans." into jb-mr2-dev

* commit '65f7a95fc4c06127e7372bcb0d14e561cc23dd80':
  Fix power issues around wifi scans.
This commit is contained in:
Robert Greenwalt
2013-06-26 10:55:00 -07:00
committed by Android Git Automerger
4 changed files with 65 additions and 60 deletions

View File

@@ -156,6 +156,7 @@
<protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
<protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
<protected-broadcast android:name="android.net.wifi.WIFI_SCAN_AVAILABLE" />
<protected-broadcast android:name="android.net.wifi.SCAN_RESULTS" />
<protected-broadcast android:name="android.net.wifi.RSSI_CHANGED" />
<protected-broadcast android:name="android.net.wifi.STATE_CHANGE" />

View File

@@ -114,10 +114,6 @@ public final class WifiService extends IWifiManager.Stub {
/* 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
*/
@@ -255,17 +251,6 @@ public final class WifiService extends IWifiManager.Stub {
},
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.
@@ -274,44 +259,6 @@ public final class WifiService extends IWifiManager.Stub {
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
@@ -352,8 +299,7 @@ public final class WifiService extends IWifiManager.Stub {
*/
public void startScan() {
enforceChangePermission();
mWifiStateMachine.startScan();
noteScanStart();
mWifiStateMachine.startScan(Binder.getCallingUid());
}
private void enforceAccessPermission() {

View File

@@ -69,6 +69,18 @@ public class WifiManager {
*/
public static final int ERROR_AUTHENTICATING = 1;
/**
* Broadcast intent action indicating whether Wi-Fi scanning is allowed currently
* @hide
*/
public static final String WIFI_SCAN_AVAILABLE = "wifi_scan_available";
/**
* Extra int indicating scan availability, WIFI_STATE_ENABLED and WIFI_STATE_DISABLED
* @hide
*/
public static final String EXTRA_SCAN_AVAILABLE = "scan_enabled";
/**
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
* enabling, disabling, or unknown. One extra provides this state as an int.

View File

@@ -141,6 +141,8 @@ public class WifiStateMachine extends StateMachine {
*/
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.
*/
@@ -601,7 +603,7 @@ public class WifiStateMachine extends StateMachine {
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
startScan();
startScan(UNKNOWN_SCAN_SOURCE);
}
},
new IntentFilter(ACTION_START_SCAN));
@@ -694,6 +696,11 @@ public class WifiStateMachine extends StateMachine {
//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);
}
/*********************************************************
@@ -716,8 +723,31 @@ public class WifiStateMachine extends StateMachine {
/**
* 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) {
@@ -1575,6 +1605,7 @@ public class WifiStateMachine extends StateMachine {
}
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);
@@ -1919,6 +1950,7 @@ public class WifiStateMachine extends StateMachine {
}
break;
/* Discard */
case CMD_START_SCAN:
case CMD_START_SUPPLICANT:
case CMD_STOP_SUPPLICANT:
case CMD_STOP_SUPPLICANT_FAILED:
@@ -1933,7 +1965,6 @@ public class WifiStateMachine extends StateMachine {
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:
@@ -2438,11 +2469,18 @@ public class WifiStateMachine extends StateMachine {
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:
@@ -2563,6 +2601,12 @@ public class WifiStateMachine extends StateMachine {
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.
}
}
@@ -2713,6 +2757,7 @@ public class WifiStateMachine extends StateMachine {
// 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:
@@ -2979,6 +3024,7 @@ public class WifiStateMachine extends StateMachine {
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 */
@@ -3296,7 +3342,7 @@ public class WifiStateMachine extends StateMachine {
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);
}