Merge "ShortcutManager: Implement usage report API" into nyc-mr1-dev
This commit is contained in:
@@ -6494,11 +6494,13 @@ package android.app.usage {
|
|||||||
method public android.content.res.Configuration getConfiguration();
|
method public android.content.res.Configuration getConfiguration();
|
||||||
method public int getEventType();
|
method public int getEventType();
|
||||||
method public java.lang.String getPackageName();
|
method public java.lang.String getPackageName();
|
||||||
|
method public java.lang.String getShortcutId();
|
||||||
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 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
|
||||||
|
field public static final int SHORTCUT_INVOCATION = 8; // 0x8
|
||||||
field public static final int USER_INTERACTION = 7; // 0x7
|
field public static final int USER_INTERACTION = 7; // 0x7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6775,11 +6775,13 @@ package android.app.usage {
|
|||||||
method public android.content.res.Configuration getConfiguration();
|
method public android.content.res.Configuration getConfiguration();
|
||||||
method public int getEventType();
|
method public int getEventType();
|
||||||
method public java.lang.String getPackageName();
|
method public java.lang.String getPackageName();
|
||||||
|
method public java.lang.String getShortcutId();
|
||||||
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 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
|
||||||
|
field public static final int SHORTCUT_INVOCATION = 8; // 0x8
|
||||||
field public static final int USER_INTERACTION = 7; // 0x7
|
field public static final int USER_INTERACTION = 7; // 0x7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6500,11 +6500,13 @@ package android.app.usage {
|
|||||||
method public android.content.res.Configuration getConfiguration();
|
method public android.content.res.Configuration getConfiguration();
|
||||||
method public int getEventType();
|
method public int getEventType();
|
||||||
method public java.lang.String getPackageName();
|
method public java.lang.String getPackageName();
|
||||||
|
method public java.lang.String getShortcutId();
|
||||||
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 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
|
||||||
|
field public static final int SHORTCUT_INVOCATION = 8; // 0x8
|
||||||
field public static final int USER_INTERACTION = 7; // 0x7
|
field public static final int USER_INTERACTION = 7; // 0x7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ public final class UsageEvents implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final int USER_INTERACTION = 7;
|
public static final int USER_INTERACTION = 7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event type denoting that an action equivalent to a ShortcutInfo is taken by the user.
|
||||||
|
*
|
||||||
|
* @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
|
||||||
|
*/
|
||||||
|
public static final int SHORTCUT_INVOCATION = 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
@@ -104,6 +111,13 @@ public final class UsageEvents implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public Configuration mConfiguration;
|
public Configuration mConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of the shortcut.
|
||||||
|
* Only present for {@link #SHORTCUT_INVOCATION} event types.
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public String mShortcutId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The package name of the source of this event.
|
* The package name of the source of this event.
|
||||||
*/
|
*/
|
||||||
@@ -145,6 +159,16 @@ public final class UsageEvents implements Parcelable {
|
|||||||
public Configuration getConfiguration() {
|
public Configuration getConfiguration() {
|
||||||
return mConfiguration;
|
return mConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID of a {@link android.content.pm.ShortcutInfo} for this event
|
||||||
|
* if the event is of type {@link #SHORTCUT_INVOCATION}, otherwise it returns null.
|
||||||
|
*
|
||||||
|
* @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
|
||||||
|
*/
|
||||||
|
public String getShortcutId() {
|
||||||
|
return mShortcutId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only used when creating the resulting events. Not used for reading/unparceling.
|
// Only used when creating the resulting events. Not used for reading/unparceling.
|
||||||
@@ -276,8 +300,13 @@ public final class UsageEvents implements Parcelable {
|
|||||||
p.writeInt(event.mEventType);
|
p.writeInt(event.mEventType);
|
||||||
p.writeLong(event.mTimeStamp);
|
p.writeLong(event.mTimeStamp);
|
||||||
|
|
||||||
if (event.mEventType == Event.CONFIGURATION_CHANGE) {
|
switch (event.mEventType) {
|
||||||
event.mConfiguration.writeToParcel(p, flags);
|
case Event.CONFIGURATION_CHANGE:
|
||||||
|
event.mConfiguration.writeToParcel(p, flags);
|
||||||
|
break;
|
||||||
|
case Event.SHORTCUT_INVOCATION:
|
||||||
|
p.writeString(event.mShortcutId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,11 +330,18 @@ public final class UsageEvents implements Parcelable {
|
|||||||
eventOut.mEventType = p.readInt();
|
eventOut.mEventType = p.readInt();
|
||||||
eventOut.mTimeStamp = p.readLong();
|
eventOut.mTimeStamp = p.readLong();
|
||||||
|
|
||||||
// Extract the configuration for configuration change events.
|
// Fill out the event-dependant fields.
|
||||||
if (eventOut.mEventType == Event.CONFIGURATION_CHANGE) {
|
eventOut.mConfiguration = null;
|
||||||
eventOut.mConfiguration = Configuration.CREATOR.createFromParcel(p);
|
eventOut.mShortcutId = null;
|
||||||
} else {
|
|
||||||
eventOut.mConfiguration = null;
|
switch (eventOut.mEventType) {
|
||||||
|
case Event.CONFIGURATION_CHANGE:
|
||||||
|
// Extract the configuration for configuration change events.
|
||||||
|
eventOut.mConfiguration = Configuration.CREATOR.createFromParcel(p);
|
||||||
|
break;
|
||||||
|
case Event.SHORTCUT_INVOCATION:
|
||||||
|
eventOut.mShortcutId = p.readString();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,17 @@ public abstract class UsageStatsManagerInternal {
|
|||||||
*/
|
*/
|
||||||
public abstract void reportConfigurationChange(Configuration config, int userId);
|
public abstract void reportConfigurationChange(Configuration config, int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports that an action equivalent to a ShortcutInfo is taken by the user.
|
||||||
|
*
|
||||||
|
* @param packageName The package name of the shortcut publisher
|
||||||
|
* @param shortcutId The ID of the shortcut in question
|
||||||
|
* @param userId The user in which the content provider was accessed.
|
||||||
|
*
|
||||||
|
* @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
|
||||||
|
*/
|
||||||
|
public abstract void reportShortcutUsage(String packageName, String shortcutId, int userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports that a content provider has been accessed by a foreground app.
|
* Reports that a content provider has been accessed by a foreground app.
|
||||||
* @param name The authority of the content provider
|
* @param name The authority of the content provider
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package android.content.pm;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.TestApi;
|
import android.annotation.TestApi;
|
||||||
|
import android.app.usage.UsageStatsManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
@@ -357,6 +358,18 @@ public class ShortcutManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applications that publish shortcuts should call this method whenever an action that's
|
||||||
|
* equivalent to an existing shortcut has been taken by the user. This includes not only when
|
||||||
|
* the user manually taps a shortcut, but when the user takes an equivalent action within the
|
||||||
|
* application -- for example, when a music player application has a shortcut to playlist X,
|
||||||
|
* then the application should not only report it when the playlist is opened from the
|
||||||
|
* shortcut, but also when the user plays the playlist within the application.
|
||||||
|
*
|
||||||
|
* <p>The information is accessible via {@link UsageStatsManager#queryEvents}
|
||||||
|
* Typically, launcher applications use this information to build a prediction model
|
||||||
|
* so that they can promote the shortcuts that are likely to be used at the moment.
|
||||||
|
*/
|
||||||
public void reportShortcutUsed(String shortcutId) {
|
public void reportShortcutUsed(String shortcutId) {
|
||||||
try {
|
try {
|
||||||
mService.reportShortcutUsed(mContext.getPackageName(), shortcutId,
|
mService.reportShortcutUsed(mContext.getPackageName(), shortcutId,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.app.ActivityManager;
|
|||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
import android.app.AppGlobals;
|
import android.app.AppGlobals;
|
||||||
import android.app.IUidObserver;
|
import android.app.IUidObserver;
|
||||||
|
import android.app.usage.UsageStatsManagerInternal;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -67,6 +68,7 @@ import android.text.format.Time;
|
|||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.KeyValueListParser;
|
import android.util.KeyValueListParser;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
@@ -277,6 +279,7 @@ public class ShortcutService extends IShortcutService.Stub {
|
|||||||
private final IPackageManager mIPackageManager;
|
private final IPackageManager mIPackageManager;
|
||||||
private final PackageManagerInternal mPackageManagerInternal;
|
private final PackageManagerInternal mPackageManagerInternal;
|
||||||
private final UserManager mUserManager;
|
private final UserManager mUserManager;
|
||||||
|
private final UsageStatsManagerInternal mUsageStatsManagerInternal;
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
final SparseIntArray mUidState = new SparseIntArray();
|
final SparseIntArray mUidState = new SparseIntArray();
|
||||||
@@ -353,8 +356,11 @@ public class ShortcutService extends IShortcutService.Stub {
|
|||||||
LocalServices.addService(ShortcutServiceInternal.class, new LocalService());
|
LocalServices.addService(ShortcutServiceInternal.class, new LocalService());
|
||||||
mHandler = new Handler(looper);
|
mHandler = new Handler(looper);
|
||||||
mIPackageManager = AppGlobals.getPackageManager();
|
mIPackageManager = AppGlobals.getPackageManager();
|
||||||
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
|
mPackageManagerInternal = Preconditions.checkNotNull(
|
||||||
mUserManager = context.getSystemService(UserManager.class);
|
LocalServices.getService(PackageManagerInternal.class));
|
||||||
|
mUserManager = Preconditions.checkNotNull(context.getSystemService(UserManager.class));
|
||||||
|
mUsageStatsManagerInternal = Preconditions.checkNotNull(
|
||||||
|
LocalServices.getService(UsageStatsManagerInternal.class));
|
||||||
|
|
||||||
mPackageMonitor.register(context, looper, UserHandle.ALL, /* externalStorage= */ false);
|
mPackageMonitor.register(context, looper, UserHandle.ALL, /* externalStorage= */ false);
|
||||||
|
|
||||||
@@ -1740,7 +1746,28 @@ public class ShortcutService extends IShortcutService.Stub {
|
|||||||
public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
|
public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
|
||||||
verifyCaller(packageName, userId);
|
verifyCaller(packageName, userId);
|
||||||
|
|
||||||
// TODO Implement it.
|
Preconditions.checkNotNull(shortcutId);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, String.format("reportShortcutUsed: Shortcut %s package %s used on user %d",
|
||||||
|
shortcutId, packageName, userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
|
||||||
|
if (ps.findShortcutById(shortcutId) == null) {
|
||||||
|
Log.w(TAG, String.format("reportShortcutUsed: package %s doesn't have shortcut %s",
|
||||||
|
packageName, shortcutId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final long token = injectClearCallingIdentity();
|
||||||
|
try {
|
||||||
|
mUsageStatsManagerInternal.reportShortcutUsage(packageName, shortcutId, userId);
|
||||||
|
} finally {
|
||||||
|
injectRestoreCallingIdentity(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import android.annotation.RequiresPermission;
|
|||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.IUidObserver;
|
import android.app.IUidObserver;
|
||||||
|
import android.app.usage.UsageStatsManagerInternal;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -450,6 +451,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
|||||||
protected PackageManager mMockPackageManager;
|
protected PackageManager mMockPackageManager;
|
||||||
protected PackageManagerInternal mMockPackageManagerInternal;
|
protected PackageManagerInternal mMockPackageManagerInternal;
|
||||||
protected UserManager mMockUserManager;
|
protected UserManager mMockUserManager;
|
||||||
|
protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
|
||||||
|
|
||||||
protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
|
protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
|
||||||
protected static final int CALLING_UID_1 = 10001;
|
protected static final int CALLING_UID_1 = 10001;
|
||||||
@@ -538,6 +540,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
|||||||
mMockPackageManager = mock(PackageManager.class);
|
mMockPackageManager = mock(PackageManager.class);
|
||||||
mMockPackageManagerInternal = mock(PackageManagerInternal.class);
|
mMockPackageManagerInternal = mock(PackageManagerInternal.class);
|
||||||
mMockUserManager = mock(UserManager.class);
|
mMockUserManager = mock(UserManager.class);
|
||||||
|
mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
|
||||||
|
|
||||||
|
LocalServices.removeServiceForTest(PackageManagerInternal.class);
|
||||||
|
LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
|
||||||
|
LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
|
||||||
|
LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal);
|
||||||
|
|
||||||
// Prepare injection values.
|
// Prepare injection values.
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils
|
|||||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled;
|
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled;
|
||||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
|
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.Manifest.permission;
|
import android.Manifest.permission;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -1418,4 +1425,46 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
|
|||||||
assertEquals(3, mManager.getRemainingCallCount());
|
assertEquals(3, mManager.getRemainingCallCount());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testReportShortcutUsed() {
|
||||||
|
runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
|
||||||
|
reset(mMockUsageStatsManagerInternal);
|
||||||
|
|
||||||
|
// Report with an nonexistent shortcut.
|
||||||
|
mManager.reportShortcutUsed("s1");
|
||||||
|
verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
|
||||||
|
anyString(), anyString(), anyInt());
|
||||||
|
|
||||||
|
// Publish s2, but s1 still doesn't exist.
|
||||||
|
mManager.setDynamicShortcuts(list(makeShortcut("s2")));
|
||||||
|
mManager.reportShortcutUsed("s1");
|
||||||
|
verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
|
||||||
|
anyString(), anyString(), anyInt());
|
||||||
|
|
||||||
|
mManager.reportShortcutUsed("s2");
|
||||||
|
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
|
||||||
|
eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_10));
|
||||||
|
|
||||||
|
});
|
||||||
|
runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
|
||||||
|
// Try with a different package.
|
||||||
|
reset(mMockUsageStatsManagerInternal);
|
||||||
|
|
||||||
|
// Report with an nonexistent shortcut.
|
||||||
|
mManager.reportShortcutUsed("s2");
|
||||||
|
verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
|
||||||
|
anyString(), anyString(), anyInt());
|
||||||
|
|
||||||
|
// Publish s2, but s1 still doesn't exist.
|
||||||
|
mManager.setDynamicShortcuts(list(makeShortcut("s3")));
|
||||||
|
mManager.reportShortcutUsed("s2");
|
||||||
|
verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
|
||||||
|
anyString(), anyString(), anyInt());
|
||||||
|
|
||||||
|
mManager.reportShortcutUsed("s3");
|
||||||
|
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
|
||||||
|
eq(CALLING_PACKAGE_2), eq("s3"), eq(USER_10));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1411,6 +1411,24 @@ public class UsageStatsService extends SystemService implements
|
|||||||
mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
|
mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportShortcutUsage(String packageName, String shortcutId, int userId) {
|
||||||
|
if (packageName == null || shortcutId == null) {
|
||||||
|
Slog.w(TAG, "Event reported without a package name or a shortcut ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsageEvents.Event event = new UsageEvents.Event();
|
||||||
|
event.mPackage = packageName.intern();
|
||||||
|
event.mShortcutId = shortcutId.intern();
|
||||||
|
|
||||||
|
// This will later be converted to system time.
|
||||||
|
event.mTimeStamp = SystemClock.elapsedRealtime();
|
||||||
|
|
||||||
|
event.mEventType = Event.SHORTCUT_INVOCATION;
|
||||||
|
mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportContentProviderUsage(String name, String packageName, int userId) {
|
public void reportContentProviderUsage(String name, String packageName, int userId) {
|
||||||
SomeArgs args = SomeArgs.obtain();
|
SomeArgs args = SomeArgs.obtain();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ final class UsageStatsXmlV1 {
|
|||||||
private static final String ACTIVE_ATTR = "active";
|
private static final String ACTIVE_ATTR = "active";
|
||||||
private static final String LAST_EVENT_ATTR = "lastEvent";
|
private static final String LAST_EVENT_ATTR = "lastEvent";
|
||||||
private static final String TYPE_ATTR = "type";
|
private static final String TYPE_ATTR = "type";
|
||||||
|
private static final String SHORTCUT_ID_ATTR = "shortcutId";
|
||||||
|
|
||||||
// Time attributes stored as an offset of the beginTime.
|
// Time attributes stored as an offset of the beginTime.
|
||||||
private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive";
|
private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive";
|
||||||
@@ -106,9 +107,15 @@ final class UsageStatsXmlV1 {
|
|||||||
event.mTimeStamp = statsOut.beginTime + XmlUtils.readLongAttribute(parser, TIME_ATTR);
|
event.mTimeStamp = statsOut.beginTime + XmlUtils.readLongAttribute(parser, TIME_ATTR);
|
||||||
|
|
||||||
event.mEventType = XmlUtils.readIntAttribute(parser, TYPE_ATTR);
|
event.mEventType = XmlUtils.readIntAttribute(parser, TYPE_ATTR);
|
||||||
if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE) {
|
switch (event.mEventType) {
|
||||||
event.mConfiguration = new Configuration();
|
case UsageEvents.Event.CONFIGURATION_CHANGE:
|
||||||
Configuration.readXmlAttrs(parser, event.mConfiguration);
|
event.mConfiguration = new Configuration();
|
||||||
|
Configuration.readXmlAttrs(parser, event.mConfiguration);
|
||||||
|
break;
|
||||||
|
case UsageEvents.Event.SHORTCUT_INVOCATION:
|
||||||
|
final String id = XmlUtils.readStringAttribute(parser, SHORTCUT_ID_ATTR);
|
||||||
|
event.mShortcutId = (id != null) ? id.intern() : null;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statsOut.events == null) {
|
if (statsOut.events == null) {
|
||||||
@@ -165,9 +172,17 @@ final class UsageStatsXmlV1 {
|
|||||||
}
|
}
|
||||||
XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType);
|
XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType);
|
||||||
|
|
||||||
if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE
|
switch (event.mEventType) {
|
||||||
&& event.mConfiguration != null) {
|
case UsageEvents.Event.CONFIGURATION_CHANGE:
|
||||||
Configuration.writeXmlAttrs(xml, event.mConfiguration);
|
if (event.mConfiguration != null) {
|
||||||
|
Configuration.writeXmlAttrs(xml, event.mConfiguration);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UsageEvents.Event.SHORTCUT_INVOCATION:
|
||||||
|
if (event.mShortcutId != null) {
|
||||||
|
XmlUtils.writeStringAttribute(xml, SHORTCUT_ID_ATTR, event.mShortcutId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml.endTag(null, EVENT_TAG);
|
xml.endTag(null, EVENT_TAG);
|
||||||
|
|||||||
@@ -549,6 +549,9 @@ class UserUsageStatsService {
|
|||||||
if (event.mConfiguration != null) {
|
if (event.mConfiguration != null) {
|
||||||
pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
|
pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
|
||||||
}
|
}
|
||||||
|
if (event.mShortcutId != null) {
|
||||||
|
pw.printPair("shortcutId", event.mShortcutId);
|
||||||
|
}
|
||||||
pw.println();
|
pw.println();
|
||||||
}
|
}
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
@@ -588,6 +591,8 @@ class UserUsageStatsService {
|
|||||||
return "SYSTEM_INTERACTION";
|
return "SYSTEM_INTERACTION";
|
||||||
case UsageEvents.Event.USER_INTERACTION:
|
case UsageEvents.Event.USER_INTERACTION:
|
||||||
return "USER_INTERACTION";
|
return "USER_INTERACTION";
|
||||||
|
case UsageEvents.Event.SHORTCUT_INVOCATION:
|
||||||
|
return "SHORTCUT_INVOCATION";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user