Skip to content

Commit

Permalink
Adding "attach-agent" to ActivityManagerShellCommand
Browse files Browse the repository at this point in the history
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

Merged-In: Ife88dbf23991dde7945d9208e54cd014bb7ecdc6
  • Loading branch information
Leonard Mosescu committed Oct 27, 2016
1 parent d19524f commit 1ab879b
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 1 deletion.
16 changes: 16 additions & 0 deletions core/java/android/app/ActivityThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,10 @@ public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
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
Expand Down Expand Up @@ -1388,6 +1392,7 @@ private class H extends Handler {
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) {
Expand Down Expand Up @@ -1444,6 +1449,7 @@ String codeToString(int code) {
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);
Expand Down Expand Up @@ -1696,6 +1702,8 @@ public void handleMessage(Message msg) {
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;
Expand Down Expand Up @@ -2955,6 +2963,14 @@ private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor
}
}

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>();

/**
Expand Down
16 changes: 16 additions & 0 deletions core/java/android/app/ApplicationThreadNative.java
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,14 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
return true;
}

case ATTACH_AGENT_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
String agent = data.readString();
attachAgent(agent);
return true;
}

case DUMP_ACTIVITY_TRANSACTION: {
data.enforceInterface(IApplicationThread.descriptor);
ParcelFileDescriptor fd = data.readFileDescriptor();
Expand Down Expand Up @@ -1303,6 +1311,14 @@ public void dumpActivity(FileDescriptor fd, IBinder token, String prefix, String
data.recycle();
}

public void attachAgent(String agent) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeString(agent);
mRemote.transact(ATTACH_AGENT_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}

public void setCoreSettings(Bundle coreSettings) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
Expand Down
2 changes: 2 additions & 0 deletions core/java/android/app/IApplicationThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType)
throws RemoteException;
void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd)
throws RemoteException;
void attachAgent(String path) throws RemoteException;
void setSchedulingGroup(int group) throws RemoteException;
// the package has been removed, clean up internal references
static final int PACKAGE_REMOVED = 0;
Expand Down Expand Up @@ -224,4 +225,5 @@ void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)
int SCHEDULE_MULTI_WINDOW_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+58;
int SCHEDULE_PICTURE_IN_PICTURE_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+59;
int SCHEDULE_LOCAL_VOICE_INTERACTION_STARTED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+60;
int ATTACH_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+61;
}
2 changes: 1 addition & 1 deletion core/java/android/os/ShellCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public int handleDefaultCommands(String cmd) {
/**
* 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()}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21831,4 +21831,29 @@ public void killPackageDependents(String packageName, int userId) {
Binder.restoreCallingIdentity(callingId);
}
}

/**
* 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");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public int onCommand(String cmd) {
return runLenientBackgroundCheck(pw);
case "get-uid-state":
return getUidState(pw);
case "attach-agent":
return runAttachAgent(pw);
default:
return handleDefaultCommands(cmd);
}
Expand Down Expand Up @@ -183,6 +185,21 @@ int getUidState(PrintWriter pw) throws RemoteException {
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();
Expand Down Expand Up @@ -241,6 +258,8 @@ static void dumpHelp(PrintWriter pw, boolean dumping) {
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.");
}
}
}

0 comments on commit 1ab879b

Please sign in to comment.