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

Commit 16f2f201 authored by Fiona Campbell's avatar Fiona Campbell
Browse files

Shell command to set all wakelocks

Expand shell command to work for all wakelocks

Bug: 422172821
Flag: EXEMPT shell command only
Test: adb shell cmd power set-wakelock acquire -d 0 PARTIAL_WAKE_LOCK

Change-Id: I0cd934ac04d35eb2af61a3a152400c181aa761df
parent 15503c93
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -89,6 +89,27 @@ public abstract class PowerManagerInternal {
        }
    }

    /**
     * Converts wakelock flags into strings.
     * @param flags wakelock flags to convert to string
     * @return Readable string of wakelock value.
     */
    @SuppressWarnings("deprecation")
    public static String getLockLevelString(int flags) {
        return switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
            case PowerManager.FULL_WAKE_LOCK -> "FULL_WAKE_LOCK";
            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK -> "SCREEN_BRIGHT_WAKE_LOCK";
            case PowerManager.SCREEN_DIM_WAKE_LOCK -> "SCREEN_DIM_WAKE_LOCK";
            case PowerManager.PARTIAL_WAKE_LOCK -> "PARTIAL_WAKE_LOCK";
            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK -> "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
            case PowerManager.DOZE_WAKE_LOCK -> "DOZE_WAKE_LOCK";
            case PowerManager.DRAW_WAKE_LOCK -> "DRAW_WAKE_LOCK";
            case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK ->
                    "SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK";
            default -> "???";
        };
    }

    /**
     * Returns true if the wakefulness state represents an interactive state
     * as defined by {@link android.os.PowerManager#isInteractive}.
+2 −25
Original line number Diff line number Diff line
@@ -5701,7 +5701,8 @@ public final class PowerManagerService extends SystemService
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(getLockLevelString());
            // Pad to 33 chars (longest wakelock name)
            sb.append(String.format("%-33s", PowerManagerInternal.getLockLevelString(mFlags)));
            sb.append(" '");
            sb.append(mTag);
            sb.append("'");
@@ -5762,30 +5763,6 @@ public final class PowerManagerService extends SystemService
            proto.end(wakeLockToken);
        }

        @SuppressWarnings("deprecation")
        private String getLockLevelString() {
            switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
                case PowerManager.FULL_WAKE_LOCK:
                    return "FULL_WAKE_LOCK                   ";
                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
                    return "SCREEN_BRIGHT_WAKE_LOCK          ";
                case PowerManager.SCREEN_DIM_WAKE_LOCK:
                    return "SCREEN_DIM_WAKE_LOCK             ";
                case PowerManager.PARTIAL_WAKE_LOCK:
                    return "PARTIAL_WAKE_LOCK                ";
                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                    return "PROXIMITY_SCREEN_OFF_WAKE_LOCK   ";
                case PowerManager.DOZE_WAKE_LOCK:
                    return "DOZE_WAKE_LOCK                   ";
                case PowerManager.DRAW_WAKE_LOCK:
                    return "DRAW_WAKE_LOCK                   ";
                case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
                    return "SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK";
                default:
                    return "???                              ";
            }
        }

        private String getLockFlagsString() {
            String result = "";
            if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
+60 −14
Original line number Diff line number Diff line
@@ -32,7 +32,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.util.SparseArray;
import android.util.ArrayMap;
import android.util.Pair;
import android.view.Display;

import com.android.server.LocalServices;
@@ -40,9 +41,11 @@ import com.android.server.pm.pkg.AndroidPackage;

import java.io.PrintWriter;
import java.util.List;
import java.util.Locale;

class PowerManagerShellCommand extends ShellCommand {
    private static final int LOW_POWER_MODE_ON = 1;
    private static final int INVALID_WAKELOCK = -1;

    private final Context mContext;
    private final PowerManagerService.BinderService mService;
@@ -66,7 +69,8 @@ class PowerManagerShellCommand extends ShellCommand {
    }
    private final PowerManagerShellCommandAlarmListener mAlarmListener;

    private SparseArray<WakeLock> mProxWakelocks = new SparseArray<>();
    // Mapping of Pair<DisplayId, WakelockType> -> Wakelock
    private final ArrayMap<Pair<Integer, Integer>, WakeLock> mWakelocks = new ArrayMap<>();

    PowerManagerShellCommand(Context context, PowerManagerService.BinderService service) {
        mContext = context;
@@ -97,6 +101,8 @@ class PowerManagerShellCommand extends ShellCommand {
                    return runListAmbientDisplaySuppressionTokens();
                case "set-prox":
                    return runSetProx();
                case "set-wakelock":
                    return runSetWakelock(/* proxForLegacy= */ false);
                case "set-face-down-detector":
                    return runSetFaceDownDetector();
                case "sleep":
