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

Commit f3409cee authored by Leonard Mosescu's avatar Leonard Mosescu
Browse files

Adding "attach-agent" to ActivityManagerShellCommand

This new command is used to attach runtime agents to a running application:

attach-agent <PROCESS> <FILE>
   Attach an agent to the specified <PROCESS>,
   which may be either a process name or a PID.

Test: m test-art-host, manual testing:
    . invalid syntax, missing arguments
    . invalid syntax, extra arguments
    . invalid numeric PID
    . invalid process name
    . valid process, not debuggable
    . valid process, missing agent
    . valid process, valid agent

Bug: 31682382

Change-Id: Ife88dbf23991dde7945d9208e54cd014bb7ecdc6
parent fe511037
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -978,6 +978,10 @@ public final class ActivityThread {
            sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
        }

        public void attachAgent(String agent) {
            sendMessage(H.ATTACH_AGENT, agent);
        }

        public void setSchedulingGroup(int group) {
            // Note: do this immediately, since going into the foreground
            // should happen regardless of what pending work we have to do
@@ -1429,6 +1433,7 @@ public final class ActivityThread {
        public static final int MULTI_WINDOW_MODE_CHANGED = 152;
        public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
        public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
        public static final int ATTACH_AGENT = 155;

        String codeToString(int code) {
            if (DEBUG_MESSAGES) {
@@ -1485,6 +1490,7 @@ public final class ActivityThread {
                    case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
                    case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
                    case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
                    case ATTACH_AGENT: return "ATTACH_AGENT";
                }
            }
            return Integer.toString(code);
@@ -1739,6 +1745,8 @@ public final class ActivityThread {
                case LOCAL_VOICE_INTERACTION_STARTED:
                    handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
                            (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
                case ATTACH_AGENT:
                    handleAttachAgent((String) msg.obj);
                    break;
            }
            Object obj = msg.obj;
@@ -3008,6 +3016,14 @@ public final class ActivityThread {
        }
    }

    static final void handleAttachAgent(String agent) {
        try {
            VMDebug.attachAgent(agent);
        } catch (IOException e) {
            Slog.e(TAG, "Attaching agent failed: " + agent);
        }
    }

    private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();

    /**
+1 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ oneway interface IApplicationThread {
    void scheduleLocalVoiceInteractionStarted(IBinder token,
            IVoiceInteractor voiceInteractor) = 61;
    void handleTrustStorageUpdate() = 62;
    void attachAgent(String path) = 63;
    /**
     * Don't change the existing transaction Ids as they could be used in the native code.
     * When adding a new method, assign the next available transaction id.
+1 −1
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ public abstract class ShellCommand {
    /**
     * Implement parsing and execution of a command.  If it isn't a command you understand,
     * call {@link #handleDefaultCommands(String)} and return its result as a last resort.
     * User {@link #getNextOption()}, {@link #getNextArg()}, and {@link #getNextArgRequired()}
     * Use {@link #getNextOption()}, {@link #getNextArg()}, and {@link #getNextArgRequired()}
     * to process additional command line arguments.  Command output can be written to
     * {@link #getOutPrintWriter()} and errors to {@link #getErrPrintWriter()}.
     *
+25 −0
Original line number Diff line number Diff line
@@ -22483,4 +22483,29 @@ public final class ActivityManagerService extends ActivityManagerNative
        // before the profile user is unlocked.
        return rInfo != null && rInfo.activityInfo != null;
    }
    /**
     * Attach an agent to the specified process (proces name or PID)
     */
    public void attachAgent(String process, String path) {
        try {
            synchronized (this) {
                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
                if (proc == null || proc.thread == null) {
                    throw new IllegalArgumentException("Unknown process: " + process);
                }
                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
                if (!isDebuggable) {
                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                        throw new SecurityException("Process not debuggable: " + proc);
                    }
                }
                proc.thread.attachAgent(path);
            }
        } catch (RemoteException e) {
            throw new IllegalStateException("Process disappeared");
        }
    }
}
+19 −0
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runTask(pw);
                case "write":
                    return runWrite(pw);
                case "attach-agent":
                    return runAttachAgent(pw);
                default:
                    return handleDefaultCommands(cmd);
            }
@@ -2462,6 +2464,21 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    int runAttachAgent(PrintWriter pw) {
        // TODO: revisit the permissions required for attaching agents
        mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
                "attach-agent");
        String process = getNextArgRequired();
        String agent = getNextArgRequired();
        String opt;
        if ((opt = getNextArg()) != null) {
            pw.println("Error: Unknown option: " + opt);
            return -1;
        }
        mInternal.attachAgent(process, agent);
        return 0;
    }

    @Override
    public void onHelp() {
        PrintWriter pw = getOutPrintWriter();
@@ -2619,6 +2636,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("      Optionally controls lenient background check mode, returns current mode.");
            pw.println("  get-uid-state <UID>");
            pw.println("      Gets the process state of an app given its <UID>.");
            pw.println("  attach-agent <PROCESS> <FILE>");
            pw.println("    Attach an agent to the specified <PROCESS>, which may be either a process name or a PID.");
            pw.println("  get-config");
            pw.println("      Rtrieve the configuration and any recent configurations of the device.");
            pw.println("  suppress-resize-config-changes <true|false>");