diff options
| author | 2022-03-15 15:35:17 -0700 | |
|---|---|---|
| committer | 2022-03-23 18:46:50 +0000 | |
| commit | 9ef2c906e80f42e1e63b3f2003fd649eb4969d6a (patch) | |
| tree | 91280e9b8d3bb54e126108792436deec51a8a0dd | |
| parent | 352d8d7abee0f1ee215ea7be3580752e6eda77ff (diff) | |
Add "clear-last-used-timestamps" command to usagestats service.
Bug: 206518483
Test: atest tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
Change-Id: Ieeedb17182ea93e162e2d7fb2d53169f2cc70e3a
5 files changed, 113 insertions, 0 deletions
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java index f822a188c99c..56811076e013 100644 --- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java @@ -245,4 +245,7 @@ public interface AppStandbyInternal { */ @Nullable String getAppStandbyConstant(@NonNull String key); + + /** Clears the last used timestamps data for the given {@code packageName}. */ + void clearLastUsedTimestampsForTest(@NonNull String packageName, @UserIdInt int userId); } diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java index 2e3b377d08a5..7db358c816c5 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java @@ -686,6 +686,17 @@ public class AppIdleHistory { Integer.toString(userId)), APP_IDLE_FILENAME); } + void clearLastUsedTimestamps(String packageName, int userId) { + ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); + AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName, + SystemClock.elapsedRealtime(), false /* create */); + if (appUsageHistory != null) { + appUsageHistory.lastUsedByUserElapsedTime = Integer.MIN_VALUE; + appUsageHistory.lastUsedElapsedTime = Integer.MIN_VALUE; + appUsageHistory.lastUsedScreenTime = Integer.MIN_VALUE; + } + } + /** * Check if App Idle File exists on disk * @param userId diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 502913063a00..75c0a933adea 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -1857,6 +1857,13 @@ public class AppStandbyController } @Override + public void clearLastUsedTimestampsForTest(@NonNull String packageName, @UserIdInt int userId) { + synchronized (mAppIdleLock) { + mAppIdleHistory.clearLastUsedTimestamps(packageName, userId); + } + } + + @Override public void flushToDisk() { synchronized (mAppIdleLock) { mAppIdleHistory.writeAppIdleTimes(mInjector.elapsedRealtime()); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 366ab0968bb8..da54c329d5be 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -79,6 +79,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; @@ -1982,6 +1983,10 @@ public class UsageStatsService extends SystemService implements } } + void clearLastUsedTimestamps(@NonNull String packageName, @UserIdInt int userId) { + mAppStandby.clearLastUsedTimestampsForTest(packageName, userId); + } + private final class BinderService extends IUsageStatsManager.Stub { private boolean hasPermission(String callingPackage) { @@ -2816,6 +2821,14 @@ public class UsageStatsService extends SystemService implements } return mAppStandby.getAppStandbyConstant(key); } + + @Override + public int handleShellCommand(@NonNull ParcelFileDescriptor in, + @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, + @NonNull String[] args) { + return new UsageStatsShellCommand(UsageStatsService.this).exec(this, + in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args); + } } void registerAppUsageObserver(int callingUid, int observerId, String[] packages, diff --git a/services/usage/java/com/android/server/usage/UsageStatsShellCommand.java b/services/usage/java/com/android/server/usage/UsageStatsShellCommand.java new file mode 100644 index 000000000000..772b22a2b179 --- /dev/null +++ b/services/usage/java/com/android/server/usage/UsageStatsShellCommand.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.usage; + +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.os.ShellCommand; +import android.os.UserHandle; + +import java.io.PrintWriter; + +class UsageStatsShellCommand extends ShellCommand { + private final UsageStatsService mService; + + UsageStatsShellCommand(UsageStatsService usageStatsService) { + mService = usageStatsService; + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(null); + } + switch (cmd) { + case "clear-last-used-timestamps": + return runClearLastUsedTimestamps(); + default: + return handleDefaultCommands(cmd); + } + } + + @Override + public void onHelp() { + final PrintWriter pw = getOutPrintWriter(); + pw.println("UsageStats service (usagestats) commands:"); + pw.println("help"); + pw.println(" Print this help text."); + pw.println(); + pw.println("clear-last-used-timestamps PACKAGE_NAME [-u | --user USER_ID]"); + pw.println(" Clears any existing usage data for the given package."); + pw.println(); + } + + @SuppressLint("AndroidFrameworkRequiresPermission") + private int runClearLastUsedTimestamps() { + final String packageName = getNextArgRequired(); + + int userId = UserHandle.USER_CURRENT; + String opt; + while ((opt = getNextOption()) != null) { + if ("-u".equals(opt) || "--user".equals(opt)) { + userId = UserHandle.parseUserArg(getNextArgRequired()); + } else { + getErrPrintWriter().println("Error: unknown option: " + opt); + return -1; + } + } + if (userId == UserHandle.USER_CURRENT) { + userId = ActivityManager.getCurrentUser(); + } + + mService.clearLastUsedTimestamps(packageName, userId); + return 0; + } +} |