Loading cmds/am/src/com/android/commands/am/Am.java +47 −1 Original line number Diff line number Diff line Loading @@ -75,6 +75,8 @@ public class Am { runInstrument(); } else if (op.equals("broadcast")) { sendBroadcast(); } else if (op.equals("profile")) { runProfile(); } else { System.err.println("Error: Unknown command: " + op); showUsage(); Loading Loading @@ -423,6 +425,49 @@ public class Am { } } private void runProfile() { String profileFile = null; boolean start = false; String process = nextArg(); if (process == null) { System.err.println("Error: No profile process supplied"); showUsage(); return; } String cmd = nextArg(); if ("start".equals(cmd)) { start = true; profileFile = nextArg(); if (profileFile == null) { System.err.println("Error: No profile file path supplied"); showUsage(); return; } } else if (!"stop".equals(cmd)) { System.err.println("Error: Profile command " + cmd + " not valid"); showUsage(); return; } try { if (!mAm.profileControl(process, start, profileFile)) { System.out.println("PROFILE FAILED on process " + process); return; } } catch (IllegalArgumentException e) { System.out.println("PROFILE FAILED: " + e.getMessage()); return; } catch (IllegalStateException e) { System.out.println("PROFILE FAILED: " + e.getMessage()); return; } catch (RemoteException e) { System.out.println("PROFILE FAILED: activity manager gone"); return; } } private String nextOption() { if (mNextArg >= mArgs.length) { return null; Loading Loading @@ -470,11 +515,12 @@ public class Am { } private void showUsage() { System.err.println("usage: am [start|broadcast|instrument]"); System.err.println("usage: am [start|broadcast|instrument|profile]"); System.err.println(" am start -D INTENT"); System.err.println(" am broadcast INTENT"); System.err.println(" am instrument [-r] [-e <ARG_NAME> <ARG_VALUE>] [-p <PROF_FILE>]"); System.err.println(" [-w] <COMPONENT> "); System.err.println(" am profile <PROCESS> [start <PROF_FILE>|stop]"); System.err.println(""); System.err.println(" INTENT is described with:"); System.err.println(" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]"); Loading core/java/android/app/ActivityManagerNative.java +29 −0 Original line number Diff line number Diff line Loading @@ -979,6 +979,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case PROFILE_CONTROL_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String process = data.readString(); boolean start = data.readInt() != 0; String path = data.readString(); boolean res = profileControl(process, start, path); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case PEEK_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Intent service = Intent.CREATOR.createFromParcel(data); Loading Loading @@ -2131,5 +2142,23 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return res; } public boolean profileControl(String process, boolean start, String path) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(process); data.writeInt(start ? 1 : 0); data.writeString(path); mRemote.transact(PROFILE_CONTROL_TRANSACTION, data, reply, 0); reply.readException(); boolean res = reply.readInt() != 0; reply.recycle(); data.recycle(); return res; } private IBinder mRemote; } core/java/android/app/ActivityThread.java +24 −0 Original line number Diff line number Diff line Loading @@ -1449,6 +1449,10 @@ public final class ActivityThread { } } public void profilerControl(boolean start, String path) { queueOrSendMessage(H.PROFILER_CONTROL, path, start ? 1 : 0); } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { long nativeMax = Debug.getNativeHeapSize() / 1024; Loading Loading @@ -1641,6 +1645,7 @@ public final class ActivityThread { public static final int LOW_MEMORY = 124; public static final int ACTIVITY_CONFIGURATION_CHANGED = 125; public static final int RELAUNCH_ACTIVITY = 126; public static final int PROFILER_CONTROL = 127; String codeToString(int code) { if (localLOGV) { switch (code) { Loading Loading @@ -1671,6 +1676,7 @@ public final class ActivityThread { case LOW_MEMORY: return "LOW_MEMORY"; case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED"; case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; case PROFILER_CONTROL: return "PROFILER_CONTROL"; } } return "(unknown)"; Loading Loading @@ -1770,6 +1776,9 @@ public final class ActivityThread { case ACTIVITY_CONFIGURATION_CHANGED: handleActivityConfigurationChanged((IBinder)msg.obj); break; case PROFILER_CONTROL: handleProfilerControl(msg.arg1 != 0, (String)msg.obj); break; } } } Loading Loading @@ -3432,6 +3441,21 @@ public final class ActivityThread { performConfigurationChanged(r.activity, mConfiguration); } final void handleProfilerControl(boolean start, String path) { if (start) { File file = new File(path); file.getParentFile().mkdirs(); try { Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); } catch (RuntimeException e) { Log.w(TAG, "Profiling failed on path " + path + " -- can the process access this path?"); } } else { Debug.stopMethodTracing(); } } final void handleLowMemory() { ArrayList<ComponentCallbacks> callbacks = new ArrayList<ComponentCallbacks>(); Loading core/java/android/app/ApplicationThreadNative.java +18 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,15 @@ public abstract class ApplicationThreadNative extends Binder requestPss(); return true; } case PROFILER_CONTROL_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); boolean start = data.readInt() != 0; String path = data.readString(); profilerControl(start, path); return true; } } return super.onTransact(code, data, reply, flags); Loading Loading @@ -654,5 +663,14 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); } public void profilerControl(boolean start, String path) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeInt(start ? 1 : 0); data.writeString(path); mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } } core/java/android/app/IActivityManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,10 @@ public interface IActivityManager extends IInterface { // Get device configuration public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException; // Turn on/off profiling in a particular process. public boolean profileControl(String process, boolean start, String path) throws RemoteException; /* * Private non-Binder interfaces */ Loading Loading @@ -365,4 +369,5 @@ public interface IActivityManager extends IInterface { int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82; int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83; int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84; int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85; } Loading
cmds/am/src/com/android/commands/am/Am.java +47 −1 Original line number Diff line number Diff line Loading @@ -75,6 +75,8 @@ public class Am { runInstrument(); } else if (op.equals("broadcast")) { sendBroadcast(); } else if (op.equals("profile")) { runProfile(); } else { System.err.println("Error: Unknown command: " + op); showUsage(); Loading Loading @@ -423,6 +425,49 @@ public class Am { } } private void runProfile() { String profileFile = null; boolean start = false; String process = nextArg(); if (process == null) { System.err.println("Error: No profile process supplied"); showUsage(); return; } String cmd = nextArg(); if ("start".equals(cmd)) { start = true; profileFile = nextArg(); if (profileFile == null) { System.err.println("Error: No profile file path supplied"); showUsage(); return; } } else if (!"stop".equals(cmd)) { System.err.println("Error: Profile command " + cmd + " not valid"); showUsage(); return; } try { if (!mAm.profileControl(process, start, profileFile)) { System.out.println("PROFILE FAILED on process " + process); return; } } catch (IllegalArgumentException e) { System.out.println("PROFILE FAILED: " + e.getMessage()); return; } catch (IllegalStateException e) { System.out.println("PROFILE FAILED: " + e.getMessage()); return; } catch (RemoteException e) { System.out.println("PROFILE FAILED: activity manager gone"); return; } } private String nextOption() { if (mNextArg >= mArgs.length) { return null; Loading Loading @@ -470,11 +515,12 @@ public class Am { } private void showUsage() { System.err.println("usage: am [start|broadcast|instrument]"); System.err.println("usage: am [start|broadcast|instrument|profile]"); System.err.println(" am start -D INTENT"); System.err.println(" am broadcast INTENT"); System.err.println(" am instrument [-r] [-e <ARG_NAME> <ARG_VALUE>] [-p <PROF_FILE>]"); System.err.println(" [-w] <COMPONENT> "); System.err.println(" am profile <PROCESS> [start <PROF_FILE>|stop]"); System.err.println(""); System.err.println(" INTENT is described with:"); System.err.println(" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]"); Loading
core/java/android/app/ActivityManagerNative.java +29 −0 Original line number Diff line number Diff line Loading @@ -979,6 +979,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case PROFILE_CONTROL_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String process = data.readString(); boolean start = data.readInt() != 0; String path = data.readString(); boolean res = profileControl(process, start, path); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case PEEK_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Intent service = Intent.CREATOR.createFromParcel(data); Loading Loading @@ -2131,5 +2142,23 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return res; } public boolean profileControl(String process, boolean start, String path) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(process); data.writeInt(start ? 1 : 0); data.writeString(path); mRemote.transact(PROFILE_CONTROL_TRANSACTION, data, reply, 0); reply.readException(); boolean res = reply.readInt() != 0; reply.recycle(); data.recycle(); return res; } private IBinder mRemote; }
core/java/android/app/ActivityThread.java +24 −0 Original line number Diff line number Diff line Loading @@ -1449,6 +1449,10 @@ public final class ActivityThread { } } public void profilerControl(boolean start, String path) { queueOrSendMessage(H.PROFILER_CONTROL, path, start ? 1 : 0); } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { long nativeMax = Debug.getNativeHeapSize() / 1024; Loading Loading @@ -1641,6 +1645,7 @@ public final class ActivityThread { public static final int LOW_MEMORY = 124; public static final int ACTIVITY_CONFIGURATION_CHANGED = 125; public static final int RELAUNCH_ACTIVITY = 126; public static final int PROFILER_CONTROL = 127; String codeToString(int code) { if (localLOGV) { switch (code) { Loading Loading @@ -1671,6 +1676,7 @@ public final class ActivityThread { case LOW_MEMORY: return "LOW_MEMORY"; case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED"; case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; case PROFILER_CONTROL: return "PROFILER_CONTROL"; } } return "(unknown)"; Loading Loading @@ -1770,6 +1776,9 @@ public final class ActivityThread { case ACTIVITY_CONFIGURATION_CHANGED: handleActivityConfigurationChanged((IBinder)msg.obj); break; case PROFILER_CONTROL: handleProfilerControl(msg.arg1 != 0, (String)msg.obj); break; } } } Loading Loading @@ -3432,6 +3441,21 @@ public final class ActivityThread { performConfigurationChanged(r.activity, mConfiguration); } final void handleProfilerControl(boolean start, String path) { if (start) { File file = new File(path); file.getParentFile().mkdirs(); try { Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); } catch (RuntimeException e) { Log.w(TAG, "Profiling failed on path " + path + " -- can the process access this path?"); } } else { Debug.stopMethodTracing(); } } final void handleLowMemory() { ArrayList<ComponentCallbacks> callbacks = new ArrayList<ComponentCallbacks>(); Loading
core/java/android/app/ApplicationThreadNative.java +18 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,15 @@ public abstract class ApplicationThreadNative extends Binder requestPss(); return true; } case PROFILER_CONTROL_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); boolean start = data.readInt() != 0; String path = data.readString(); profilerControl(start, path); return true; } } return super.onTransact(code, data, reply, flags); Loading Loading @@ -654,5 +663,14 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); } public void profilerControl(boolean start, String path) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeInt(start ? 1 : 0); data.writeString(path); mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } }
core/java/android/app/IActivityManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,10 @@ public interface IActivityManager extends IInterface { // Get device configuration public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException; // Turn on/off profiling in a particular process. public boolean profileControl(String process, boolean start, String path) throws RemoteException; /* * Private non-Binder interfaces */ Loading Loading @@ -365,4 +369,5 @@ public interface IActivityManager extends IInterface { int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82; int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83; int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84; int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85; }