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

Commit d4b447b3 authored by Lee Shombert's avatar Lee Shombert
Browse files

Add Process.isProcessFrozen()

Add Process.isProcessFrozen(pid, uid).  The method returns true if
/sys/fs/cgroup/[apps,system]/uid_<uid>/pid_<pid>/cgroup.freeze is
readable and contains the character '1'.  Otherwise the method returns
false.  This means that the method returns false if the caller does
not have sufficient privileges.

The method queries the "system" path if the UID is less than 10000.
It queries the "apps" path if the UID >= 10000.

The command "isfrozen <PROCESS>" is now avaiable in the am shell
command.  It prints "true" or "false" depending on the return value
from the new method.

Flag: EXEMPT bugfix
Bug: 409803220
Test: manual test using 'am' commands to freeze, unfreeze, and query
processes.

Change-Id: I27d8a82716d593d4e714e375d79a400381765fa8
parent 43e4a4ec
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1178,6 +1178,20 @@ public class Process {
     */
    public static final native void setProcessFrozen(int pid, int uid, boolean frozen);

    /**
     * Return true if the process is frozen.  It returns false if the pid/uid combination is not
     * found or if the caller does not have permission to query the pid.
     *
     * @param pid Identifier of the process to query.
     * @param uid Identifier of the user the process is running under.
     * @return true if the process is frozen, false otherwise.
     * @throws IllegalArgumentException if the uid is negative.
     *
     * @hide
     */
    public static final native boolean isProcessFrozen(int pid, int uid)
            throws IllegalArgumentException;

    /**
     * Return the scheduling group of requested process.
     *
+23 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <processgroup/sched_policy.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <cutils/misc.h>

#include <algorithm>
#include <array>
@@ -332,6 +333,27 @@ void android_os_Process_setProcessFrozen(
    }
}

jboolean android_os_Process_isProcessFrozen(JNIEnv *env, jobject, jint pid, jint uid)
{
    if (uid < 0) {
        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "uid is negative: %d", uid);
        return false;
    }

    char const* type = (uid < FIRST_APPLICATION_UID) ? "system" : "apps";
    char path[PATH_MAX];
    snprintf(path, sizeof(path), "/sys/fs/cgroup/%s/uid_%d/pid_%d/cgroup.freeze", type, uid, pid);

    int fd = ::open(path, O_RDONLY);
    if (fd >= 0) {
      char flag = 0;
      ::read(fd, &flag, 1);
      ::close(fd);
      return flag == '1';
    }
    return false;
}

jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid)
{
    SchedPolicy sp;
@@ -1401,6 +1423,7 @@ static const JNINativeMethod methods[] = {
        {"sendSignalThrows", "(II)V", (void*)android_os_Process_sendSignalThrows},
        {"sendTgSignalThrows", "(III)V", (void*)android_os_Process_sendTgSignalThrows},
        {"setProcessFrozen", "(IIZ)V", (void*)android_os_Process_setProcessFrozen},
        {"isProcessFrozen", "(II)Z", (void*)android_os_Process_isProcessFrozen},
        {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
        {"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory},
        {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V",
+15 −0
Original line number Diff line number Diff line
@@ -284,6 +284,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runFreeze(pw, true);
                case "unfreeze":
                    return runFreeze(pw, false);
                case "isfrozen":
                    return isFrozen(pw);
                case "instrument":
                    getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
                    return -1;
@@ -1348,6 +1350,17 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    @NeverCompile
    int isFrozen(PrintWriter pw) throws RemoteException {
        ProcessRecord proc = getProcessFromShell();
        if (proc == null) {
            return -1;
        }
        boolean frozen = android.os.Process.isProcessFrozen(proc.mPid, proc.uid);
        pw.println(frozen ? "true" : "false");
        return 0;
    }

    /**
     * Parses from the shell the pid or process name and provides the corresponding
     * {@link ProcessRecord}.
@@ -4462,6 +4475,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("          may be either a process name or pid.  Options are:");
            pw.println("      --sticky: persists the unfrozen state for the process lifetime or");
            pw.println("                  until a freeze is triggered via shell");
            pw.println("  isfrozen <PROCESS>");
            pw.println("      Print the frozen status of the process (true or false)");
            pw.println("  instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
            pw.println("          [--user <USER_ID> | current]");
            pw.println("          [--no-hidden-api-checks [--no-test-api-access]]");