Merge "WifiLock extensions for high performance mode"

This commit is contained in:
Irfan Sheriff
2010-10-26 16:08:29 -07:00
committed by Android (Google) Code Review
5 changed files with 112 additions and 35 deletions

View File

@@ -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 },
};

View File

@@ -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;

View File

@@ -338,6 +338,16 @@ public class WifiManager {
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
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
@@ -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

View File

@@ -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.

View File

@@ -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);
}