Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c11e952 authored by Irfan Sheriff's avatar Irfan Sheriff
Browse files

DO NOT MERGE WifiLock extensions for high performance mode

Add extension to WifiLock to allow apps to operate
in high performance mode (high power & disable suspend
optimizations for battery consumption).

Bug: 2834260
Change-Id: I8b33d307f3d569bc92ba2139b9ed224ffc147547
parent e6bfceeb
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -493,6 +493,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[25];

    snprintf(cmdstr, sizeof(cmdstr), "DRIVER SETSUSPEND %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;
@@ -571,6 +580,7 @@ static JNINativeMethod gWifiMethods[] = {
    { "setScanResultHandlingCommand", "(I)Z", (void*) android_net_wifi_setScanResultHandlingCommand },
    { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
    { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
    { "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 },
+39 −12
Original line number Diff line number Diff line
@@ -116,6 +116,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;
@@ -1782,8 +1784,8 @@ public class WifiService extends IWifiManager.Stub {
        msg.sendToTarget();
    }

    private void sendStartMessage(boolean scanOnlyMode) {
        Message.obtain(mWifiHandler, MESSAGE_START_WIFI, scanOnlyMode ? 1 : 0, 0).sendToTarget();
    private void sendStartMessage(int lockMode) {
        Message.obtain(mWifiHandler, MESSAGE_START_WIFI, lockMode, 0).sendToTarget();
    }

    private void sendAccessPointMessage(boolean enable, WifiConfiguration wifiConfig, int uid) {
@@ -1801,12 +1803,15 @@ public class WifiService extends IWifiManager.Stub {
        boolean wifiEnabled = getPersistedWifiEnabled();
        boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden;
        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;
        }

@@ -1827,7 +1832,7 @@ public class WifiService extends IWifiManager.Stub {
                    sWakeLock.acquire();
                    sendEnableMessage(true, false, mLastEnableUid);
                    sWakeLock.acquire();
                    sendStartMessage(strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY);
                    sendStartMessage(strongestLockMode);
                } else if (!mWifiStateTracker.isDriverStopped()) {
                    int wakeLockTimeout =
                            Settings.Secure.getInt(
@@ -1905,8 +1910,10 @@ public class WifiService extends IWifiManager.Stub {
                    break;

                case MESSAGE_START_WIFI:
                    mWifiStateTracker.setScanOnlyMode(msg.arg1 != 0);
                    mWifiStateTracker.setScanOnlyMode(msg.arg1 == WifiManager.WIFI_MODE_SCAN_ONLY);
                    mWifiStateTracker.restart();
                    mWifiStateTracker.setHighPerfMode(msg.arg1 ==
                            WifiManager.WIFI_MODE_FULL_HIGH_PERF);
                    sWakeLock.release();
                    break;

@@ -1986,8 +1993,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:");
@@ -2042,11 +2051,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;
        }

@@ -2085,7 +2098,11 @@ public class WifiService extends IWifiManager.Stub {

    public boolean acquireWifiLock(IBinder binder, int lockMode, String tag) {
        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;
        }
        WifiLock wifiLock = new WifiLock(lockMode, tag, binder);
@@ -2107,6 +2124,12 @@ public class WifiService extends IWifiManager.Stub {
                ++mFullLocksAcquired;
                mBatteryStats.noteFullWifiLockAcquired(uid);
                break;
            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
                ++mFullHighPerfLocksAcquired;
                /* Treat high power as a full lock for battery stats */
                mBatteryStats.noteFullWifiLockAcquired(uid);
                break;

            case WifiManager.WIFI_MODE_SCAN_ONLY:
                ++mScanLocksAcquired;
                mBatteryStats.noteScanWifiLockAcquired(uid);
@@ -2146,6 +2169,10 @@ public class WifiService extends IWifiManager.Stub {
                        ++mFullLocksReleased;
                        mBatteryStats.noteFullWifiLockReleased(uid);
                        break;
                    case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
                        ++mFullHighPerfLocksReleased;
                        mBatteryStats.noteFullWifiLockReleased(uid);
                        break;
                    case WifiManager.WIFI_MODE_SCAN_ONLY:
                        ++mScanLocksReleased;
                        mBatteryStats.noteScanWifiLockReleased(uid);
+13 −2
Original line number Diff line number Diff line
@@ -306,6 +306,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
@@ -993,8 +1003,9 @@ 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},
     * {@link #WIFI_MODE_SCAN_ONLY} and {@link #WIFI_MODE_FULL_HIGH_PERF} 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
+2 −0
Original line number Diff line number Diff line
@@ -149,6 +149,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.
+99 −4
Original line number Diff line number Diff line
@@ -276,6 +276,9 @@ public class WifiStateTracker extends NetworkStateTracker {
    
    private boolean mIsScanModeActive;
    private boolean mEnableRssiPolling;
    private boolean mIsHighPerfEnabled;
    private int mPowerModeRefCount = 0;
    private int mOptimizationsDisabledRefCount = 0;

    /**
     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
@@ -659,6 +662,67 @@ public class WifiStateTracker extends NetworkStateTracker {
        }
    }

    /**
     * Set suspend mode optimizations. These include:
     * - packet filtering
     * - turn off roaming
     * - DTIM settings
     *
     * Uses reference counting to keep the suspend optimizations disabled
     * as long as one entity wants optimizations disabled.
     *
     * For example, WifiLock can keep suspend optimizations disabled
     * or the user setting (wifi never sleeps) can keep suspend optimizations
     * disabled. As long as one entity wants it disabled, it should stay
     * that way
     *
     * @param enabled true if optimizations need enabled, false otherwise
     */
    public synchronized void setSuspendModeOptimizations(boolean enabled) {

        /* It is good to plumb suspend optimization enable
         * or disable even if ref count indicates already done
         * since we could have a case of previous failure.
         */
        if (!enabled) {
            mOptimizationsDisabledRefCount++;
        } else {
            mOptimizationsDisabledRefCount--;
            if (mOptimizationsDisabledRefCount > 0) {
                return;
            } else {
                /* Keep refcount from becoming negative */
                mOptimizationsDisabledRefCount = 0;
            }
        }

        if (mWifiState.get() != WIFI_STATE_ENABLED || isDriverStopped()) {
            return;
        }

        WifiNative.setSuspendOptimizationsCommand(enabled);
    }


    /**
     * Set high performance mode of operation. This would mean
     * use active power mode and disable suspend optimizations
     * @param enabled true if enabled, false otherwise
     */
    public synchronized void setHighPerfMode(boolean enabled) {
        if (mIsHighPerfEnabled != enabled) {
            if (enabled) {
                setPowerMode(DRIVER_POWER_MODE_ACTIVE);
                setSuspendModeOptimizations(false);
            } else {
                setPowerMode(DRIVER_POWER_MODE_AUTO);
                setSuspendModeOptimizations(true);
            }
            mIsHighPerfEnabled = enabled;
            Log.d(TAG,"high performance mode: " + enabled);
        }
    }


    private void checkIsBluetoothPlaying() {
        boolean isBluetoothPlaying = false;
@@ -744,6 +808,9 @@ public class WifiStateTracker extends NetworkStateTracker {
                dhcpThread.start();
                mDhcpTarget = new DhcpHandler(dhcpThread.getLooper(), this);
                mIsScanModeActive = true;
                mIsHighPerfEnabled = false;
                mOptimizationsDisabledRefCount = 0;
                mPowerModeRefCount = 0;
                mTornDownByConnMgr = false;
                mLastBssid = null;
                mLastSsid = null;
@@ -1947,13 +2014,41 @@ public class WifiStateTracker extends NetworkStateTracker {
     * @param mode
     *     DRIVER_POWER_MODE_AUTO
     *     DRIVER_POWER_MODE_ACTIVE
     * @return {@code true} if the operation succeeds, {@code false} otherwise
     *
     * Uses reference counting to keep power mode active
     * as long as one entity wants power mode to be active.
     *
     * For example, WifiLock high perf mode can keep power mode active
     * or a DHCP session can keep it active. As long as one entity wants
     * it enabled, it should stay that way
     *
     */
    private synchronized void setPowerMode(int mode) {

        /* It is good to plumb power mode change
         * even if ref count indicates already done
         * since we could have a case of previous failure.
         */
    public synchronized boolean setPowerMode(int mode) {
        switch(mode) {
            case DRIVER_POWER_MODE_ACTIVE:
                mPowerModeRefCount++;
                break;
            case DRIVER_POWER_MODE_AUTO:
                mPowerModeRefCount--;
                if (mPowerModeRefCount > 0) {
                    return;
                } else {
                    /* Keep refcount from becoming negative */
                    mPowerModeRefCount = 0;
                }
                break;
        }

        if (mWifiState.get() != WIFI_STATE_ENABLED || isDriverStopped()) {
            return false;
            return;
        }
        return WifiNative.setPowerModeCommand(mode);

        WifiNative.setPowerModeCommand(mode);
    }

    /**