diff options
| author | Irfan Sheriff <isheriff@google.com> | 2010-10-26 16:08:29 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-10-26 16:08:29 -0700 |
| commit | a8413beb39b6b75e9b77ded4388e73f22bda556e (patch) | |
| tree | 00537ae5a80c56ef8a7a8ab7835aebed5f7f2dc7 | |
| parent | e1838c773d45296dc4da6c325fea2d636b0fd0b4 (diff) | |
| parent | 5876a4273e67271f0eca607af9520f7e5abbe4f3 (diff) | |
| download | frameworks_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.cpp | 11 | ||||
| -rw-r--r-- | services/java/com/android/server/WifiService.java | 42 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 14 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 2 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 78 |
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); } |
