Merge "Adding "attach-agent" to ActivityManagerShellCommand"
am: 05dfd10254
Change-Id: I3623f617319f03bad87f65b61959ec2ce822ac7e
This commit is contained in:
@@ -974,6 +974,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
|
||||
@@ -1408,6 +1412,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) {
|
||||
@@ -1464,6 +1469,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);
|
||||
@@ -1718,6 +1724,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;
|
||||
@@ -2987,6 +2995,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>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -502,6 +502,14 @@ public abstract class ApplicationThreadNative extends Binder
|
||||
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();
|
||||
@@ -1305,6 +1313,14 @@ class ApplicationThreadProxy implements IApplicationThread {
|
||||
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);
|
||||
|
||||
@@ -123,6 +123,7 @@ public interface IApplicationThread extends IInterface {
|
||||
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;
|
||||
@@ -225,4 +226,5 @@ public interface IApplicationThread extends IInterface {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,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()}.
|
||||
*
|
||||
|
||||
@@ -22273,4 +22273,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ class ActivityManagerShellCommand extends ShellCommand {
|
||||
return runLenientBackgroundCheck(pw);
|
||||
case "get-uid-state":
|
||||
return getUidState(pw);
|
||||
case "attach-agent":
|
||||
return runAttachAgent(pw);
|
||||
default:
|
||||
return handleDefaultCommands(cmd);
|
||||
}
|
||||
@@ -183,6 +185,21 @@ 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();
|
||||
@@ -241,6 +258,8 @@ 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user