summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrfan Sheriff <isheriff@google.com>2010-10-26 16:08:29 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-10-26 16:08:29 -0700
commita8413beb39b6b75e9b77ded4388e73f22bda556e (patch)
tree00537ae5a80c56ef8a7a8ab7835aebed5f7f2dc7
parente1838c773d45296dc4da6c325fea2d636b0fd0b4 (diff)
parent5876a4273e67271f0eca607af9520f7e5abbe4f3 (diff)
downloadframeworks_base-a8413beb39b6b75e9b77ded4388e73f22bda556e.zip
frameworks_base-a8413beb39b6b75e9b77ded4388e73f22bda556e.tar.gz
frameworks_base-a8413beb39b6b75e9b77ded4388e73f22bda556e.tar.bz2
Merge "WifiLock extensions for high performance mode"
-rw-r--r--core/jni/android_net_wifi_Wifi.cpp11
-rw-r--r--services/java/com/android/server/WifiService.java42
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java14
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java2
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java78
5 files changed, 112 insertions, 35 deletions
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 27d4b9e..a024420 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -571,6 +571,15 @@ static jboolean android_net_wifi_clearBlacklistCommand(JNIEnv* env, jobject claz
return doBooleanCommand("BLACKLIST clear", "OK");
}
+static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, jobject clazz, jboolean enabled)
+{
+ char cmdstr[BUF_SIZE];
+
+ snprintf(cmdstr, sizeof(cmdstr), "DRIVER SETSUSPENDOPT %d", enabled ? 0 : 1);
+ return doBooleanCommand(cmdstr, "OK");
+}
+
+
static jboolean android_net_wifi_doDhcpRequest(JNIEnv* env, jobject clazz, jobject info)
{
jint ipaddr, gateway, mask, dns1, dns2, server, lease;
@@ -657,6 +666,8 @@ static JNINativeMethod gWifiMethods[] = {
(void*) android_net_wifi_wpsPinFromAccessPointCommand },
{ "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)I",
(void*) android_net_wifi_wpsPinFromDeviceCommand },
+ { "setSuspendOptimizationsCommand", "(Z)Z",
+ (void*) android_net_wifi_setSuspendOptimizationsCommand},
{ "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest },
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError },
};
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 92588fc..210fe8a 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -102,6 +102,8 @@ public class WifiService extends IWifiManager.Stub {
private final LockList mLocks = new LockList();
// some wifi lock statistics
+ private int mFullHighPerfLocksAcquired;
+ private int mFullHighPerfLocksReleased;
private int mFullLocksAcquired;
private int mFullLocksReleased;
private int mScanLocksAcquired;
@@ -1040,12 +1042,15 @@ public class WifiService extends IWifiManager.Stub {
boolean wifiEnabled = getPersistedWifiEnabled();
boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden.get();
boolean lockHeld = mLocks.hasLocks();
- int strongestLockMode;
+ int strongestLockMode = WifiManager.WIFI_MODE_FULL;
boolean wifiShouldBeEnabled = wifiEnabled && !airplaneMode;
boolean wifiShouldBeStarted = !mDeviceIdle || lockHeld;
- if (mDeviceIdle && lockHeld) {
+
+ if (lockHeld) {
strongestLockMode = mLocks.getStrongestLockMode();
- } else {
+ }
+ /* If device is not idle, lockmode cannot be scan only */
+ if (!mDeviceIdle && strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY) {
strongestLockMode = WifiManager.WIFI_MODE_FULL;
}
@@ -1067,6 +1072,8 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateMachine.setDriverStart(true);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
+ mWifiStateMachine.setHighPerfModeEnabled(strongestLockMode
+ == WifiManager.WIFI_MODE_FULL_HIGH_PERF);
} else {
mWifiStateMachine.requestCmWakeLock();
mWifiStateMachine.setDriverStart(false);
@@ -1145,8 +1152,10 @@ public class WifiService extends IWifiManager.Stub {
}
pw.println();
pw.println("Locks acquired: " + mFullLocksAcquired + " full, " +
+ mFullHighPerfLocksAcquired + " full high perf, " +
mScanLocksAcquired + " scan");
pw.println("Locks released: " + mFullLocksReleased + " full, " +
+ mFullHighPerfLocksReleased + " full high perf, " +
mScanLocksReleased + " scan");
pw.println();
pw.println("Locks held:");
@@ -1184,11 +1193,15 @@ public class WifiService extends IWifiManager.Stub {
if (mList.isEmpty()) {
return WifiManager.WIFI_MODE_FULL;
}
- for (WifiLock l : mList) {
- if (l.mMode == WifiManager.WIFI_MODE_FULL) {
- return WifiManager.WIFI_MODE_FULL;
- }
+
+ if (mFullHighPerfLocksAcquired > mFullHighPerfLocksReleased) {
+ return WifiManager.WIFI_MODE_FULL_HIGH_PERF;
}
+
+ if (mFullLocksAcquired > mFullLocksReleased) {
+ return WifiManager.WIFI_MODE_FULL;
+ }
+
return WifiManager.WIFI_MODE_SCAN_ONLY;
}
@@ -1235,7 +1248,11 @@ public class WifiService extends IWifiManager.Stub {
public boolean acquireWifiLock(IBinder binder, int lockMode, String tag, WorkSource ws) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
- if (lockMode != WifiManager.WIFI_MODE_FULL && lockMode != WifiManager.WIFI_MODE_SCAN_ONLY) {
+ if (lockMode != WifiManager.WIFI_MODE_FULL &&
+ lockMode != WifiManager.WIFI_MODE_SCAN_ONLY &&
+ lockMode != WifiManager.WIFI_MODE_FULL_HIGH_PERF) {
+ Slog.e(TAG, "Illegal argument, lockMode= " + lockMode);
+ if (DBG) throw new IllegalArgumentException("lockMode=" + lockMode);
return false;
}
if (ws != null && ws.size() == 0) {
@@ -1256,6 +1273,7 @@ public class WifiService extends IWifiManager.Stub {
private void noteAcquireWifiLock(WifiLock wifiLock) throws RemoteException {
switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
+ case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
break;
case WifiManager.WIFI_MODE_SCAN_ONLY:
@@ -1267,6 +1285,7 @@ public class WifiService extends IWifiManager.Stub {
private void noteReleaseWifiLock(WifiLock wifiLock) throws RemoteException {
switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
+ case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
break;
case WifiManager.WIFI_MODE_SCAN_ONLY:
@@ -1287,6 +1306,10 @@ public class WifiService extends IWifiManager.Stub {
case WifiManager.WIFI_MODE_FULL:
++mFullLocksAcquired;
break;
+ case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
+ ++mFullHighPerfLocksAcquired;
+ break;
+
case WifiManager.WIFI_MODE_SCAN_ONLY:
++mScanLocksAcquired;
break;
@@ -1356,6 +1379,9 @@ public class WifiService extends IWifiManager.Stub {
case WifiManager.WIFI_MODE_FULL:
++mFullLocksReleased;
break;
+ case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
+ ++mFullHighPerfLocksReleased;
+ break;
case WifiManager.WIFI_MODE_SCAN_ONLY:
++mScanLocksReleased;
break;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 84d615c..356a0bd 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -339,6 +339,16 @@ public class WifiManager {
public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
/**
+ * In this Wi-Fi lock mode, Wi-Fi will behave as in the mode
+ * {@link #WIFI_MODE_FULL} but it operates at high performance
+ * at the expense of power. This mode should be used
+ * only when the wifi connection needs to have minimum loss and low
+ * latency as it can impact the battery life.
+ * @hide
+ */
+ public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
+
+ /**
* In this Wi-Fi lock mode, Wi-Fi will be kept active,
* and will behave normally, i.e., it will attempt to automatically
* establish a connection to a remembered access point that is
@@ -1261,8 +1271,8 @@ public class WifiManager {
/**
* Creates a new WifiLock.
*
- * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL} and
- * {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks.
+ * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},
+ * and {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks.
* @param tag a tag for the WifiLock to identify it in debugging messages. This string is
* never shown to the user under normal conditions, but should be descriptive
* enough to identify your application and the specific WifiLock within it, if it
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 313ae0b..3d8157c 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -161,6 +161,8 @@ public class WifiNative {
public native static String getDhcpError();
+ public native static boolean setSuspendOptimizationsCommand(boolean enabled);
+
/**
* Wait for the supplicant to send an event, returning the event string.
* @return the event string sent by the supplicant.
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index faafb7a..6bd67cc 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -246,11 +246,20 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private static final int CMD_RECONNECT = 75;
/* Reassociate to a network */
private static final int CMD_REASSOCIATE = 76;
- /* Set power mode
- * POWER_MODE_ACTIVE
- * POWER_MODE_AUTO
+ /* Controls power mode and suspend mode optimizations
+ *
+ * When high perf mode is enabled, power mode is set to
+ * POWER_MODE_ACTIVE and suspend mode optimizations are disabled
+ *
+ * When high perf mode is disabled, power mode is set to
+ * POWER_MODE_AUTO and suspend mode optimizations are enabled
+ *
+ * Suspend mode optimizations include:
+ * - packet filtering
+ * - turn off roaming
+ * - DTIM wake up settings
*/
- private static final int CMD_SET_POWER_MODE = 77;
+ private static final int CMD_SET_HIGH_PERF_MODE = 77;
/* Set bluetooth co-existence
* BLUETOOTH_COEXISTENCE_MODE_ENABLED
* BLUETOOTH_COEXISTENCE_MODE_DISABLED
@@ -335,8 +344,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
*/
private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
- private static final int DRIVER_POWER_MODE_ACTIVE = 1;
- private static final int DRIVER_POWER_MODE_AUTO = 0;
+ private static final int POWER_MODE_ACTIVE = 1;
+ private static final int POWER_MODE_AUTO = 0;
/* Default parent state */
private HierarchicalState mDefaultState = new DefaultState();
@@ -856,13 +865,13 @@ public class WifiStateMachine extends HierarchicalStateMachine {
}
/**
- * Set power mode
- * @param mode
- * DRIVER_POWER_MODE_AUTO
- * DRIVER_POWER_MODE_ACTIVE
+ * Set high performance mode of operation.
+ * Enabling would set active power mode and disable suspend optimizations;
+ * disabling would set auto power mode and enable suspend optimizations
+ * @param enable true if enable, false otherwise
*/
- public void setPowerMode(int mode) {
- sendMessage(obtainMessage(CMD_SET_POWER_MODE, mode, 0));
+ public void setHighPerfModeEnabled(boolean enable) {
+ sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
}
/**
@@ -1269,6 +1278,21 @@ public class WifiStateMachine extends HierarchicalStateMachine {
return null;
}
+ private void setHighPerfModeEnabledNative(boolean enable) {
+ if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
+ Log.e(TAG, "set suspend optimizations failed!");
+ }
+ if (enable) {
+ if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
+ Log.e(TAG, "set power mode active failed!");
+ }
+ } else {
+ if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
+ Log.e(TAG, "set power mode auto failed!");
+ }
+ }
+ }
+
private void configureLinkProperties() {
if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
@@ -1654,7 +1678,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_CLEAR_BLACKLIST:
case CMD_SET_SCAN_MODE:
case CMD_SET_SCAN_TYPE:
- case CMD_SET_POWER_MODE:
+ case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_BLUETOOTH_COEXISTENCE:
case CMD_SET_BLUETOOTH_SCAN_MODE:
case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -1756,7 +1780,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_STOP_DRIVER:
case CMD_SET_SCAN_MODE:
case CMD_SET_SCAN_TYPE:
- case CMD_SET_POWER_MODE:
+ case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_BLUETOOTH_COEXISTENCE:
case CMD_SET_BLUETOOTH_SCAN_MODE:
case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -1884,7 +1908,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_STOP_DRIVER:
case CMD_SET_SCAN_MODE:
case CMD_SET_SCAN_TYPE:
- case CMD_SET_POWER_MODE:
+ case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_BLUETOOTH_COEXISTENCE:
case CMD_SET_BLUETOOTH_SCAN_MODE:
case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -1981,7 +2005,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_STOP_DRIVER:
case CMD_SET_SCAN_MODE:
case CMD_SET_SCAN_TYPE:
- case CMD_SET_POWER_MODE:
+ case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_BLUETOOTH_COEXISTENCE:
case CMD_SET_BLUETOOTH_SCAN_MODE:
case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -2138,7 +2162,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case NETWORK_DISCONNECTION_EVENT:
case PASSWORD_MAY_BE_INCORRECT_EVENT:
case CMD_SET_SCAN_TYPE:
- case CMD_SET_POWER_MODE:
+ case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_BLUETOOTH_COEXISTENCE:
case CMD_SET_BLUETOOTH_SCAN_MODE:
case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -2192,8 +2216,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
WifiNative.setScanModeCommand(false);
}
break;
- case CMD_SET_POWER_MODE:
- WifiNative.setPowerModeCommand(message.arg1);
+ case CMD_SET_HIGH_PERF_MODE:
+ setHighPerfModeEnabledNative(message.arg1 == 1);
break;
case CMD_SET_BLUETOOTH_COEXISTENCE:
WifiNative.setBluetoothCoexistenceModeCommand(message.arg1);
@@ -2256,7 +2280,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_START_DRIVER:
case CMD_STOP_DRIVER:
case CMD_SET_SCAN_TYPE:
- case CMD_SET_POWER_MODE:
+ case CMD_SET_HIGH_PERF_MODE:
case CMD_SET_BLUETOOTH_COEXISTENCE:
case CMD_SET_BLUETOOTH_SCAN_MODE:
case CMD_SET_NUM_ALLOWED_CHANNELS:
@@ -2505,7 +2529,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
if (!mUseStaticIp) {
mDhcpThread = null;
mModifiedBluetoothCoexistenceMode = false;
- mPowerMode = DRIVER_POWER_MODE_AUTO;
+ mPowerMode = POWER_MODE_AUTO;
if (shouldDisableCoexistenceMode()) {
/*
@@ -2535,10 +2559,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
if (mPowerMode < 0) {
// Handle the case where supplicant driver does not support
// getPowerModeCommand.
- mPowerMode = DRIVER_POWER_MODE_AUTO;
+ mPowerMode = POWER_MODE_AUTO;
}
- if (mPowerMode != DRIVER_POWER_MODE_ACTIVE) {
- WifiNative.setPowerModeCommand(DRIVER_POWER_MODE_ACTIVE);
+ if (mPowerMode != POWER_MODE_ACTIVE) {
+ WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
}
Log.d(TAG, "DHCP request started");
@@ -2639,6 +2663,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_RECONFIGURE_IP:
deferMessage(message);
break;
+ /* Defer any power mode changes since we must keep active power mode at DHCP */
+ case CMD_SET_HIGH_PERF_MODE:
+ deferMessage(message);
+ break;
default:
return NOT_HANDLED;
}
@@ -2650,7 +2678,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
public void exit() {
/* reset power state & bluetooth coexistence if on DHCP */
if (!mUseStaticIp) {
- if (mPowerMode != DRIVER_POWER_MODE_ACTIVE) {
+ if (mPowerMode != POWER_MODE_ACTIVE) {
WifiNative.setPowerModeCommand(mPowerMode);
}