Merge "Work on issue #74404949: Screen state usage API" into pi-dev

am: 886fc6aef0

Change-Id: Ia612052dee8b7729900ab091ecae7db073f8d9fd
This commit is contained in:
Dianne Hackborn
2018-04-02 17:52:06 -07:00
committed by android-build-merger
9 changed files with 159 additions and 83 deletions

View File

@@ -7360,8 +7360,8 @@ package android.app.usage {
method public int getCount(); method public int getCount();
method public int getEventType(); method public int getEventType();
method public long getFirstTimeStamp(); method public long getFirstTimeStamp();
method public long getLastEventTime();
method public long getLastTimeStamp(); method public long getLastTimeStamp();
method public long getLastTimeUsed();
method public long getTotalTime(); method public long getTotalTime();
method public void writeToParcel(android.os.Parcel, int); method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.usage.EventStats> CREATOR; field public static final android.os.Parcelable.Creator<android.app.usage.EventStats> CREATOR;
@@ -7469,6 +7469,8 @@ package android.app.usage {
method public int getStandbyBucket(); method public int getStandbyBucket();
method public long getTimeStamp(); method public long getTimeStamp();
field public static final int CONFIGURATION_CHANGE = 5; // 0x5 field public static final int CONFIGURATION_CHANGE = 5; // 0x5
field public static final int KEYGUARD_HIDDEN = 18; // 0x12
field public static final int KEYGUARD_SHOWN = 17; // 0x11
field public static final int MOVE_TO_BACKGROUND = 2; // 0x2 field public static final int MOVE_TO_BACKGROUND = 2; // 0x2
field public static final int MOVE_TO_FOREGROUND = 1; // 0x1 field public static final int MOVE_TO_FOREGROUND = 1; // 0x1
field public static final int NONE = 0; // 0x0 field public static final int NONE = 0; // 0x0

View File

@@ -41,10 +41,9 @@ public final class EventStats implements Parcelable {
public long mEndTimeStamp; public long mEndTimeStamp;
/** /**
* Last time used by the user with an explicit action (notification, activity launch).
* {@hide} * {@hide}
*/ */
public long mLastTimeUsed; public long mLastEventTime;
/** /**
* {@hide} * {@hide}
@@ -66,7 +65,7 @@ public final class EventStats implements Parcelable {
mEventType = stats.mEventType; mEventType = stats.mEventType;
mBeginTimeStamp = stats.mBeginTimeStamp; mBeginTimeStamp = stats.mBeginTimeStamp;
mEndTimeStamp = stats.mEndTimeStamp; mEndTimeStamp = stats.mEndTimeStamp;
mLastTimeUsed = stats.mLastTimeUsed; mLastEventTime = stats.mLastEventTime;
mTotalTime = stats.mTotalTime; mTotalTime = stats.mTotalTime;
mCount = stats.mCount; mCount = stats.mCount;
} }
@@ -100,12 +99,12 @@ public final class EventStats implements Parcelable {
} }
/** /**
* Get the last time this event was used, measured in milliseconds since the epoch. * Get the last time this event triggered, measured in milliseconds since the epoch.
* <p/> * <p/>
* See {@link System#currentTimeMillis()}. * See {@link System#currentTimeMillis()}.
*/ */
public long getLastTimeUsed() { public long getLastEventTime() {
return mLastTimeUsed; return mLastEventTime;
} }
/** /**
@@ -138,7 +137,7 @@ public final class EventStats implements Parcelable {
// We use the mBeginTimeStamp due to a bug where UsageStats files can overlap with // We use the mBeginTimeStamp due to a bug where UsageStats files can overlap with
// regards to their mEndTimeStamp. // regards to their mEndTimeStamp.
if (right.mBeginTimeStamp > mBeginTimeStamp) { if (right.mBeginTimeStamp > mBeginTimeStamp) {
mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed); mLastEventTime = Math.max(mLastEventTime, right.mLastEventTime);
} }
mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp); mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp); mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
@@ -156,7 +155,7 @@ public final class EventStats implements Parcelable {
dest.writeInt(mEventType); dest.writeInt(mEventType);
dest.writeLong(mBeginTimeStamp); dest.writeLong(mBeginTimeStamp);
dest.writeLong(mEndTimeStamp); dest.writeLong(mEndTimeStamp);
dest.writeLong(mLastTimeUsed); dest.writeLong(mLastEventTime);
dest.writeLong(mTotalTime); dest.writeLong(mTotalTime);
dest.writeInt(mCount); dest.writeInt(mCount);
} }
@@ -168,7 +167,7 @@ public final class EventStats implements Parcelable {
stats.mEventType = in.readInt(); stats.mEventType = in.readInt();
stats.mBeginTimeStamp = in.readLong(); stats.mBeginTimeStamp = in.readLong();
stats.mEndTimeStamp = in.readLong(); stats.mEndTimeStamp = in.readLong();
stats.mLastTimeUsed = in.readLong(); stats.mLastEventTime = in.readLong();
stats.mTotalTime = in.readLong(); stats.mTotalTime = in.readLong();
stats.mCount = in.readInt(); stats.mCount = in.readInt();
return stats; return stats;

View File

@@ -152,6 +152,18 @@ public final class UsageEvents implements Parcelable {
*/ */
public static final int SCREEN_NON_INTERACTIVE = 16; public static final int SCREEN_NON_INTERACTIVE = 16;
/**
* An event type denoting that the screen's keyguard has been shown, whether or not
* the screen is off.
*/
public static final int KEYGUARD_SHOWN = 17;
/**
* An event type denoting that the screen's keyguard has been hidden. This typically
* happens when the user unlocks their phone after turning it on.
*/
public static final int KEYGUARD_HIDDEN = 18;
/** @hide */ /** @hide */
public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0; public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;

View File

@@ -319,6 +319,8 @@ public final class UsageStatsManager {
* <ul> * <ul>
* <li>{@link UsageEvents.Event#SCREEN_INTERACTIVE}</li> * <li>{@link UsageEvents.Event#SCREEN_INTERACTIVE}</li>
* <li>{@link UsageEvents.Event#SCREEN_NON_INTERACTIVE}</li> * <li>{@link UsageEvents.Event#SCREEN_NON_INTERACTIVE}</li>
* <li>{@link UsageEvents.Event#KEYGUARD_SHOWN}</li>
* <li>{@link UsageEvents.Event#KEYGUARD_HIDDEN}</li>
* </ul> * </ul>
* *
* <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>

View File

@@ -1529,6 +1529,11 @@ public class ActivityManagerService extends IActivityManager.Stub
*/ */
private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
/**
* State of external calls telling us if the device is awake or asleep.
*/
private boolean mKeyguardShown = false;
/** /**
* Set if we are shutting down the system, similar to sleeping. * Set if we are shutting down the system, similar to sleeping.
*/ */
@@ -12968,6 +12973,12 @@ public class ActivityManagerService extends IActivityManager.Stub
: UsageEvents.Event.SCREEN_NON_INTERACTIVE); : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
} }
void reportCurKeyguardUsageEventLocked() {
reportGlobalUsageEventLocked(mKeyguardShown
? UsageEvents.Event.KEYGUARD_SHOWN
: UsageEvents.Event.KEYGUARD_HIDDEN);
}
void onWakefulnessChanged(int wakefulness) { void onWakefulnessChanged(int wakefulness) {
synchronized(this) { synchronized(this) {
boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE; boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -13131,6 +13142,10 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized(this) { synchronized(this) {
long ident = Binder.clearCallingIdentity(); long ident = Binder.clearCallingIdentity();
if (mKeyguardShown != keyguardShowing) {
mKeyguardShown = keyguardShowing;
reportCurKeyguardUsageEventLocked();
}
try { try {
mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing, mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
secondaryDisplayShowing); secondaryDisplayShowing);

View File

@@ -1593,6 +1593,7 @@ class UserController implements Handler.Callback {
void onSystemReady() { void onSystemReady() {
updateCurrentProfileIds(); updateCurrentProfileIds();
mInjector.reportCurWakefulnessUsageEvent();
} }
/** /**

View File

@@ -30,12 +30,10 @@ class IntervalStats {
public long beginTime; public long beginTime;
public long endTime; public long endTime;
public long lastTimeSaved; public long lastTimeSaved;
public long lastInteractiveTime; public final EventTracker interactiveTracker = new EventTracker();
public long lastNonInteractiveTime; public final EventTracker nonInteractiveTracker = new EventTracker();
public long interactiveDuration; public final EventTracker keyguardShownTracker = new EventTracker();
public int interactiveCount; public final EventTracker keyguardHiddenTracker = new EventTracker();
public long nonInteractiveDuration;
public int nonInteractiveCount;
public final ArrayMap<String, UsageStats> packageStats = new ArrayMap<>(); public final ArrayMap<String, UsageStats> packageStats = new ArrayMap<>();
public final ArrayMap<Configuration, ConfigurationStats> configurations = new ArrayMap<>(); public final ArrayMap<Configuration, ConfigurationStats> configurations = new ArrayMap<>();
public Configuration activeConfiguration; public Configuration activeConfiguration;
@@ -47,6 +45,44 @@ class IntervalStats {
// strings that had identical copies in the cache. // strings that had identical copies in the cache.
private final ArraySet<String> mStringCache = new ArraySet<>(); private final ArraySet<String> mStringCache = new ArraySet<>();
public static final class EventTracker {
public long curStartTime;
public long lastEventTime;
public long duration;
public int count;
public void commitTime(long timeStamp) {
if (curStartTime != 0) {
duration += timeStamp - duration;
curStartTime = 0;
}
}
public void update(long timeStamp) {
if (curStartTime == 0) {
// If we aren't already running, time to bump the count.
count++;
}
commitTime(timeStamp);
curStartTime = timeStamp;
lastEventTime = timeStamp;
}
void addToEventStats(List<EventStats> out, int event, long beginTime, long endTime) {
if (count != 0 || duration != 0) {
EventStats ev = new EventStats();
ev.mEventType = event;
ev.mCount = count;
ev.mTotalTime = duration;
ev.mLastEventTime = lastEventTime;
ev.mBeginTimeStamp = beginTime;
ev.mEndTimeStamp = endTime;
out.add(ev);
}
}
}
/** /**
* Gets the UsageStats object for the given package, or creates one and adds it internally. * Gets the UsageStats object for the given package, or creates one and adds it internally.
*/ */
@@ -180,58 +216,42 @@ class IntervalStats {
usageStats.mAppLaunchCount += 1; usageStats.mAppLaunchCount += 1;
} }
private void commitInteractiveTime(long timeStamp) {
if (lastInteractiveTime != 0) {
interactiveDuration += timeStamp - lastInteractiveTime;
lastInteractiveTime = 0;
}
if (lastNonInteractiveTime != 0) {
nonInteractiveDuration += timeStamp - lastNonInteractiveTime;
lastNonInteractiveTime = 0;
}
}
void commitTime(long timeStamp) { void commitTime(long timeStamp) {
commitInteractiveTime(timeStamp); interactiveTracker.commitTime(timeStamp);
nonInteractiveTracker.commitTime(timeStamp);
keyguardShownTracker.commitTime(timeStamp);
keyguardHiddenTracker.commitTime(timeStamp);
} }
void updateScreenInteractive(long timeStamp) { void updateScreenInteractive(long timeStamp) {
if (lastInteractiveTime != 0) { interactiveTracker.update(timeStamp);
// Already interactive, just keep running. nonInteractiveTracker.commitTime(timeStamp);
return;
}
commitInteractiveTime(timeStamp);
lastInteractiveTime = timeStamp;
interactiveCount++;
} }
void updateScreenNonInteractive(long timeStamp) { void updateScreenNonInteractive(long timeStamp) {
if (lastNonInteractiveTime != 0) { nonInteractiveTracker.update(timeStamp);
// Already non-interactive, just keep running. interactiveTracker.commitTime(timeStamp);
return;
}
commitInteractiveTime(timeStamp);
lastNonInteractiveTime = timeStamp;
nonInteractiveCount++;
} }
private void addOneEventStats(List<EventStats> out, int event, int count, long duration) { void updateKeyguardShown(long timeStamp) {
if (count != 0 || duration != 0) { keyguardShownTracker.update(timeStamp);
EventStats ev = new EventStats(); keyguardHiddenTracker.commitTime(timeStamp);
ev.mEventType = event; }
ev.mCount = count;
ev.mTotalTime = duration; void updateKeyguardHidden(long timeStamp) {
ev.mBeginTimeStamp = beginTime; keyguardHiddenTracker.update(timeStamp);
ev.mEndTimeStamp = endTime; keyguardShownTracker.commitTime(timeStamp);
out.add(ev);
}
} }
void addEventStatsTo(List<EventStats> out) { void addEventStatsTo(List<EventStats> out) {
addOneEventStats(out, UsageEvents.Event.SCREEN_INTERACTIVE, interactiveCount, interactiveTracker.addToEventStats(out, UsageEvents.Event.SCREEN_INTERACTIVE,
interactiveDuration); beginTime, endTime);
addOneEventStats(out, UsageEvents.Event.SCREEN_NON_INTERACTIVE, nonInteractiveCount, nonInteractiveTracker.addToEventStats(out, UsageEvents.Event.SCREEN_NON_INTERACTIVE,
nonInteractiveDuration); beginTime, endTime);
keyguardShownTracker.addToEventStats(out, UsageEvents.Event.KEYGUARD_SHOWN,
beginTime, endTime);
keyguardHiddenTracker.addToEventStats(out, UsageEvents.Event.KEYGUARD_HIDDEN,
beginTime, endTime);
} }
private String getCachedStringRef(String str) { private String getCachedStringRef(String str) {

View File

@@ -40,6 +40,8 @@ final class UsageStatsXmlV1 {
private static final String INTERACTIVE_TAG = "interactive"; private static final String INTERACTIVE_TAG = "interactive";
private static final String NON_INTERACTIVE_TAG = "non-interactive"; private static final String NON_INTERACTIVE_TAG = "non-interactive";
private static final String KEYGUARD_SHOWN_TAG = "keyguard-shown";
private static final String KEYGUARD_HIDDEN_TAG = "keyguard-hidden";
private static final String PACKAGES_TAG = "packages"; private static final String PACKAGES_TAG = "packages";
private static final String PACKAGE_TAG = "package"; private static final String PACKAGE_TAG = "package";
@@ -103,12 +105,12 @@ final class UsageStatsXmlV1 {
} }
} }
private static Pair<Integer, Long> loadCountAndTime(XmlPullParser parser) private static void loadCountAndTime(XmlPullParser parser,
IntervalStats.EventTracker tracker)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
int count = XmlUtils.readIntAttribute(parser, COUNT_ATTR, 0); tracker.count = XmlUtils.readIntAttribute(parser, COUNT_ATTR, 0);
long time = XmlUtils.readLongAttribute(parser, TIME_ATTR, 0); tracker.duration = XmlUtils.readLongAttribute(parser, TIME_ATTR, 0);
XmlUtils.skipCurrentTag(parser); XmlUtils.skipCurrentTag(parser);
return new Pair<>(count, time);
} }
private static void loadChooserCounts( private static void loadChooserCounts(
@@ -340,17 +342,21 @@ final class UsageStatsXmlV1 {
final String tag = parser.getName(); final String tag = parser.getName();
switch (tag) { switch (tag) {
case INTERACTIVE_TAG: { case INTERACTIVE_TAG:
Pair<Integer, Long> result = loadCountAndTime(parser); loadCountAndTime(parser, statsOut.interactiveTracker);
statsOut.interactiveCount = result.first; break;
statsOut.interactiveDuration = result.second;
} break;
case NON_INTERACTIVE_TAG: { case NON_INTERACTIVE_TAG:
Pair<Integer, Long> result = loadCountAndTime(parser); loadCountAndTime(parser, statsOut.nonInteractiveTracker);
statsOut.nonInteractiveCount = result.first; break;
statsOut.nonInteractiveDuration = result.second;
} break; case KEYGUARD_SHOWN_TAG:
loadCountAndTime(parser, statsOut.keyguardShownTracker);
break;
case KEYGUARD_HIDDEN_TAG:
loadCountAndTime(parser, statsOut.keyguardHiddenTracker);
break;
case PACKAGE_TAG: case PACKAGE_TAG:
loadUsageStats(parser, statsOut); loadUsageStats(parser, statsOut);
@@ -378,10 +384,14 @@ final class UsageStatsXmlV1 {
public static void write(XmlSerializer xml, IntervalStats stats) throws IOException { public static void write(XmlSerializer xml, IntervalStats stats) throws IOException {
XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime); XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime);
writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveCount, stats.interactiveDuration); writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveTracker.count,
stats.interactiveTracker.duration);
writeCountAndTime(xml, NON_INTERACTIVE_TAG, stats.nonInteractiveCount, writeCountAndTime(xml, NON_INTERACTIVE_TAG, stats.nonInteractiveTracker.count,
stats.nonInteractiveDuration); stats.nonInteractiveTracker.duration);
writeCountAndTime(xml, KEYGUARD_SHOWN_TAG, stats.keyguardShownTracker.count,
stats.keyguardShownTracker.duration);
writeCountAndTime(xml, KEYGUARD_HIDDEN_TAG, stats.keyguardHiddenTracker.count,
stats.keyguardHiddenTracker.duration);
xml.startTag(null, PACKAGES_TAG); xml.startTag(null, PACKAGES_TAG);
final int statsCount = stats.packageStats.size(); final int statsCount = stats.packageStats.size();

View File

@@ -211,6 +211,12 @@ class UserUsageStatsService {
case UsageEvents.Event.SCREEN_NON_INTERACTIVE: { case UsageEvents.Event.SCREEN_NON_INTERACTIVE: {
stats.updateScreenNonInteractive(event.mTimeStamp); stats.updateScreenNonInteractive(event.mTimeStamp);
} break; } break;
case UsageEvents.Event.KEYGUARD_SHOWN: {
stats.updateKeyguardShown(event.mTimeStamp);
} break;
case UsageEvents.Event.KEYGUARD_HIDDEN: {
stats.updateKeyguardHidden(event.mTimeStamp);
} break;
default: { default: {
stats.update(event.mPackage, event.mTimeStamp, event.mEventType); stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
if (incrementAppLaunch) { if (incrementAppLaunch) {
@@ -665,14 +671,19 @@ class UserUsageStatsService {
} }
} }
void printEventAggregation(IndentingPrintWriter pw, String label, int count, long duration, void printEventAggregation(IndentingPrintWriter pw, String label,
boolean prettyDates) { IntervalStats.EventTracker tracker, boolean prettyDates) {
if (count != 0 || duration != 0) { if (tracker.count != 0 || tracker.duration != 0) {
pw.print(label); pw.print(label);
pw.print(": "); pw.print(": ");
pw.print(count); pw.print(tracker.count);
pw.print("x for "); pw.print("x for ");
pw.print(formatElapsedTime(duration, prettyDates)); pw.print(formatElapsedTime(tracker.duration, prettyDates));
if (tracker.curStartTime != 0) {
pw.print(" (now running, started at ");
formatDateTime(tracker.curStartTime, prettyDates);
pw.print(")");
}
pw.println(); pw.println();
} }
} }
@@ -752,10 +763,14 @@ class UserUsageStatsService {
pw.decreaseIndent(); pw.decreaseIndent();
pw.println("event aggregations"); pw.println("event aggregations");
pw.increaseIndent(); pw.increaseIndent();
printEventAggregation(pw, "screen-interactive", stats.interactiveCount, printEventAggregation(pw, "screen-interactive", stats.interactiveTracker,
stats.interactiveDuration, prettyDates); prettyDates);
printEventAggregation(pw, "screen-non-interactive", stats.nonInteractiveCount, printEventAggregation(pw, "screen-non-interactive", stats.nonInteractiveTracker,
stats.nonInteractiveDuration, prettyDates); prettyDates);
printEventAggregation(pw, "keyguard-shown", stats.keyguardShownTracker,
prettyDates);
printEventAggregation(pw, "keyguard-hidden", stats.keyguardHiddenTracker,
prettyDates);
pw.decreaseIndent(); pw.decreaseIndent();
} }