summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-05-20 18:18:46 -0700
committerDianne Hackborn <hackbod@google.com>2015-05-21 16:45:29 -0700
commitb5a380d409a1431a38db978864b9d85b689e3cce (patch)
tree5cd36c4c095331869e1019739500b517fbf516a6 /core/java
parentaba3ecb976cacd7c92fe8f8afae20d112781d68e (diff)
downloadframeworks_base-b5a380d409a1431a38db978864b9d85b689e3cce.zip
frameworks_base-b5a380d409a1431a38db978864b9d85b689e3cce.tar.gz
frameworks_base-b5a380d409a1431a38db978864b9d85b689e3cce.tar.bz2
Add API to track usage time of apps.
This adds a new ActivityOption for the caller to ask the system to track the time the user is in the app it launches, delivering the result when they are done. The time interval tracked is from when the app launches the activity until the user leaves that app'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 they cross 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 gmail in a new task, and they complete the share, the time during that entire operation will be included. The user is considered to complete the operation once they switch to another activity that is not part of the tracked flow. For example, use 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. The data is delivered to the app through a PendingIntent, which includes the total time the app was in the flow along with a time break-down by app package. Change-Id: If1cf8892d422c52ec5042eba0e15a8e7e8f83abf
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityOptions.java68
1 files changed, 68 insertions, 0 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 8909b28..9f23b43 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -25,6 +25,7 @@ import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.util.Pair;
+import android.util.Slog;
import android.view.View;
import android.view.Window;
@@ -39,6 +40,19 @@ public class 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.
* @hide
*/
@@ -118,6 +132,8 @@ public class ActivityOptions {
private static final String KEY_RESULT_CODE = "android:resultCode";
private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex";
+ private static final String KEY_USAGE_TIME_REPORT = "android:usageTimeReport";
+
/** @hide */
public static final int ANIM_NONE = 0;
/** @hide */
@@ -160,6 +176,7 @@ public class ActivityOptions {
private Intent mResultData;
private int mResultCode;
private int mExitCoordinatorIndex;
+ private PendingIntent mUsageTimeReport;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -586,6 +603,15 @@ public class ActivityOptions {
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 */
public boolean getLaunchTaskBehind() {
return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
@@ -597,6 +623,11 @@ public class ActivityOptions {
/** @hide */
public ActivityOptions(Bundle opts) {
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);
switch (mAnimationType) {
case ANIM_CUSTOM:
@@ -730,6 +761,11 @@ public class ActivityOptions {
public Intent getResultData() { return mResultData; }
/** @hide */
+ public PendingIntent getUsageTimeReport() {
+ return mUsageTimeReport;
+ }
+
+ /** @hide */
public static void abort(Bundle options) {
if (options != null) {
(new ActivityOptions(options)).abort();
@@ -745,6 +781,7 @@ public class ActivityOptions {
if (otherOptions.mPackageName != null) {
mPackageName = otherOptions.mPackageName;
}
+ mUsageTimeReport = otherOptions.mUsageTimeReport;
mTransitionReceiver = null;
mSharedElementNames = null;
mIsReturning = false;
@@ -828,6 +865,9 @@ public class ActivityOptions {
b.putString(KEY_PACKAGE_NAME, mPackageName);
}
b.putInt(KEY_ANIM_TYPE, mAnimationType);
+ if (mUsageTimeReport != null) {
+ b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
+ }
switch (mAnimationType) {
case ANIM_CUSTOM:
b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
@@ -873,6 +913,34 @@ public class ActivityOptions {
}
/**
+ * 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
* @hide
*/