Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -7445,6 +7445,7 @@ package android.app.usage { method public java.util.Map<java.lang.String, android.app.usage.UsageStats> queryAndAggregateUsageStats(long, long); method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long); method public android.app.usage.UsageEvents queryEvents(long, long); method public android.app.usage.UsageEvents queryEventsForSelf(long, long); method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long); field public static final int INTERVAL_BEST = 4; // 0x4 field public static final int INTERVAL_DAILY = 0; // 0x0 core/java/android/app/usage/IUsageStatsManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ interface IUsageStatsManager { ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime, String callingPackage); UsageEvents queryEvents(long beginTime, long endTime, String callingPackage); UsageEvents queryEventsForPackage(long beginTime, long endTime, String callingPackage); void setAppInactive(String packageName, boolean inactive, int userId); boolean isAppInactive(String packageName, int userId); void whitelistAppTemporarily(String packageName, long duration, int userId); Loading core/java/android/app/usage/UsageStatsManager.java +34 −4 Original line number Diff line number Diff line Loading @@ -52,10 +52,13 @@ import java.util.Map; * </pre> * A request for data in the middle of a time interval will include that interval. * <p/> * <b>NOTE:</b> This API requires the permission android.permission.PACKAGE_USAGE_STATS. * However, declaring the permission implies intention to use the API and the user of the device * still needs to grant permission through the Settings application. * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS} * <b>NOTE:</b> Most methods on this API require the permission * android.permission.PACKAGE_USAGE_STATS. However, declaring the permission implies intention to * use the API and the user of the device still needs to grant permission through the Settings * application. * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS}. * Methods which only return the information for the calling package do not require this permission. * E.g. {@link #getAppStandbyBucket()} and {@link #queryEventsForSelf(long, long)}. */ @SystemService(Context.USAGE_STATS_SERVICE) public final class UsageStatsManager { Loading Loading @@ -206,6 +209,8 @@ public final class UsageStatsManager { * 2014 - com.example.charlie * </pre> * * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. * @param endTime The exclusive end of the range of stats to include in the results. Loading Loading @@ -235,6 +240,7 @@ public final class UsageStatsManager { * Gets the hardware configurations the device was in for the given time range, aggregated by * the specified interval. The results are ordered as in * {@link #queryUsageStats(int, long, long)}. * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. Loading @@ -259,6 +265,7 @@ public final class UsageStatsManager { /** * Query for events in the given time range. Events are only kept by the system for a few * days. * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param beginTime The inclusive beginning of the range of events to include in the results. * @param endTime The exclusive end of the range of events to include in the results. Loading @@ -277,10 +284,33 @@ public final class UsageStatsManager { return sEmptyResults; } /** * Like {@link #queryEvents(long, long)}, but only returns events for the calling package. * * @param beginTime The inclusive beginning of the range of events to include in the results. * @param endTime The exclusive end of the range of events to include in the results. * @return A {@link UsageEvents} object. * * @see #queryEvents(long, long) */ public UsageEvents queryEventsForSelf(long beginTime, long endTime) { try { final UsageEvents events = mService.queryEventsForPackage(beginTime, endTime, mContext.getOpPackageName()); if (events != null) { return events; } } catch (RemoteException e) { // fallthrough } return sEmptyResults; } /** * A convenience method that queries for all stats in the given range (using the best interval * for that range), merges the resulting data, and keys it by package name. * See {@link #queryUsageStats(int, long, long)}. * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param beginTime The inclusive beginning of the range of stats to include in the results. * @param endTime The exclusive end of the range of stats to include in the results. Loading services/usage/java/com/android/server/usage/UsageStatsService.java +37 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,23 @@ public class UsageStatsService extends SystemService implements } } /** * Called by the Binder stub. */ UsageEvents queryEventsForPackage(int userId, long beginTime, long endTime, String packageName) { synchronized (mLock) { final long timeNow = checkAndGetTimeLocked(); if (!validRange(timeNow, beginTime, endTime)) { return null; } final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); return service.queryEventsForPackage(beginTime, endTime, packageName); } } private static boolean validRange(long currentTime, long beginTime, long endTime) { return beginTime <= currentTime && beginTime < endTime; } Loading Loading @@ -660,6 +677,26 @@ public class UsageStatsService extends SystemService implements } } @Override public UsageEvents queryEventsForPackage(long beginTime, long endTime, String callingPackage) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); if (mPackageManagerInternal.getPackageUid(callingPackage, PackageManager.MATCH_ANY_USER, callingUserId) != callingUid) { throw new SecurityException("Calling uid " + callingPackage + " cannot query events" + "for package " + callingPackage); } final long token = Binder.clearCallingIdentity(); try { return UsageStatsService.this.queryEventsForPackage(callingUserId, beginTime, endTime, callingPackage); } finally { Binder.restoreCallingIdentity(token); } } @Override public boolean isAppInactive(String packageName, int userId) { try { Loading services/usage/java/com/android/server/usage/UserUsageStatsService.java +41 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,47 @@ class UserUsageStatsService { return new UsageEvents(results, table); } UsageEvents queryEventsForPackage(final long beginTime, final long endTime, final String packageName) { final ArraySet<String> names = new ArraySet<>(); names.add(packageName); final List<UsageEvents.Event> results = queryStats(UsageStatsManager.INTERVAL_DAILY, beginTime, endTime, (stats, mutable, accumulatedResult) -> { if (stats.events == null) { return; } final int startIndex = stats.events.closestIndexOnOrAfter(beginTime); if (startIndex < 0) { return; } final int size = stats.events.size(); for (int i = startIndex; i < size; i++) { if (stats.events.keyAt(i) >= endTime) { return; } final UsageEvents.Event event = stats.events.valueAt(i); if (!packageName.equals(event.mPackage)) { continue; } if (event.mClass != null) { names.add(event.mClass); } accumulatedResult.add(event); } }); if (results == null || results.isEmpty()) { return null; } final String[] table = names.toArray(new String[names.size()]); Arrays.sort(table); return new UsageEvents(results, table); } void persistActiveStats() { if (mStatsChanged) { Slog.i(TAG, mLogPrefix + "Flushing usage stats to disk"); Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -7445,6 +7445,7 @@ package android.app.usage { method public java.util.Map<java.lang.String, android.app.usage.UsageStats> queryAndAggregateUsageStats(long, long); method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long); method public android.app.usage.UsageEvents queryEvents(long, long); method public android.app.usage.UsageEvents queryEventsForSelf(long, long); method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long); field public static final int INTERVAL_BEST = 4; // 0x4 field public static final int INTERVAL_DAILY = 0; // 0x0
core/java/android/app/usage/IUsageStatsManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ interface IUsageStatsManager { ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime, String callingPackage); UsageEvents queryEvents(long beginTime, long endTime, String callingPackage); UsageEvents queryEventsForPackage(long beginTime, long endTime, String callingPackage); void setAppInactive(String packageName, boolean inactive, int userId); boolean isAppInactive(String packageName, int userId); void whitelistAppTemporarily(String packageName, long duration, int userId); Loading
core/java/android/app/usage/UsageStatsManager.java +34 −4 Original line number Diff line number Diff line Loading @@ -52,10 +52,13 @@ import java.util.Map; * </pre> * A request for data in the middle of a time interval will include that interval. * <p/> * <b>NOTE:</b> This API requires the permission android.permission.PACKAGE_USAGE_STATS. * However, declaring the permission implies intention to use the API and the user of the device * still needs to grant permission through the Settings application. * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS} * <b>NOTE:</b> Most methods on this API require the permission * android.permission.PACKAGE_USAGE_STATS. However, declaring the permission implies intention to * use the API and the user of the device still needs to grant permission through the Settings * application. * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS}. * Methods which only return the information for the calling package do not require this permission. * E.g. {@link #getAppStandbyBucket()} and {@link #queryEventsForSelf(long, long)}. */ @SystemService(Context.USAGE_STATS_SERVICE) public final class UsageStatsManager { Loading Loading @@ -206,6 +209,8 @@ public final class UsageStatsManager { * 2014 - com.example.charlie * </pre> * * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. * @param endTime The exclusive end of the range of stats to include in the results. Loading Loading @@ -235,6 +240,7 @@ public final class UsageStatsManager { * Gets the hardware configurations the device was in for the given time range, aggregated by * the specified interval. The results are ordered as in * {@link #queryUsageStats(int, long, long)}. * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. Loading @@ -259,6 +265,7 @@ public final class UsageStatsManager { /** * Query for events in the given time range. Events are only kept by the system for a few * days. * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param beginTime The inclusive beginning of the range of events to include in the results. * @param endTime The exclusive end of the range of events to include in the results. Loading @@ -277,10 +284,33 @@ public final class UsageStatsManager { return sEmptyResults; } /** * Like {@link #queryEvents(long, long)}, but only returns events for the calling package. * * @param beginTime The inclusive beginning of the range of events to include in the results. * @param endTime The exclusive end of the range of events to include in the results. * @return A {@link UsageEvents} object. * * @see #queryEvents(long, long) */ public UsageEvents queryEventsForSelf(long beginTime, long endTime) { try { final UsageEvents events = mService.queryEventsForPackage(beginTime, endTime, mContext.getOpPackageName()); if (events != null) { return events; } } catch (RemoteException e) { // fallthrough } return sEmptyResults; } /** * A convenience method that queries for all stats in the given range (using the best interval * for that range), merges the resulting data, and keys it by package name. * See {@link #queryUsageStats(int, long, long)}. * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param beginTime The inclusive beginning of the range of stats to include in the results. * @param endTime The exclusive end of the range of stats to include in the results. Loading
services/usage/java/com/android/server/usage/UsageStatsService.java +37 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,23 @@ public class UsageStatsService extends SystemService implements } } /** * Called by the Binder stub. */ UsageEvents queryEventsForPackage(int userId, long beginTime, long endTime, String packageName) { synchronized (mLock) { final long timeNow = checkAndGetTimeLocked(); if (!validRange(timeNow, beginTime, endTime)) { return null; } final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); return service.queryEventsForPackage(beginTime, endTime, packageName); } } private static boolean validRange(long currentTime, long beginTime, long endTime) { return beginTime <= currentTime && beginTime < endTime; } Loading Loading @@ -660,6 +677,26 @@ public class UsageStatsService extends SystemService implements } } @Override public UsageEvents queryEventsForPackage(long beginTime, long endTime, String callingPackage) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); if (mPackageManagerInternal.getPackageUid(callingPackage, PackageManager.MATCH_ANY_USER, callingUserId) != callingUid) { throw new SecurityException("Calling uid " + callingPackage + " cannot query events" + "for package " + callingPackage); } final long token = Binder.clearCallingIdentity(); try { return UsageStatsService.this.queryEventsForPackage(callingUserId, beginTime, endTime, callingPackage); } finally { Binder.restoreCallingIdentity(token); } } @Override public boolean isAppInactive(String packageName, int userId) { try { Loading
services/usage/java/com/android/server/usage/UserUsageStatsService.java +41 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,47 @@ class UserUsageStatsService { return new UsageEvents(results, table); } UsageEvents queryEventsForPackage(final long beginTime, final long endTime, final String packageName) { final ArraySet<String> names = new ArraySet<>(); names.add(packageName); final List<UsageEvents.Event> results = queryStats(UsageStatsManager.INTERVAL_DAILY, beginTime, endTime, (stats, mutable, accumulatedResult) -> { if (stats.events == null) { return; } final int startIndex = stats.events.closestIndexOnOrAfter(beginTime); if (startIndex < 0) { return; } final int size = stats.events.size(); for (int i = startIndex; i < size; i++) { if (stats.events.keyAt(i) >= endTime) { return; } final UsageEvents.Event event = stats.events.valueAt(i); if (!packageName.equals(event.mPackage)) { continue; } if (event.mClass != null) { names.add(event.mClass); } accumulatedResult.add(event); } }); if (results == null || results.isEmpty()) { return null; } final String[] table = names.toArray(new String[names.size()]); Arrays.sort(table); return new UsageEvents(results, table); } void persistActiveStats() { if (mStatsChanged) { Slog.i(TAG, mLogPrefix + "Flushing usage stats to disk"); Loading