summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2014-08-26 20:09:06 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-26 20:09:07 +0000
commit1dc0f364010083057bdf104cc6e27c870cae8702 (patch)
treee02dd37ef27f7f4dd6741b5989624dc0fa08bb27
parent5b62d263a70ad7dceba7a488b11478ad3eaf3f45 (diff)
parent9d9607527f5bbf49c96565b63b90e36276b0dda7 (diff)
downloadframeworks_base-1dc0f364010083057bdf104cc6e27c870cae8702.zip
frameworks_base-1dc0f364010083057bdf104cc6e27c870cae8702.tar.gz
frameworks_base-1dc0f364010083057bdf104cc6e27c870cae8702.tar.bz2
Merge "Split up ComponentName in UsageEvents.Event" into lmp-dev
-rw-r--r--api/current.txt3
-rw-r--r--core/java/android/app/usage/UsageEvents.java79
-rw-r--r--services/usage/java/com/android/server/usage/IntervalStats.java39
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java3
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsXmlV1.java34
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java17
-rw-r--r--tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java2
7 files changed, 124 insertions, 53 deletions
diff --git a/api/current.txt b/api/current.txt
index ba97e21..a820163 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5719,8 +5719,9 @@ package android.app.usage {
public static final class UsageEvents.Event {
ctor public UsageEvents.Event();
- method public android.content.ComponentName getComponent();
+ method public java.lang.String getClassName();
method public int getEventType();
+ method public java.lang.String getPackageName();
method public long getTimeStamp();
field public static final int MOVE_TO_BACKGROUND = 2; // 0x2
field public static final int MOVE_TO_FOREGROUND = 1; // 0x1
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index d1ebc5f..2431ad0 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -65,7 +65,12 @@ public final class UsageEvents implements Parcelable {
/**
* {@hide}
*/
- public ComponentName mComponent;
+ public String mPackage;
+
+ /**
+ * {@hide}
+ */
+ public String mClass;
/**
* {@hide}
@@ -78,10 +83,26 @@ public final class UsageEvents implements Parcelable {
public int mEventType;
/**
- * The component this event represents.
+ * TODO(adamlesinski): Removed before release.
+ * {@hide}
*/
public ComponentName getComponent() {
- return mComponent;
+ return new ComponentName(mPackage, mClass);
+ }
+
+ /**
+ * The package name of the source of this event.
+ */
+ public String getPackageName() {
+ return mPackage;
+ }
+
+ /**
+ * The class name of the source of this event. This may be null for
+ * certain events.
+ */
+ public String getClassName() {
+ return mClass;
}
/**
@@ -115,7 +136,7 @@ public final class UsageEvents implements Parcelable {
* In order to save space, since ComponentNames will be duplicated everywhere,
* we use a map and index into it.
*/
- private ComponentName[] mComponentNameTable;
+ private String[] mStringPool;
/**
* Construct the iterator from a parcel.
@@ -125,7 +146,7 @@ public final class UsageEvents implements Parcelable {
mEventCount = in.readInt();
mIndex = in.readInt();
if (mEventCount > 0) {
- mComponentNameTable = in.createTypedArray(ComponentName.CREATOR);
+ mStringPool = in.createStringArray();
final int listByteLength = in.readInt();
final int positionInParcel = in.readInt();
@@ -149,8 +170,8 @@ public final class UsageEvents implements Parcelable {
* Construct the iterator in preparation for writing it to a parcel.
* {@hide}
*/
- public UsageEvents(List<Event> events, ComponentName[] nameTable) {
- mComponentNameTable = nameTable;
+ public UsageEvents(List<Event> events, String[] stringPool) {
+ mStringPool = stringPool;
mEventCount = events.size();
mEventsToWrite = events;
}
@@ -178,8 +199,19 @@ public final class UsageEvents implements Parcelable {
return false;
}
- final int index = mParcel.readInt();
- eventOut.mComponent = mComponentNameTable[index];
+ final int packageIndex = mParcel.readInt();
+ if (packageIndex >= 0) {
+ eventOut.mPackage = mStringPool[packageIndex];
+ } else {
+ eventOut.mPackage = null;
+ }
+
+ final int classIndex = mParcel.readInt();
+ if (classIndex >= 0) {
+ eventOut.mClass = mStringPool[classIndex];
+ } else {
+ eventOut.mClass = null;
+ }
eventOut.mEventType = mParcel.readInt();
eventOut.mTimeStamp = mParcel.readLong();
mIndex++;
@@ -206,12 +238,20 @@ public final class UsageEvents implements Parcelable {
return 0;
}
+ private int findStringIndex(String str) {
+ final int index = Arrays.binarySearch(mStringPool, str);
+ if (index < 0) {
+ throw new IllegalStateException("String '" + str + "' is not in the string pool");
+ }
+ return index;
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mEventCount);
dest.writeInt(mIndex);
if (mEventCount > 0) {
- dest.writeTypedArray(mComponentNameTable, flags);
+ dest.writeStringArray(mStringPool);
if (mEventsToWrite != null) {
// Write out the events
@@ -221,12 +261,21 @@ public final class UsageEvents implements Parcelable {
for (int i = 0; i < mEventCount; i++) {
final Event event = mEventsToWrite.get(i);
- int index = Arrays.binarySearch(mComponentNameTable, event.getComponent());
- if (index < 0) {
- throw new IllegalStateException(event.getComponent().toShortString() +
- " is not in the component name table");
+ final int packageIndex;
+ if (event.mPackage != null) {
+ packageIndex = findStringIndex(event.mPackage);
+ } else {
+ packageIndex = -1;
+ }
+
+ final int classIndex;
+ if (event.mClass != null) {
+ classIndex = findStringIndex(event.mClass);
+ } else {
+ classIndex = -1;
}
- p.writeInt(index);
+ p.writeInt(packageIndex);
+ p.writeInt(classIndex);
p.writeInt(event.getEventType());
p.writeLong(event.getTimeStamp());
}
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index 43027ad..dc036e2 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -18,8 +18,8 @@ package com.android.server.usage;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
-import android.content.ComponentName;
import android.util.ArrayMap;
+import android.util.ArraySet;
class IntervalStats {
public long beginTime;
@@ -28,10 +28,11 @@ class IntervalStats {
public final ArrayMap<String, UsageStats> stats = new ArrayMap<>();
public TimeSparseArray<UsageEvents.Event> events;
- // Maps flattened string representations of component names to ComponentName.
- // This helps save memory from using many duplicate ComponentNames and
- // parse time when reading XML.
- private final ArrayMap<String, ComponentName> mComponentNames = new ArrayMap<>();
+ // A string cache. This is important as when we're parsing XML files, we don't want to
+ // keep hundreds of strings that have the same contents. We will read the string
+ // and only keep it if it's not in the cache. The GC will take care of the
+ // strings that had identical copies in the cache.
+ private final ArraySet<String> mStringCache = new ArraySet<>();
UsageStats getOrCreateUsageStats(String packageName) {
UsageStats usageStats = stats.get(packageName);
@@ -63,19 +64,21 @@ class IntervalStats {
endTime = timeStamp;
}
- /**
- * Return a ComponentName for the given string representation. This will use a cached
- * copy of the ComponentName if possible, otherwise it will parse and add it to the
- * internal cache.
- */
- ComponentName getCachedComponentName(String str) {
- ComponentName name = mComponentNames.get(str);
- if (name == null) {
- name = ComponentName.unflattenFromString(str);
- if (name != null) {
- mComponentNames.put(str, name);
- }
+ private String getCachedStringRef(String str) {
+ final int index = mStringCache.indexOf(str);
+ if (index < 0) {
+ mStringCache.add(str);
+ return str;
+ }
+ return mStringCache.valueAt(index);
+ }
+
+ UsageEvents.Event buildEvent(String packageName, String className) {
+ UsageEvents.Event event = new UsageEvents.Event();
+ event.mPackage = getCachedStringRef(packageName);
+ if (className != null) {
+ event.mClass = getCachedStringRef(className);
}
- return name;
+ return event;
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 82e837d..0e8b427 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -354,7 +354,8 @@ public class UsageStatsService extends SystemService implements
}
UsageEvents.Event event = new UsageEvents.Event();
- event.mComponent = component;
+ event.mPackage = component.getPackageName();
+ event.mClass = component.getClassName();
event.mTimeStamp = timeStamp;
event.mEventType = eventType;
mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index 916601b..374429a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -37,6 +37,8 @@ final class UsageStatsXmlV1 {
private static final String END_TIME_ATTR = "endTime";
private static final String PACKAGE_TAG = "package";
private static final String NAME_ATTR = "name";
+ private static final String PACKAGE_ATTR = "package";
+ private static final String CLASS_ATTR = "class";
private static final String TOTAL_TIME_ACTIVE_ATTR = "totalTimeActive";
private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive";
private static final String LAST_EVENT_ATTR = "lastEvent";
@@ -80,18 +82,27 @@ final class UsageStatsXmlV1 {
return null;
}
- final String componentName = XmlUtils.readStringAttribute(parser, NAME_ATTR);
- if (componentName == null) {
- throw new ProtocolException("no " + NAME_ATTR + " attribute present");
- }
+ String packageName = XmlUtils.readStringAttribute(parser, PACKAGE_ATTR);
+ String className;
+ if (packageName == null) {
+ // Try getting the component name if it exists.
+ final String componentName = XmlUtils.readStringAttribute(parser, NAME_ATTR);
+ if (componentName == null) {
+ throw new ProtocolException("no " + NAME_ATTR + " or " + PACKAGE_ATTR +
+ " attribute present");
+ }
+ ComponentName component = ComponentName.unflattenFromString(componentName);
+ if (component == null) {
+ throw new ProtocolException("ComponentName " + componentName + " is invalid");
+ }
- ComponentName component = statsOut.getCachedComponentName(componentName);
- if (component == null) {
- throw new ProtocolException("ComponentName " + componentName + " is invalid");
+ packageName = component.getPackageName();
+ className = component.getClassName();
+ } else {
+ className = XmlUtils.readStringAttribute(parser, CLASS_ATTR);
}
- UsageEvents.Event event = new UsageEvents.Event();
- event.mComponent = component;
+ UsageEvents.Event event = statsOut.buildEvent(packageName, className);
event.mEventType = XmlUtils.readIntAttribute(parser, TYPE_ATTR);
event.mTimeStamp = XmlUtils.readLongAttribute(parser, TIME_ATTR);
XmlUtils.skipCurrentTag(parser);
@@ -112,7 +123,10 @@ final class UsageStatsXmlV1 {
private static void writeEvent(FastXmlSerializer serializer, UsageEvents.Event event)
throws IOException {
serializer.startTag(null, EVENT_LOG_TAG);
- serializer.attribute(null, NAME_ATTR, event.getComponent().flattenToString());
+ serializer.attribute(null, PACKAGE_ATTR, event.mPackage);
+ if (event.mClass != null) {
+ serializer.attribute(null, CLASS_ATTR, event.mClass);
+ }
serializer.attribute(null, TYPE_ATTR, Integer.toString(event.getEventType()));
serializer.attribute(null, TIME_ATTR, Long.toString(event.getTimeStamp()));
serializer.endTag(null, EVENT_LOG_TAG);
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index e489fb3..6951590 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -20,7 +20,6 @@ import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
-import android.content.ComponentName;
import android.util.ArraySet;
import android.util.Slog;
@@ -114,7 +113,7 @@ class UserUsageStatsService {
void reportEvent(UsageEvents.Event event) {
if (DEBUG) {
- Slog.d(TAG, mLogPrefix + "Got usage event for " + event.getComponent().getPackageName()
+ Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
+ "[" + event.getTimeStamp() + "]: "
+ eventToString(event.getEventType()));
}
@@ -130,7 +129,7 @@ class UserUsageStatsService {
mCurrentStats[UsageStatsManager.INTERVAL_DAILY].events.put(event.getTimeStamp(), event);
for (IntervalStats stats : mCurrentStats) {
- stats.update(event.getComponent().getPackageName(), event.getTimeStamp(),
+ stats.update(event.mPackage, event.getTimeStamp(),
event.getEventType());
}
@@ -203,17 +202,21 @@ class UserUsageStatsService {
return null;
}
- ArraySet<ComponentName> names = new ArraySet<>();
+ ArraySet<String> names = new ArraySet<>();
ArrayList<UsageEvents.Event> results = new ArrayList<>();
final int size = events.size();
for (int i = startIndex; i < size; i++) {
if (events.keyAt(i) >= endTime) {
break;
}
- names.add(events.valueAt(i).getComponent());
- results.add(events.valueAt(i));
+ final UsageEvents.Event event = events.valueAt(i);
+ names.add(event.mPackage);
+ if (event.mClass != null) {
+ names.add(event.mClass);
+ }
+ results.add(event);
}
- ComponentName[] table = names.toArray(new ComponentName[names.size()]);
+ String[] table = names.toArray(new String[names.size()]);
Arrays.sort(table);
return new UsageEvents(results, table);
}
diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
index 5d8fc9e..5f62ad8 100644
--- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
+++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
@@ -108,7 +108,7 @@ public class UsageLogActivity extends ListActivity implements Runnable {
holder = (ViewHolder) convertView.getTag();
}
- holder.packageName.setText(mEvents.get(position).getComponent().toShortString());
+ holder.packageName.setText(mEvents.get(position).getPackageName());
String state;
switch (mEvents.get(position).getEventType()) {
case UsageEvents.Event.MOVE_TO_FOREGROUND: