Loading api/current.txt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -3745,6 +3745,7 @@ package android.app { } } public class ActivityOptions { public class ActivityOptions { method public static android.app.ActivityOptions makeBasic(); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); Loading @@ -3752,8 +3753,11 @@ package android.app { method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public void requestUsageTimeReport(android.app.PendingIntent); method public android.os.Bundle toBundle(); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_REPORT_PACKAGES = "android.package"; field public static final java.lang.String EXTRA_USAGE_REPORT_TIME = "android.time"; } } public class AlarmManager { public class AlarmManager { api/system-current.txt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -3837,6 +3837,7 @@ package android.app { } } public class ActivityOptions { public class ActivityOptions { method public static android.app.ActivityOptions makeBasic(); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); Loading @@ -3844,8 +3845,11 @@ package android.app { method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public void requestUsageTimeReport(android.app.PendingIntent); method public android.os.Bundle toBundle(); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_REPORT_PACKAGES = "android.package"; field public static final java.lang.String EXTRA_USAGE_REPORT_TIME = "android.time"; } } public class AlarmManager { public class AlarmManager { core/java/android/app/ActivityOptions.java +68 −0 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.IRemoteCallback; import android.os.RemoteException; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ResultReceiver; import android.util.Pair; import android.util.Pair; import android.util.Slog; import android.view.View; import android.view.View; import android.view.Window; import android.view.Window; Loading @@ -38,6 +39,19 @@ import java.util.ArrayList; public class ActivityOptions { public class ActivityOptions { private static final String TAG = "ActivityOptions"; private static final String TAG = "ActivityOptions"; /** * A long in the extras delivered by {@link #requestUsageTimeReport} that contains * the total time (in ms) the user spent in the app. */ public static final String EXTRA_USAGE_REPORT_TIME = "android.time"; /** * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains * detailed information about the time spent in each package associated with the app; * each key is a package name, whose value is a long containing the time (in ms). */ public static final String EXTRA_USAGE_REPORT_PACKAGES = "android.package"; /** /** * The package name that created the options. * The package name that created the options. * @hide * @hide Loading Loading @@ -118,6 +132,8 @@ public class ActivityOptions { private static final String KEY_RESULT_CODE = "android:resultCode"; private static final String KEY_RESULT_CODE = "android:resultCode"; private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; private static final String KEY_USAGE_TIME_REPORT = "android:usageTimeReport"; /** @hide */ /** @hide */ public static final int ANIM_NONE = 0; public static final int ANIM_NONE = 0; /** @hide */ /** @hide */ Loading Loading @@ -160,6 +176,7 @@ public class ActivityOptions { private Intent mResultData; private Intent mResultData; private int mResultCode; private int mResultCode; private int mExitCoordinatorIndex; private int mExitCoordinatorIndex; private PendingIntent mUsageTimeReport; /** /** * Create an ActivityOptions specifying a custom animation to run when * Create an ActivityOptions specifying a custom animation to run when Loading Loading @@ -586,6 +603,15 @@ public class ActivityOptions { return opts; return opts; } } /** * Create a basic ActivityOptions that has no special animation associated with it. * Other options can still be set. */ public static ActivityOptions makeBasic() { final ActivityOptions opts = new ActivityOptions(); return opts; } /** @hide */ /** @hide */ public boolean getLaunchTaskBehind() { public boolean getLaunchTaskBehind() { return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; Loading @@ -597,6 +623,11 @@ public class ActivityOptions { /** @hide */ /** @hide */ public ActivityOptions(Bundle opts) { public ActivityOptions(Bundle opts) { mPackageName = opts.getString(KEY_PACKAGE_NAME); mPackageName = opts.getString(KEY_PACKAGE_NAME); try { mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT); } catch (RuntimeException e) { Slog.w(TAG, e); } mAnimationType = opts.getInt(KEY_ANIM_TYPE); mAnimationType = opts.getInt(KEY_ANIM_TYPE); switch (mAnimationType) { switch (mAnimationType) { case ANIM_CUSTOM: case ANIM_CUSTOM: Loading Loading @@ -729,6 +760,11 @@ public class ActivityOptions { /** @hide */ /** @hide */ public Intent getResultData() { return mResultData; } public Intent getResultData() { return mResultData; } /** @hide */ public PendingIntent getUsageTimeReport() { return mUsageTimeReport; } /** @hide */ /** @hide */ public static void abort(Bundle options) { public static void abort(Bundle options) { if (options != null) { if (options != null) { Loading @@ -745,6 +781,7 @@ public class ActivityOptions { if (otherOptions.mPackageName != null) { if (otherOptions.mPackageName != null) { mPackageName = otherOptions.mPackageName; mPackageName = otherOptions.mPackageName; } } mUsageTimeReport = otherOptions.mUsageTimeReport; mTransitionReceiver = null; mTransitionReceiver = null; mSharedElementNames = null; mSharedElementNames = null; mIsReturning = false; mIsReturning = false; Loading Loading @@ -828,6 +865,9 @@ public class ActivityOptions { b.putString(KEY_PACKAGE_NAME, mPackageName); b.putString(KEY_PACKAGE_NAME, mPackageName); } } b.putInt(KEY_ANIM_TYPE, mAnimationType); b.putInt(KEY_ANIM_TYPE, mAnimationType); if (mUsageTimeReport != null) { b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport); } switch (mAnimationType) { switch (mAnimationType) { case ANIM_CUSTOM: case ANIM_CUSTOM: b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); Loading Loading @@ -872,6 +912,34 @@ public class ActivityOptions { return b; return b; } } /** * Ask the the system track that time the user spends in the app being launched, and * report it back once done. The report will be sent to the given receiver, with * the extras {@link #EXTRA_USAGE_REPORT_TIME} and {@link #EXTRA_USAGE_REPORT_PACKAGES} * filled in. * * <p>The time interval tracked is from launching this activity until the user leaves * that activity's flow. They are considered to stay in the flow as long as * new activities are being launched or returned to from the original flow, * even if this crosses package or task boundaries. For example, if the originator * starts an activity to view an image, and while there the user selects to share, * which launches their email app in a new task, and they complete the share, the * time during that entire operation will be included until they finally hit back from * the original image viewer activity.</p> * * <p>The user is considered to complete a flow once they switch to another * activity that is not part of the tracked flow. This may happen, for example, by * using the notification shade, launcher, or recents to launch or switch to another * app. Simply going in to these navigation elements does not break the flow (although * the launcher and recents stops time tracking of the session); it is the act of * going somewhere else that completes the tracking.</p> * * @param receiver A broadcast receiver that willl receive the report. */ public void requestUsageTimeReport(PendingIntent receiver) { mUsageTimeReport = receiver; } /** /** * Return the filtered options only meant to be seen by the target activity itself * Return the filtered options only meant to be seen by the target activity itself * @hide * @hide Loading services/core/java/com/android/server/am/ActivityManagerService.java +47 −3 Original line number Original line Diff line number Diff line Loading @@ -425,6 +425,11 @@ public final class ActivityManagerService extends ActivityManagerNative */ */ private int mLastFocusedUserId; private int mLastFocusedUserId; /** * If non-null, we are tracking the time the user spends in the currently focused app. */ private AppTimeTracker mCurAppTimeTracker; /** /** * List of intents that were used to start the most recent tasks. * List of intents that were used to start the most recent tasks. */ */ Loading Loading @@ -1330,7 +1335,8 @@ public final class ActivityManagerService extends ActivityManagerNative static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51; static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51; static final int DELETE_DUMPHEAP_MSG = 52; static final int DELETE_DUMPHEAP_MSG = 52; static final int FOREGROUND_PROFILE_CHANGED_MSG = 53; static final int FOREGROUND_PROFILE_CHANGED_MSG = 53; static final int DISPATCH_UIDS_CHANGED = 54; static final int DISPATCH_UIDS_CHANGED_MSG = 54; static final int REPORT_TIME_TRACKER_MSG = 55; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; static final int FIRST_BROADCAST_QUEUE_MSG = 200; Loading Loading @@ -1563,7 +1569,7 @@ public final class ActivityManagerService extends ActivityManagerNative dispatchProcessDied(pid, uid); dispatchProcessDied(pid, uid); break; break; } } case DISPATCH_UIDS_CHANGED: { case DISPATCH_UIDS_CHANGED_MSG: { dispatchUidsChanged(); dispatchUidsChanged(); } break; } break; } } Loading Loading @@ -1988,6 +1994,10 @@ public final class ActivityManagerService extends ActivityManagerNative case FOREGROUND_PROFILE_CHANGED_MSG: { case FOREGROUND_PROFILE_CHANGED_MSG: { dispatchForegroundProfileChanged(msg.arg1); dispatchForegroundProfileChanged(msg.arg1); } break; } break; case REPORT_TIME_TRACKER_MSG: { AppTimeTracker tracker = (AppTimeTracker)msg.obj; tracker.deliverResult(mContext); } break; } } } } }; }; Loading Loading @@ -2573,6 +2583,27 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r); if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r); ActivityRecord last = mFocusedActivity; ActivityRecord last = mFocusedActivity; mFocusedActivity = r; mFocusedActivity = r; if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) { if (mCurAppTimeTracker != r.appTimeTracker) { // We are switching app tracking. Complete the current one. if (mCurAppTimeTracker != null) { mCurAppTimeTracker.stop(); mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget(); mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker); mCurAppTimeTracker = null; } if (r.appTimeTracker != null) { mCurAppTimeTracker = r.appTimeTracker; startTimeTrackingFocusedActivityLocked(); } } else { startTimeTrackingFocusedActivityLocked(); } } else { r.appTimeTracker = null; } if (r.task != null && r.task.voiceInteractor != null) { if (r.task != null && r.task.voiceInteractor != null) { startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid); startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid); } else { } else { Loading Loading @@ -10132,14 +10163,24 @@ public final class ActivityManagerService extends ActivityManagerNative } } } } void startTimeTrackingFocusedActivityLocked() { if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) { mCurAppTimeTracker.start(mFocusedActivity.packageName); } } void updateSleepIfNeededLocked() { void updateSleepIfNeededLocked() { if (mSleeping && !shouldSleepLocked()) { if (mSleeping && !shouldSleepLocked()) { mSleeping = false; mSleeping = false; startTimeTrackingFocusedActivityLocked(); mTopProcessState = ActivityManager.PROCESS_STATE_TOP; mTopProcessState = ActivityManager.PROCESS_STATE_TOP; mStackSupervisor.comeOutOfSleepIfNeededLocked(); mStackSupervisor.comeOutOfSleepIfNeededLocked(); updateOomAdjLocked(); updateOomAdjLocked(); } else if (!mSleeping && shouldSleepLocked()) { } else if (!mSleeping && shouldSleepLocked()) { mSleeping = true; mSleeping = true; if (mCurAppTimeTracker != null) { mCurAppTimeTracker.stop(); } mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; mStackSupervisor.goingToSleepLocked(); mStackSupervisor.goingToSleepLocked(); updateOomAdjLocked(); updateOomAdjLocked(); Loading Loading @@ -13342,6 +13383,9 @@ public final class ActivityManagerService extends ActivityManagerNative + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); } } } } if (mCurAppTimeTracker != null) { mCurAppTimeTracker.dumpWithHeader(pw, " ", true); } if (mMemWatchProcesses.getMap().size() > 0) { if (mMemWatchProcesses.getMap().size() > 0) { pw.println(" Mem watch processes:"); pw.println(" Mem watch processes:"); final ArrayMap<String, SparseArray<Pair<Long, String>>> procs final ArrayMap<String, SparseArray<Pair<Long, String>>> procs Loading Loading @@ -18460,7 +18504,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (mPendingUidChanges.size() == 0) { if (mPendingUidChanges.size() == 0) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "*** Enqueueing dispatch uid changed!"); "*** Enqueueing dispatch uid changed!"); mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED).sendToTarget(); mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget(); } } final int NA = mAvailUidChanges.size(); final int NA = mAvailUidChanges.size(); if (NA > 0) { if (NA > 0) { services/core/java/com/android/server/am/ActivityRecord.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.*; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskDescription; import android.app.PendingIntent; import android.os.PersistableBundle; import android.os.PersistableBundle; import android.os.Trace; import android.os.Trace; Loading Loading @@ -142,6 +143,7 @@ final class ActivityRecord { ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode ActivityOptions pendingOptions; // most recently given options ActivityOptions pendingOptions; // most recently given options ActivityOptions returningOptions; // options that are coming back via convertToTranslucent ActivityOptions returningOptions; // options that are coming back via convertToTranslucent AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold UriPermissionOwner uriPermissions; // current special URI access perms. UriPermissionOwner uriPermissions; // current special URI access perms. ProcessRecord app; // if non-null, hosting application ProcessRecord app; // if non-null, hosting application Loading Loading @@ -262,6 +264,9 @@ final class ActivityRecord { if (pendingOptions != null) { if (pendingOptions != null) { pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions); pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions); } } if (appTimeTracker != null) { appTimeTracker.dumpWithHeader(pw, prefix, false); } if (uriPermissions != null) { if (uriPermissions != null) { uriPermissions.dump(pw, prefix); uriPermissions.dump(pw, prefix); } } Loading Loading @@ -463,6 +468,10 @@ final class ActivityRecord { if (options != null) { if (options != null) { pendingOptions = new ActivityOptions(options); pendingOptions = new ActivityOptions(options); mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind(); mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind(); PendingIntent usageReport = pendingOptions.getUsageTimeReport(); if (usageReport != null) { appTimeTracker = new AppTimeTracker(usageReport); } } } // This starts out true, since the initial state of an activity // This starts out true, since the initial state of an activity Loading Loading
api/current.txt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -3745,6 +3745,7 @@ package android.app { } } public class ActivityOptions { public class ActivityOptions { method public static android.app.ActivityOptions makeBasic(); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); Loading @@ -3752,8 +3753,11 @@ package android.app { method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public void requestUsageTimeReport(android.app.PendingIntent); method public android.os.Bundle toBundle(); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_REPORT_PACKAGES = "android.package"; field public static final java.lang.String EXTRA_USAGE_REPORT_TIME = "android.time"; } } public class AlarmManager { public class AlarmManager {
api/system-current.txt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -3837,6 +3837,7 @@ package android.app { } } public class ActivityOptions { public class ActivityOptions { method public static android.app.ActivityOptions makeBasic(); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); Loading @@ -3844,8 +3845,11 @@ package android.app { method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeTaskLaunchBehind(); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public void requestUsageTimeReport(android.app.PendingIntent); method public android.os.Bundle toBundle(); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_REPORT_PACKAGES = "android.package"; field public static final java.lang.String EXTRA_USAGE_REPORT_TIME = "android.time"; } } public class AlarmManager { public class AlarmManager {
core/java/android/app/ActivityOptions.java +68 −0 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.IRemoteCallback; import android.os.RemoteException; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ResultReceiver; import android.util.Pair; import android.util.Pair; import android.util.Slog; import android.view.View; import android.view.View; import android.view.Window; import android.view.Window; Loading @@ -38,6 +39,19 @@ import java.util.ArrayList; public class ActivityOptions { public class ActivityOptions { private static final String TAG = "ActivityOptions"; private static final String TAG = "ActivityOptions"; /** * A long in the extras delivered by {@link #requestUsageTimeReport} that contains * the total time (in ms) the user spent in the app. */ public static final String EXTRA_USAGE_REPORT_TIME = "android.time"; /** * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains * detailed information about the time spent in each package associated with the app; * each key is a package name, whose value is a long containing the time (in ms). */ public static final String EXTRA_USAGE_REPORT_PACKAGES = "android.package"; /** /** * The package name that created the options. * The package name that created the options. * @hide * @hide Loading Loading @@ -118,6 +132,8 @@ public class ActivityOptions { private static final String KEY_RESULT_CODE = "android:resultCode"; private static final String KEY_RESULT_CODE = "android:resultCode"; private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; private static final String KEY_USAGE_TIME_REPORT = "android:usageTimeReport"; /** @hide */ /** @hide */ public static final int ANIM_NONE = 0; public static final int ANIM_NONE = 0; /** @hide */ /** @hide */ Loading Loading @@ -160,6 +176,7 @@ public class ActivityOptions { private Intent mResultData; private Intent mResultData; private int mResultCode; private int mResultCode; private int mExitCoordinatorIndex; private int mExitCoordinatorIndex; private PendingIntent mUsageTimeReport; /** /** * Create an ActivityOptions specifying a custom animation to run when * Create an ActivityOptions specifying a custom animation to run when Loading Loading @@ -586,6 +603,15 @@ public class ActivityOptions { return opts; return opts; } } /** * Create a basic ActivityOptions that has no special animation associated with it. * Other options can still be set. */ public static ActivityOptions makeBasic() { final ActivityOptions opts = new ActivityOptions(); return opts; } /** @hide */ /** @hide */ public boolean getLaunchTaskBehind() { public boolean getLaunchTaskBehind() { return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; Loading @@ -597,6 +623,11 @@ public class ActivityOptions { /** @hide */ /** @hide */ public ActivityOptions(Bundle opts) { public ActivityOptions(Bundle opts) { mPackageName = opts.getString(KEY_PACKAGE_NAME); mPackageName = opts.getString(KEY_PACKAGE_NAME); try { mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT); } catch (RuntimeException e) { Slog.w(TAG, e); } mAnimationType = opts.getInt(KEY_ANIM_TYPE); mAnimationType = opts.getInt(KEY_ANIM_TYPE); switch (mAnimationType) { switch (mAnimationType) { case ANIM_CUSTOM: case ANIM_CUSTOM: Loading Loading @@ -729,6 +760,11 @@ public class ActivityOptions { /** @hide */ /** @hide */ public Intent getResultData() { return mResultData; } public Intent getResultData() { return mResultData; } /** @hide */ public PendingIntent getUsageTimeReport() { return mUsageTimeReport; } /** @hide */ /** @hide */ public static void abort(Bundle options) { public static void abort(Bundle options) { if (options != null) { if (options != null) { Loading @@ -745,6 +781,7 @@ public class ActivityOptions { if (otherOptions.mPackageName != null) { if (otherOptions.mPackageName != null) { mPackageName = otherOptions.mPackageName; mPackageName = otherOptions.mPackageName; } } mUsageTimeReport = otherOptions.mUsageTimeReport; mTransitionReceiver = null; mTransitionReceiver = null; mSharedElementNames = null; mSharedElementNames = null; mIsReturning = false; mIsReturning = false; Loading Loading @@ -828,6 +865,9 @@ public class ActivityOptions { b.putString(KEY_PACKAGE_NAME, mPackageName); b.putString(KEY_PACKAGE_NAME, mPackageName); } } b.putInt(KEY_ANIM_TYPE, mAnimationType); b.putInt(KEY_ANIM_TYPE, mAnimationType); if (mUsageTimeReport != null) { b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport); } switch (mAnimationType) { switch (mAnimationType) { case ANIM_CUSTOM: case ANIM_CUSTOM: b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); Loading Loading @@ -872,6 +912,34 @@ public class ActivityOptions { return b; return b; } } /** * Ask the the system track that time the user spends in the app being launched, and * report it back once done. The report will be sent to the given receiver, with * the extras {@link #EXTRA_USAGE_REPORT_TIME} and {@link #EXTRA_USAGE_REPORT_PACKAGES} * filled in. * * <p>The time interval tracked is from launching this activity until the user leaves * that activity's flow. They are considered to stay in the flow as long as * new activities are being launched or returned to from the original flow, * even if this crosses package or task boundaries. For example, if the originator * starts an activity to view an image, and while there the user selects to share, * which launches their email app in a new task, and they complete the share, the * time during that entire operation will be included until they finally hit back from * the original image viewer activity.</p> * * <p>The user is considered to complete a flow once they switch to another * activity that is not part of the tracked flow. This may happen, for example, by * using the notification shade, launcher, or recents to launch or switch to another * app. Simply going in to these navigation elements does not break the flow (although * the launcher and recents stops time tracking of the session); it is the act of * going somewhere else that completes the tracking.</p> * * @param receiver A broadcast receiver that willl receive the report. */ public void requestUsageTimeReport(PendingIntent receiver) { mUsageTimeReport = receiver; } /** /** * Return the filtered options only meant to be seen by the target activity itself * Return the filtered options only meant to be seen by the target activity itself * @hide * @hide Loading
services/core/java/com/android/server/am/ActivityManagerService.java +47 −3 Original line number Original line Diff line number Diff line Loading @@ -425,6 +425,11 @@ public final class ActivityManagerService extends ActivityManagerNative */ */ private int mLastFocusedUserId; private int mLastFocusedUserId; /** * If non-null, we are tracking the time the user spends in the currently focused app. */ private AppTimeTracker mCurAppTimeTracker; /** /** * List of intents that were used to start the most recent tasks. * List of intents that were used to start the most recent tasks. */ */ Loading Loading @@ -1330,7 +1335,8 @@ public final class ActivityManagerService extends ActivityManagerNative static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51; static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51; static final int DELETE_DUMPHEAP_MSG = 52; static final int DELETE_DUMPHEAP_MSG = 52; static final int FOREGROUND_PROFILE_CHANGED_MSG = 53; static final int FOREGROUND_PROFILE_CHANGED_MSG = 53; static final int DISPATCH_UIDS_CHANGED = 54; static final int DISPATCH_UIDS_CHANGED_MSG = 54; static final int REPORT_TIME_TRACKER_MSG = 55; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; static final int FIRST_BROADCAST_QUEUE_MSG = 200; Loading Loading @@ -1563,7 +1569,7 @@ public final class ActivityManagerService extends ActivityManagerNative dispatchProcessDied(pid, uid); dispatchProcessDied(pid, uid); break; break; } } case DISPATCH_UIDS_CHANGED: { case DISPATCH_UIDS_CHANGED_MSG: { dispatchUidsChanged(); dispatchUidsChanged(); } break; } break; } } Loading Loading @@ -1988,6 +1994,10 @@ public final class ActivityManagerService extends ActivityManagerNative case FOREGROUND_PROFILE_CHANGED_MSG: { case FOREGROUND_PROFILE_CHANGED_MSG: { dispatchForegroundProfileChanged(msg.arg1); dispatchForegroundProfileChanged(msg.arg1); } break; } break; case REPORT_TIME_TRACKER_MSG: { AppTimeTracker tracker = (AppTimeTracker)msg.obj; tracker.deliverResult(mContext); } break; } } } } }; }; Loading Loading @@ -2573,6 +2583,27 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r); if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r); ActivityRecord last = mFocusedActivity; ActivityRecord last = mFocusedActivity; mFocusedActivity = r; mFocusedActivity = r; if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) { if (mCurAppTimeTracker != r.appTimeTracker) { // We are switching app tracking. Complete the current one. if (mCurAppTimeTracker != null) { mCurAppTimeTracker.stop(); mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget(); mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker); mCurAppTimeTracker = null; } if (r.appTimeTracker != null) { mCurAppTimeTracker = r.appTimeTracker; startTimeTrackingFocusedActivityLocked(); } } else { startTimeTrackingFocusedActivityLocked(); } } else { r.appTimeTracker = null; } if (r.task != null && r.task.voiceInteractor != null) { if (r.task != null && r.task.voiceInteractor != null) { startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid); startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid); } else { } else { Loading Loading @@ -10132,14 +10163,24 @@ public final class ActivityManagerService extends ActivityManagerNative } } } } void startTimeTrackingFocusedActivityLocked() { if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) { mCurAppTimeTracker.start(mFocusedActivity.packageName); } } void updateSleepIfNeededLocked() { void updateSleepIfNeededLocked() { if (mSleeping && !shouldSleepLocked()) { if (mSleeping && !shouldSleepLocked()) { mSleeping = false; mSleeping = false; startTimeTrackingFocusedActivityLocked(); mTopProcessState = ActivityManager.PROCESS_STATE_TOP; mTopProcessState = ActivityManager.PROCESS_STATE_TOP; mStackSupervisor.comeOutOfSleepIfNeededLocked(); mStackSupervisor.comeOutOfSleepIfNeededLocked(); updateOomAdjLocked(); updateOomAdjLocked(); } else if (!mSleeping && shouldSleepLocked()) { } else if (!mSleeping && shouldSleepLocked()) { mSleeping = true; mSleeping = true; if (mCurAppTimeTracker != null) { mCurAppTimeTracker.stop(); } mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; mStackSupervisor.goingToSleepLocked(); mStackSupervisor.goingToSleepLocked(); updateOomAdjLocked(); updateOomAdjLocked(); Loading Loading @@ -13342,6 +13383,9 @@ public final class ActivityManagerService extends ActivityManagerNative + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); } } } } if (mCurAppTimeTracker != null) { mCurAppTimeTracker.dumpWithHeader(pw, " ", true); } if (mMemWatchProcesses.getMap().size() > 0) { if (mMemWatchProcesses.getMap().size() > 0) { pw.println(" Mem watch processes:"); pw.println(" Mem watch processes:"); final ArrayMap<String, SparseArray<Pair<Long, String>>> procs final ArrayMap<String, SparseArray<Pair<Long, String>>> procs Loading Loading @@ -18460,7 +18504,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (mPendingUidChanges.size() == 0) { if (mPendingUidChanges.size() == 0) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "*** Enqueueing dispatch uid changed!"); "*** Enqueueing dispatch uid changed!"); mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED).sendToTarget(); mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget(); } } final int NA = mAvailUidChanges.size(); final int NA = mAvailUidChanges.size(); if (NA > 0) { if (NA > 0) {
services/core/java/com/android/server/am/ActivityRecord.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.*; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskDescription; import android.app.PendingIntent; import android.os.PersistableBundle; import android.os.PersistableBundle; import android.os.Trace; import android.os.Trace; Loading Loading @@ -142,6 +143,7 @@ final class ActivityRecord { ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode ActivityOptions pendingOptions; // most recently given options ActivityOptions pendingOptions; // most recently given options ActivityOptions returningOptions; // options that are coming back via convertToTranslucent ActivityOptions returningOptions; // options that are coming back via convertToTranslucent AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold UriPermissionOwner uriPermissions; // current special URI access perms. UriPermissionOwner uriPermissions; // current special URI access perms. ProcessRecord app; // if non-null, hosting application ProcessRecord app; // if non-null, hosting application Loading Loading @@ -262,6 +264,9 @@ final class ActivityRecord { if (pendingOptions != null) { if (pendingOptions != null) { pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions); pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions); } } if (appTimeTracker != null) { appTimeTracker.dumpWithHeader(pw, prefix, false); } if (uriPermissions != null) { if (uriPermissions != null) { uriPermissions.dump(pw, prefix); uriPermissions.dump(pw, prefix); } } Loading Loading @@ -463,6 +468,10 @@ final class ActivityRecord { if (options != null) { if (options != null) { pendingOptions = new ActivityOptions(options); pendingOptions = new ActivityOptions(options); mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind(); mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind(); PendingIntent usageReport = pendingOptions.getUsageTimeReport(); if (usageReport != null) { appTimeTracker = new AppTimeTracker(usageReport); } } } // This starts out true, since the initial state of an activity // This starts out true, since the initial state of an activity Loading