Merge "WifiLock extensions for high performance mode"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a8413beb39
@@ -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 },
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user