diff options
| author | Dianne Hackborn <hackbod@google.com> | 2011-08-15 17:40:28 -0700 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2011-08-15 17:55:57 -0700 |
| commit | 62f20ecf492d2b29881bba307c79ff55e68760e6 (patch) | |
| tree | 58ea602138a28fb3555368900acbad6219ae2de2 /core/java/android | |
| parent | 0f2da17a9523fc40bceb5209cabd044df648e98e (diff) | |
Add new am option to profile the launching of an activity.
Change-Id: Ie71a8043eafe41f53a0b3dbb5170276d87acbc9b
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/Activity.java | 3 | ||||
| -rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 41 | ||||
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 106 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 34 | ||||
| -rw-r--r-- | core/java/android/app/IActivityManager.java | 9 | ||||
| -rw-r--r-- | core/java/android/app/IApplicationThread.java | 6 | ||||
| -rw-r--r-- | core/java/android/app/Instrumentation.java | 4 | ||||
| -rw-r--r-- | core/java/android/os/ParcelFileDescriptor.java | 10 |
8 files changed, 184 insertions, 29 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 929867bc8e7b..1271ddd68c83 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -3353,7 +3353,8 @@ public class Activity extends ContextThemeWrapper intent, intent.resolveTypeIfNeeded( getContentResolver()), null, 0, - mToken, mEmbeddedID, requestCode, true, false); + mToken, mEmbeddedID, requestCode, true, false, + null, null, false); } catch (RemoteException e) { // Empty } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index a73e10a863b3..8901fc8c5b10 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -124,9 +124,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; + String profileFile = data.readString(); + ParcelFileDescriptor profileFd = data.readInt() != 0 + ? data.readFileDescriptor() : null; + boolean autoStopProfiler = data.readInt() != 0; int result = startActivity(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, - requestCode, onlyIfNeeded, debug); + requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler); reply.writeNoException(); reply.writeInt(result); return true; @@ -146,9 +150,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; + String profileFile = data.readString(); + ParcelFileDescriptor profileFd = data.readInt() != 0 + ? data.readFileDescriptor() : null; + boolean autoStopProfiler = data.readInt() != 0; WaitResult result = startActivityAndWait(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, - requestCode, onlyIfNeeded, debug); + requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler); reply.writeNoException(); result.writeToParcel(reply, 0); return true; @@ -349,8 +357,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM if (data.readInt() != 0) { config = Configuration.CREATOR.createFromParcel(data); } + boolean stopProfiling = data.readInt() != 0; if (token != null) { - activityIdle(token, config); + activityIdle(token, config, stopProfiling); } reply.writeNoException(); return true; @@ -1572,7 +1581,8 @@ class ActivityManagerProxy implements IActivityManager String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, - boolean debug) throws RemoteException { + boolean debug, String profileFile, ParcelFileDescriptor profileFd, + boolean autoStopProfiler) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -1586,6 +1596,14 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(requestCode); data.writeInt(onlyIfNeeded ? 1 : 0); data.writeInt(debug ? 1 : 0); + data.writeString(profileFile); + if (profileFd != null) { + data.writeInt(1); + profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); + } else { + data.writeInt(0); + } + data.writeInt(autoStopProfiler ? 1 : 0); mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); @@ -1597,7 +1615,8 @@ class ActivityManagerProxy implements IActivityManager String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, - boolean debug) throws RemoteException { + boolean debug, String profileFile, ParcelFileDescriptor profileFd, + boolean autoStopProfiler) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -1611,6 +1630,14 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(requestCode); data.writeInt(onlyIfNeeded ? 1 : 0); data.writeInt(debug ? 1 : 0); + data.writeString(profileFile); + if (profileFd != null) { + data.writeInt(1); + profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); + } else { + data.writeInt(0); + } + data.writeInt(autoStopProfiler ? 1 : 0); mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0); reply.readException(); WaitResult result = WaitResult.CREATOR.createFromParcel(reply); @@ -1829,7 +1856,8 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - public void activityIdle(IBinder token, Configuration config) throws RemoteException + public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -1841,6 +1869,7 @@ class ActivityManagerProxy implements IActivityManager } else { data.writeInt(0); } + data.writeInt(stopProfiling ? 1 : 0); mRemote.transact(ACTIVITY_IDLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d5f630a647d0..e3762206588d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -225,6 +225,10 @@ public final class ActivityThread { Configuration createdConfig; ActivityClientRecord nextIdle; + String profileFile; + ParcelFileDescriptor profileFd; + boolean autoStopProfiler; + ActivityInfo activityInfo; CompatibilityInfo compatInfo; LoadedApk packageInfo; @@ -361,6 +365,9 @@ public final class ActivityThread { List<ProviderInfo> providers; ComponentName instrumentationName; String profileFile; + ParcelFileDescriptor profileFd; + boolean autoStopProfiler; + boolean profiling; Bundle instrumentationArgs; IInstrumentationWatcher instrumentationWatcher; int debugMode; @@ -371,6 +378,57 @@ public final class ActivityThread { public String toString() { return "AppBindData{appInfo=" + appInfo + "}"; } + public void setProfiler(String file, ParcelFileDescriptor fd) { + if (profiling) { + if (fd != null) { + try { + fd.close(); + } catch (IOException e) { + } + } + return; + } + if (profileFd != null) { + try { + profileFd.close(); + } catch (IOException e) { + } + } + profileFile = file; + profileFd = fd; + } + public void startProfiling() { + if (profileFd == null || profiling) { + return; + } + try { + Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), + 8 * 1024 * 1024, 0); + profiling = true; + } catch (RuntimeException e) { + Slog.w(TAG, "Profiling failed on path " + profileFile); + try { + profileFd.close(); + profileFd = null; + } catch (IOException e2) { + Slog.w(TAG, "Failure closing profile fd", e2); + } + } + } + public void stopProfiling() { + if (profiling) { + profiling = false; + Debug.stopMethodTracing(); + if (profileFd != null) { + try { + profileFd.close(); + } catch (IOException e) { + } + } + profileFd = null; + profileFile = null; + } + } } static final class DumpComponentInfo { @@ -463,7 +521,8 @@ public final class ActivityThread { public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) { + List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { ActivityClientRecord r = new ActivityClientRecord(); r.token = token; @@ -479,6 +538,10 @@ public final class ActivityThread { r.startsNotResumed = notResumed; r.isForward = isForward; + r.profileFile = profileName; + r.profileFd = profileFd; + r.autoStopProfiler = autoStopProfiler; + queueOrSendMessage(H.LAUNCH_ACTIVITY, r); } @@ -579,6 +642,7 @@ public final class ActivityThread { public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, String profileFile, + ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, int debugMode, boolean isRestrictedBackupMode, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, @@ -596,7 +660,8 @@ public final class ActivityThread { data.appInfo = appInfo; data.providers = providers; data.instrumentationName = instrumentationName; - data.profileFile = profileFile; + data.setProfiler(profileFile, profileFd); + data.autoStopProfiler = false; data.instrumentationArgs = instrumentationArgs; data.instrumentationWatcher = instrumentationWatcher; data.debugMode = debugMode; @@ -1225,6 +1290,10 @@ public final class ActivityThread { private class Idler implements MessageQueue.IdleHandler { public final boolean queueIdle() { ActivityClientRecord a = mNewActivities; + boolean stopProfiling = false; + if (mBoundApplication.profileFd != null && mBoundApplication.autoStopProfiler) { + stopProfiling = true; + } if (a != null) { mNewActivities = null; IActivityManager am = ActivityManagerNative.getDefault(); @@ -1236,7 +1305,7 @@ public final class ActivityThread { (a.activity != null && a.activity.mFinished)); if (a.activity != null && !a.activity.mFinished) { try { - am.activityIdle(a.token, a.createdConfig); + am.activityIdle(a.token, a.createdConfig, stopProfiling); a.createdConfig = null; } catch (RemoteException ex) { // Ignore @@ -1247,6 +1316,9 @@ public final class ActivityThread { prev.nextIdle = null; } while (a != null); } + if (stopProfiling) { + mBoundApplication.stopProfiling(); + } ensureJitEnabled(); return false; } @@ -1560,7 +1632,8 @@ public final class ActivityThread { } public boolean isProfiling() { - return mBoundApplication != null && mBoundApplication.profileFile != null; + return mBoundApplication != null && mBoundApplication.profileFile != null + && mBoundApplication.profileFd == null; } public String getProfileFilePath() { @@ -1870,6 +1943,13 @@ public final class ActivityThread { // we are back active so skip it. unscheduleGcIdler(); + Slog.i(TAG, "Launch: profileFd=" + r.profileFile + " stop=" + r.autoStopProfiler); + if (r.profileFd != null) { + mBoundApplication.setProfiler(r.profileFile, r.profileFd); + mBoundApplication.startProfiling(); + mBoundApplication.autoStopProfiler = r.autoStopProfiler; + } + if (localLOGV) Slog.v( TAG, "Handling launch of " + r); Activity a = performLaunchActivity(r, customIntent); @@ -3489,8 +3569,9 @@ public final class ActivityThread { ViewDebug.startLooperProfiling(pcd.path, pcd.fd.getFileDescriptor()); break; default: - Debug.startMethodTracing(pcd.path, pcd.fd.getFileDescriptor(), - 8 * 1024 * 1024, 0); + mBoundApplication.setProfiler(pcd.path, pcd.fd); + mBoundApplication.autoStopProfiler = false; + mBoundApplication.startProfiling(); break; } } catch (RuntimeException e) { @@ -3509,9 +3590,8 @@ public final class ActivityThread { ViewDebug.stopLooperProfiling(); break; default: - Debug.stopMethodTracing(); + mBoundApplication.stopProfiling(); break; - } } } @@ -3607,6 +3687,10 @@ public final class ActivityThread { Process.setArgV0(data.processName); android.ddm.DdmHandleAppName.setAppName(data.processName); + if (data.profileFd != null) { + data.startProfiling(); + } + // If the app is Honeycomb MR1 or earlier, switch its AsyncTask // implementation to use the pool executor. Normally, we use the // serialized executor as the default. This has to happen in the @@ -3745,7 +3829,8 @@ public final class ActivityThread { mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher); - if (data.profileFile != null && !ii.handleProfiling) { + if (data.profileFile != null && !ii.handleProfiling + && data.profileFd == null) { data.handlingProfiling = true; File file = new File(data.profileFile); file.getParentFile().mkdirs(); @@ -3799,7 +3884,8 @@ public final class ActivityThread { /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { IActivityManager am = ActivityManagerNative.getDefault(); - if (mBoundApplication.profileFile != null && mBoundApplication.handlingProfiling) { + if (mBoundApplication.profileFile != null && mBoundApplication.handlingProfiling + && mBoundApplication.profileFd == null) { Debug.stopMethodTracing(); } //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index bea057eb2677..0a6fdd4af98f 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -138,8 +138,12 @@ public abstract class ApplicationThreadNative extends Binder List<Intent> pi = data.createTypedArrayList(Intent.CREATOR); boolean notResumed = data.readInt() != 0; boolean isForward = data.readInt() != 0; + String profileName = data.readString(); + ParcelFileDescriptor profileFd = data.readInt() != 0 + ? data.readFileDescriptor() : null; + boolean autoStopProfiler = data.readInt() != 0; scheduleLaunchActivity(intent, b, ident, info, compatInfo, state, ri, pi, - notResumed, isForward); + notResumed, isForward, profileName, profileFd, autoStopProfiler); return true; } @@ -255,6 +259,9 @@ public abstract class ApplicationThreadNative extends Binder ComponentName testName = (data.readInt() != 0) ? new ComponentName(data) : null; String profileName = data.readString(); + ParcelFileDescriptor profileFd = data.readInt() != 0 + ? data.readFileDescriptor() : null; + boolean autoStopProfiler = data.readInt() != 0; Bundle testArgs = data.readBundle(); IBinder binder = data.readStrongBinder(); IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder); @@ -265,7 +272,7 @@ public abstract class ApplicationThreadNative extends Binder HashMap<String, IBinder> services = data.readHashMap(null); Bundle coreSettings = data.readBundle(); bindApplication(packageName, info, - providers, testName, profileName, + providers, testName, profileName, profileFd, autoStopProfiler, testArgs, testWatcher, testMode, restrictedBackupMode, config, compatInfo, services, coreSettings); return true; @@ -624,7 +631,8 @@ class ApplicationThreadProxy implements IApplicationThread { public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) + List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); @@ -638,6 +646,14 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeTypedList(pendingNewIntents); data.writeInt(notResumed ? 1 : 0); data.writeInt(isForward ? 1 : 0); + data.writeString(profileName); + if (profileFd != null) { + data.writeInt(1); + profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); + } else { + data.writeInt(0); + } + data.writeInt(autoStopProfiler ? 1 : 0); mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); @@ -793,8 +809,9 @@ class ApplicationThreadProxy implements IApplicationThread { } public final void bindApplication(String packageName, ApplicationInfo info, - List<ProviderInfo> providers, ComponentName testName, - String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode, + List<ProviderInfo> providers, ComponentName testName, String profileName, + ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle testArgs, + IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) throws RemoteException { Parcel data = Parcel.obtain(); @@ -809,6 +826,13 @@ class ApplicationThreadProxy implements IApplicationThread { testName.writeToParcel(data, 0); } data.writeString(profileName); + if (profileFd != null) { + data.writeInt(1); + profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); + } else { + data.writeInt(0); + } + data.writeInt(autoStopProfiler ? 1 : 0); data.writeBundle(testArgs); data.writeStrongInterface(testWatcher); data.writeInt(debugMode); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index b1b0583a5d7f..49f84497fa73 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -84,11 +84,13 @@ public interface IActivityManager extends IInterface { public int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, - boolean onlyIfNeeded, boolean debug) throws RemoteException; + boolean onlyIfNeeded, boolean debug, String profileFile, + ParcelFileDescriptor profileFd, boolean autoStopProfiler) throws RemoteException; public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, - boolean onlyIfNeeded, boolean debug) throws RemoteException; + boolean onlyIfNeeded, boolean debug, String profileFile, + ParcelFileDescriptor profileFd, boolean autoStopProfiler) throws RemoteException; public int startActivityWithConfig(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, @@ -118,7 +120,8 @@ public interface IActivityManager extends IInterface { public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; /* oneway */ - public void activityIdle(IBinder token, Configuration config) throws RemoteException; + public void activityIdle(IBinder token, Configuration config, + boolean stopProfiling) throws RemoteException; public void activityPaused(IBinder token) throws RemoteException; /* oneway */ public void activityStopped(IBinder token, Bundle state, diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 3a8eb285b997..9ae5ab19760b 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -55,7 +55,8 @@ public interface IApplicationThread extends IInterface { void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) + List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) throws RemoteException; void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, int configChanges, @@ -86,7 +87,8 @@ public interface IApplicationThread extends IInterface { static final int DEBUG_ON = 1; static final int DEBUG_WAIT = 2; void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers, - ComponentName testName, String profileName, Bundle testArguments, + ComponentName testName, String profileName, ParcelFileDescriptor profileFd, + boolean autoStopProfiler, Bundle testArguments, IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) throws RemoteException; diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index f99b42074018..f3bc495e2a91 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1379,7 +1379,7 @@ public class Instrumentation { .startActivity(whoThread, intent, intent.resolveTypeIfNeeded(who.getContentResolver()), null, 0, token, target != null ? target.mEmbeddedID : null, - requestCode, false, false); + requestCode, false, false, null, null, false); checkStartActivityResult(result, intent); } catch (RemoteException e) { } @@ -1475,7 +1475,7 @@ public class Instrumentation { .startActivity(whoThread, intent, intent.resolveTypeIfNeeded(who.getContentResolver()), null, 0, token, target != null ? target.mWho : null, - requestCode, false, false); + requestCode, false, false, null, null, false); checkStartActivityResult(result, intent); } catch (RemoteException e) { } diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 3ea3f5608ed9..ac15d9c6255b 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -129,6 +129,16 @@ public class ParcelFileDescriptor implements Parcelable { } /** + * Create a new ParcelFileDescriptor that is a dup of the existing + * FileDescriptor. This obeys standard POSIX semantics, where the + * new file descriptor shared state such as file position with the + * original file descriptor. + */ + public ParcelFileDescriptor dup() throws IOException { + return dup(getFileDescriptor()); + } + + /** * Create a new ParcelFileDescriptor from a raw native fd. The new * ParcelFileDescriptor holds a dup of the original fd passed in here, * so you must still close that fd as well as the new ParcelFileDescriptor. |
