summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Greenwalt <rgreenwalt@google.com>2013-06-25 11:41:53 -0700
committerThe Android Automerger <android-build@android.com>2013-06-28 14:36:40 -0700
commit46bb6d6cb7ee4002fe6c306a1f027d536272f617 (patch)
treeb94a298e5acb1b48de55aa5fdf9783e973c23257
parent8d41901e6669b5916f4fcbbf262445ca906e1556 (diff)
downloadbase-46bb6d6cb7ee4002fe6c306a1f027d536272f617.tar.gz
Fix power issues around wifi scans.
- Sending a broadcast indicating when scan requests could be serviced so that apps don't request scans we won't do anything with. - Fix our batt stats accounting so we only count it if we send the request to the driver. bug: 8868201 bug: 9496690 Change-Id: I64a4f1c294c848ac64c50d8854ed4a6a1a47f603
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--services/java/com/android/server/wifi/WifiService.java56
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java12
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java56
4 files changed, 65 insertions, 60 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 619a10b9ef75..9624f15ceb3a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -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" />
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index 66ef97808dd1..a70978ee6c4b 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -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() {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ec76a8b5ee37..a3c172adad3a 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -70,6 +70,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.
* Another extra provides the previous state, if available.
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 32d48ac16320..58ae8dcee4f5 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -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) {
@@ -1544,6 +1574,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);
@@ -1888,6 +1919,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:
@@ -1902,7 +1934,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:
@@ -2405,11 +2436,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:
@@ -2530,6 +2568,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.
}
}
@@ -2680,6 +2724,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:
@@ -2943,6 +2988,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 */
@@ -3260,7 +3306,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);
}