@@ -192,14 +198,21 @@ class PowerManagerShellCommand extends ShellCommand {
        return 0;
    }

    /** TODO: Consider updating this code to support all wakelock types. */
    private int runSetProx() throws RemoteException {
        return runSetWakelock(/* proxForLegacy= */ true);
    }

    private int runSetWakelock(boolean proxForLegacy) throws RemoteException {
        PrintWriter pw = getOutPrintWriter();
        final boolean acquire;
        switch (getNextArgRequired().toLowerCase()) {
            case "list":
                pw.println("Wakelocks:");
                pw.println(mProxWakelocks);
                for (int i = 0; i < mWakelocks.size(); i++) {
                    pw.println("Display " + mWakelocks.keyAt(i).first + ", wakelock type: "
                            + PowerManagerInternal.getLockLevelString(mWakelocks.keyAt(i).second)
                            + ": " + mWakelocks.valueAt(i));
                }
                return 0;
            case "acquire":
                acquire = true;
@@ -208,7 +221,7 @@ class PowerManagerShellCommand extends ShellCommand {
                acquire = false;
                break;
            default:
                pw.println("Error: Allowed options are 'list' 'enable' and 'disable'.");
                pw.println("Error: Allowed options are 'list' 'acquire' and 'release'.");
                return -1;
        }

@@ -222,15 +235,9 @@ class PowerManagerShellCommand extends ShellCommand {
                return -1;
            }
        }

        int wakelockIndex = displayId + 1; // SparseArray doesn't support negative indexes
        WakeLock wakelock = mProxWakelocks.get(wakelockIndex);
        if (wakelock == null) {
            PowerManager pm = mContext.getSystemService(PowerManager.class);
            wakelock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
                        "PowerManagerShellCommand[" + displayId + "]", displayId);
            mProxWakelocks.put(wakelockIndex, wakelock);
        }
        String wakelockTypeString = proxForLegacy ? PowerManagerInternal.getLockLevelString(
                PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) : getNextArg().toUpperCase(Locale.US);
        WakeLock wakelock = getWakelock(displayId, wakelockTypeString);

        if (acquire) {
            wakelock.acquire();
@@ -241,6 +248,40 @@ class PowerManagerShellCommand extends ShellCommand {
        return 0;
    }

    private WakeLock getWakelock(int displayId, String wakelockString) {
        int wakelockType = stringToWakelockType(wakelockString);
        if (wakelockType == INVALID_WAKELOCK) {
            throw new IllegalArgumentException("Wakelock type invalid: " + wakelockString);
        }
        Pair<Integer, Integer> wakelockIdentifier = new Pair<>(displayId, wakelockType);

        WakeLock wakelockForDisplay = mWakelocks.get(wakelockIdentifier);

        if (wakelockForDisplay == null) {
            PowerManager pm = mContext.getSystemService(PowerManager.class);
            wakelockForDisplay = pm.newWakeLock(wakelockType,
                    "PowerManagerShellCommand[" + displayId + ":"
                            + "0x" + Integer.toHexString(wakelockType) + "]", displayId);
            mWakelocks.put(wakelockIdentifier, wakelockForDisplay);
        }
        return wakelockForDisplay;
    }

    private int stringToWakelockType(String string) {
        return switch (string) {
            case "PARTIAL_WAKE_LOCK" -> PowerManager.PARTIAL_WAKE_LOCK;
            case "SCREEN_DIM_WAKE_LOCK" -> PowerManager.SCREEN_DIM_WAKE_LOCK;
            case "SCREEN_BRIGHT_WAKE_LOCK" -> PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
            case "FULL_WAKE_LOCK" -> PowerManager.FULL_WAKE_LOCK;
            case "DOZE_WAKE_LOCK" -> PowerManager.DOZE_WAKE_LOCK;
            case "DRAW_WAKE_LOCK" -> PowerManager.DRAW_WAKE_LOCK;
            case "SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK" ->
                    PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
            case "PROXIMITY_SCREEN_OFF_WAKE_LOCK" -> PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
            default -> INVALID_WAKELOCK;
        };
    }

    /**
     * To be used for testing - allowing us to disable the usage of face down detector.
     */
@@ -375,6 +416,11 @@ class PowerManagerShellCommand extends ShellCommand {
        pw.println("    Acquires the proximity sensor wakelock. Wakelock is associated with");
        pw.println("    a specific display if specified. 'list' lists wakelocks previously");
        pw.println("    created by set-prox including their held status.");
        pw.println("  set-wakelock [list|acquire|release] (-d <display_id>) [wakelock type]");
        pw.println("    Acquires the specified wakelock. Wakelock is associated with");
        pw.println("    a specific display if specified. 'list' lists wakelocks previously");
        pw.println("    created by set-wakelock including their held status.");
        pw.println("    Available wakelocks are described in PowerManager.*_WAKE_LOCK.");
        pw.println("  set-face-down-detector [true|false]");
        pw.println("    sets whether we use face down detector timeouts or not");
        pw.println("  sleep (--disable-wakelocks)");