diff options
author | 2021-11-04 16:02:21 +0000 | |
---|---|---|
committer | 2021-11-04 16:02:21 +0000 | |
commit | 3785977ca6f5e4fd34c1dd26a53841144e063a3e (patch) | |
tree | 3272200690674c8535c97eb6f3e5020af019d940 | |
parent | cc590ac913b5ea11e5338714076fa5f2083cd7ee (diff) |
Revert "Add basic launch time prediction."
This reverts commit cc590ac913b5ea11e5338714076fa5f2083cd7ee.
Reason for revert: breakage of errorprone build
Change-Id: I0a896a2637521b36df2a132b8209f4fab23946ad
13 files changed, 30 insertions, 909 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 0f36d32c459c..968c6e5d9cf6 100644 --- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java @@ -1,6 +1,5 @@ package com.android.server.usage; -import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.usage.AppStandbyInfo; @@ -24,7 +23,7 @@ public interface AppStandbyInternal { try { final Class<?> clazz = Class.forName("com.android.server.usage.AppStandbyController", true, loader); - final Constructor<?> ctor = clazz.getConstructor(Context.class); + final Constructor<?> ctor = clazz.getConstructor(Context.class); return (AppStandbyInternal) ctor.newInstance(context); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { @@ -72,16 +71,6 @@ public interface AppStandbyInternal { long getTimeSinceLastJobRun(String packageName, int userId); - void setEstimatedLaunchTime(String packageName, int userId, - @CurrentTimeMillisLong long launchTimeMs); - - /** - * Returns the saved estimated launch time for the app. Will return {@code Long#MAX_VALUE} if no - * value is saved. - */ - @CurrentTimeMillisLong - long getEstimatedLaunchTime(String packageName, int userId); - /** * Returns the time (in milliseconds) since the app was last interacted with by the user. * This can be larger than the current elapsedRealtime, in case it happened before boot or diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java index d808e80dced2..6232dfb12822 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java @@ -25,12 +25,8 @@ import static com.android.server.job.controllers.Package.packageToString; import android.annotation.CurrentTimeMillisLong; import android.annotation.ElapsedRealtimeLong; import android.annotation.NonNull; -import android.app.usage.UsageStatsManagerInternal; -import android.app.usage.UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener; import android.content.Context; -import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.os.UserHandle; import android.provider.DeviceConfig; import android.util.ArraySet; @@ -42,9 +38,7 @@ import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.os.SomeArgs; import com.android.server.JobSchedulerBackgroundThread; -import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; import com.android.server.utils.AlarmQueue; @@ -59,10 +53,6 @@ public class PrefetchController extends StateController { || Log.isLoggable(TAG, Log.DEBUG); private final PcConstants mPcConstants; - private final PcHandler mHandler; - - @GuardedBy("mLock") - private final UsageStatsManagerInternal mUsageStatsManagerInternal; @GuardedBy("mLock") private final SparseArrayMap<String, ArraySet<JobStatus>> mTrackedJobs = new SparseArrayMap<>(); @@ -82,34 +72,11 @@ public class PrefetchController extends StateController { @CurrentTimeMillisLong private long mLaunchTimeThresholdMs = PcConstants.DEFAULT_LAUNCH_TIME_THRESHOLD_MS; - @SuppressWarnings("FieldCanBeLocal") - private final EstimatedLaunchTimeChangedListener mEstimatedLaunchTimeChangedListener = - new EstimatedLaunchTimeChangedListener() { - @Override - public void onEstimatedLaunchTimeChanged(int userId, @NonNull String packageName, - @CurrentTimeMillisLong long newEstimatedLaunchTime) { - final SomeArgs args = SomeArgs.obtain(); - args.arg1 = packageName; - args.argi1 = userId; - args.argl1 = newEstimatedLaunchTime; - mHandler.obtainMessage(MSG_PROCESS_UPDATED_ESTIMATED_LAUNCH_TIME, args) - .sendToTarget(); - } - }; - - private static final int MSG_RETRIEVE_ESTIMATED_LAUNCH_TIME = 0; - private static final int MSG_PROCESS_UPDATED_ESTIMATED_LAUNCH_TIME = 1; - public PrefetchController(JobSchedulerService service) { super(service); mPcConstants = new PcConstants(); - mHandler = new PcHandler(mContext.getMainLooper()); mThresholdAlarmListener = new ThresholdAlarmListener( mContext, JobSchedulerBackgroundThread.get().getLooper()); - mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class); - - mUsageStatsManagerInternal - .registerLaunchTimeChangedListener(mEstimatedLaunchTimeChangedListener); } @Override @@ -179,14 +146,11 @@ public class PrefetchController extends StateController { @CurrentTimeMillisLong private long getNextEstimatedLaunchTimeLocked(int userId, @NonNull String pkgName, @CurrentTimeMillisLong long now) { - final Long nextEstimatedLaunchTime = mEstimatedLaunchTimes.get(userId, pkgName); + Long nextEstimatedLaunchTime = mEstimatedLaunchTimes.get(userId, pkgName); if (nextEstimatedLaunchTime == null || nextEstimatedLaunchTime < now) { - // Don't query usage stats here because it may have to read from disk. - mHandler.obtainMessage(MSG_RETRIEVE_ESTIMATED_LAUNCH_TIME, userId, 0, pkgName) - .sendToTarget(); - // Store something in the cache so we don't keep posting retrieval messages. - mEstimatedLaunchTimes.add(userId, pkgName, Long.MAX_VALUE); - return Long.MAX_VALUE; + // TODO(194532703): get estimated time from UsageStats + nextEstimatedLaunchTime = now + 2 * HOUR_IN_MILLIS; + mEstimatedLaunchTimes.add(userId, pkgName, nextEstimatedLaunchTime); } return nextEstimatedLaunchTime; } @@ -206,42 +170,6 @@ public class PrefetchController extends StateController { return changed; } - private void processUpdatedEstimatedLaunchTime(int userId, @NonNull String pkgName, - @CurrentTimeMillisLong long newEstimatedLaunchTime) { - if (DEBUG) { - Slog.d(TAG, "Estimated launch time for " + packageToString(userId, pkgName) - + " changed to " + newEstimatedLaunchTime - + " (" - + TimeUtils.formatDuration(newEstimatedLaunchTime - sSystemClock.millis()) - + " from now)"); - } - - synchronized (mLock) { - final ArraySet<JobStatus> jobs = mTrackedJobs.get(userId, pkgName); - if (jobs == null) { - if (DEBUG) { - Slog.i(TAG, - "Not caching launch time since we haven't seen any prefetch" - + " jobs for " + packageToString(userId, pkgName)); - } - } else { - // Don't bother caching the value unless the app has scheduled prefetch jobs - // before. This is based on the assumption that if an app has scheduled a - // prefetch job before, then it will probably schedule another one again. - mEstimatedLaunchTimes.add(userId, pkgName, newEstimatedLaunchTime); - - if (!jobs.isEmpty()) { - final long now = sSystemClock.millis(); - final long nowElapsed = sElapsedRealtimeClock.millis(); - updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed); - if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) { - mStateChangedListener.onControllerStateChanged(jobs); - } - } - } - } - } - @GuardedBy("mLock") private boolean updateConstraintLocked(@NonNull JobStatus jobStatus, @CurrentTimeMillisLong long now, @ElapsedRealtimeLong long nowElapsed) { @@ -361,49 +289,6 @@ public class PrefetchController extends StateController { } } - private class PcHandler extends Handler { - PcHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_RETRIEVE_ESTIMATED_LAUNCH_TIME: - final int userId = msg.arg1; - final String pkgName = (String) msg.obj; - // It's okay to get the time without holding the lock since all updates to - // the local cache go through the handler (and therefore will be sequential). - final long nextEstimatedLaunchTime = mUsageStatsManagerInternal - .getEstimatedPackageLaunchTime(pkgName, userId); - if (DEBUG) { - Slog.d(TAG, "Retrieved launch time for " - + packageToString(userId, pkgName) - + " of " + nextEstimatedLaunchTime - + " (" + TimeUtils.formatDuration( - nextEstimatedLaunchTime - sSystemClock.millis()) - + " from now)"); - } - synchronized (mLock) { - final Long curEstimatedLaunchTime = - mEstimatedLaunchTimes.get(userId, pkgName); - if (curEstimatedLaunchTime == null - || nextEstimatedLaunchTime != curEstimatedLaunchTime) { - processUpdatedEstimatedLaunchTime( - userId, pkgName, nextEstimatedLaunchTime); - } - } - break; - - case MSG_PROCESS_UPDATED_ESTIMATED_LAUNCH_TIME: - final SomeArgs args = (SomeArgs) msg.obj; - processUpdatedEstimatedLaunchTime(args.argi1, (String) args.arg1, args.argl1); - args.recycle(); - break; - } - } - } - @VisibleForTesting class PcConstants { private boolean mShouldReevaluateConstraints = false; @@ -481,8 +366,7 @@ public class PrefetchController extends StateController { final String pkgName = mEstimatedLaunchTimes.keyAt(u, p); final long estimatedLaunchTime = mEstimatedLaunchTimes.valueAt(u, p); - pw.print(packageToString(userId, pkgName)); - pw.print(": "); + pw.print("<" + userId + ">" + pkgName + ": "); pw.print(estimatedLaunchTime); pw.print(" ("); TimeUtils.formatDuration(estimatedLaunchTime - now, pw, 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 8b175127373a..187422bf1970 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java @@ -32,8 +32,6 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import static com.android.server.usage.AppStandbyController.isUserUsage; -import android.annotation.CurrentTimeMillisLong; -import android.annotation.ElapsedRealtimeLong; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageStatsManager; import android.os.SystemClock; @@ -117,8 +115,6 @@ public class AppIdleHistory { // Reason why the app was last marked for restriction. private static final String ATTR_LAST_RESTRICTION_ATTEMPT_REASON = "lastRestrictionAttemptReason"; - // The next estimated launch time of the app, in ms since epoch. - private static final String ATTR_NEXT_ESTIMATED_APP_LAUNCH_TIME = "nextEstimatedAppLaunchTime"; // device on time = mElapsedDuration + (timeNow - mElapsedSnapshot) private long mElapsedSnapshot; // Elapsed time snapshot when last write of mDeviceOnDuration @@ -155,9 +151,6 @@ public class AppIdleHistory { int lastInformedBucket; // The last time a job was run for this app, using elapsed timebase long lastJobRunTime; - // The estimated time the app will be launched next, in milliseconds since epoch. - @CurrentTimeMillisLong - long nextEstimatedLaunchTime; // When should the bucket active state timeout, in elapsed timebase, if greater than // lastUsedElapsedTime. // This is used to keep the app in a high bucket regardless of other timeouts and @@ -418,17 +411,6 @@ public class AppIdleHistory { } /** - * Marks the next time the app is expected to be launched, in the current millis timebase. - */ - public void setEstimatedLaunchTime(String packageName, int userId, - @ElapsedRealtimeLong long nowElapsed, @CurrentTimeMillisLong long launchTime) { - ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); - AppUsageHistory appUsageHistory = - getPackageHistory(userHistory, packageName, nowElapsed, true); - appUsageHistory.nextEstimatedLaunchTime = launchTime; - } - - /** * Marks the last time a job was run, with the given elapsedRealtime. The time stored is * based on the elapsed timebase. * @param packageName @@ -461,23 +443,6 @@ public class AppIdleHistory { } /** - * Returns the next estimated launch time of this app. Will return {@link Long#MAX_VALUE} if - * there's no estimated time. - */ - @CurrentTimeMillisLong - public long getEstimatedLaunchTime(String packageName, int userId, long nowElapsed) { - ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); - AppUsageHistory appUsageHistory = - getPackageHistory(userHistory, packageName, nowElapsed, false); - // Don't adjust the default, else it'll wrap around to a positive value - if (appUsageHistory == null - || appUsageHistory.nextEstimatedLaunchTime < System.currentTimeMillis()) { - return Long.MAX_VALUE; - } - return appUsageHistory.nextEstimatedLaunchTime; - } - - /** * Returns the time since the last job was run for this app. This can be larger than the * current elapsedRealtime, in case it happened before boot or a really large value if no jobs * were ever run. @@ -706,8 +671,6 @@ public class AppIdleHistory { Slog.wtf(TAG, "Unable to read last restrict reason", nfe); } } - appUsageHistory.nextEstimatedLaunchTime = getLongValue(parser, - ATTR_NEXT_ESTIMATED_APP_LAUNCH_TIME, 0); appUsageHistory.lastInformedBucket = -1; userHistory.put(packageName, appUsageHistory); } @@ -790,10 +753,6 @@ public class AppIdleHistory { } xml.attribute(null, ATTR_LAST_RESTRICTION_ATTEMPT_REASON, Integer.toHexString(history.lastRestrictReason)); - if (history.nextEstimatedLaunchTime > 0) { - xml.attribute(null, ATTR_NEXT_ESTIMATED_APP_LAUNCH_TIME, - Long.toString(history.nextEstimatedLaunchTime)); - } xml.endTag(null, TAG_PACKAGE); } @@ -820,7 +779,6 @@ public class AppIdleHistory { idpw.println(" App Standby States:"); idpw.increaseIndent(); ArrayMap<String, AppUsageHistory> userHistory = mIdleHistory.get(userId); - final long now = System.currentTimeMillis(); final long elapsedRealtime = SystemClock.elapsedRealtime(); final long totalElapsedTime = getElapsedTime(elapsedRealtime); final long screenOnTime = getScreenOnTime(elapsedRealtime); @@ -861,10 +819,6 @@ public class AppIdleHistory { idpw.print(" lastRestrictReason=" + UsageStatsManager.reasonToString(appUsageHistory.lastRestrictReason)); } - if (appUsageHistory.nextEstimatedLaunchTime > 0) { - idpw.print(" nextEstimatedLaunchTime="); - TimeUtils.formatDuration(appUsageHistory.nextEstimatedLaunchTime - now, idpw); - } idpw.print(" idle=" + (isIdle(packageName, userId, elapsedRealtime) ? "y" : "n")); idpw.println(); } 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 abbae4e8e43c..096211b433c7 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -54,7 +54,6 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; -import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -1088,24 +1087,6 @@ public class AppStandbyController } @Override - public void setEstimatedLaunchTime(String packageName, int userId, - @CurrentTimeMillisLong long launchTime) { - final long nowElapsed = mInjector.elapsedRealtime(); - synchronized (mAppIdleLock) { - mAppIdleHistory.setEstimatedLaunchTime(packageName, userId, nowElapsed, launchTime); - } - } - - @Override - @CurrentTimeMillisLong - public long getEstimatedLaunchTime(String packageName, int userId) { - final long elapsedRealtime = mInjector.elapsedRealtime(); - synchronized (mAppIdleLock) { - return mAppIdleHistory.getEstimatedLaunchTime(packageName, userId, elapsedRealtime); - } - } - - @Override public long getTimeSinceLastUsedByUser(String packageName, int userId) { final long elapsedRealtime = mInjector.elapsedRealtime(); synchronized (mAppIdleLock) { diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 0f5cd4e44bed..71fae3debbea 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -15,7 +15,6 @@ */ package android.app.usage; -import android.annotation.CurrentTimeMillisLong; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -585,7 +584,6 @@ public final class UsageEvents implements Parcelable { * <p/> * See {@link System#currentTimeMillis()}. */ - @CurrentTimeMillisLong public long getTimeStamp() { return mTimeStamp; } @@ -803,9 +801,6 @@ public final class UsageEvents implements Parcelable { * @return true if an event was available, false if there are no more events. */ public boolean getNextEvent(Event eventOut) { - if (eventOut == null) { - throw new IllegalArgumentException("Given eventOut must not be null"); - } if (mIndex >= mEventCount) { return false; } diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java index 21fc19ec3079..b2226d1e0fa3 100644 --- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java +++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java @@ -16,7 +16,6 @@ package android.app.usage; -import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -235,10 +234,6 @@ public abstract class UsageStatsManagerInternal { public abstract void setLastJobRunTime(String packageName, @UserIdInt int userId, long elapsedRealtime); - /** Returns the estimated time that the app will be launched, in milliseconds since epoch. */ - @CurrentTimeMillisLong - public abstract long getEstimatedPackageLaunchTime(String packageName, @UserIdInt int userId); - /** * Returns the time in millis since a job was executed for this app, in elapsed realtime * timebase. This value can be larger than the current elapsed realtime if the job was executed @@ -345,21 +340,4 @@ public abstract class UsageStatsManagerInternal { /** Unregister a listener from being notified of every new usage event. */ public abstract void unregisterListener(@NonNull UsageEventListener listener); - - /** - * Listener interface for estimated launch time changes. - */ - public interface EstimatedLaunchTimeChangedListener { - /** Callback to inform listeners when estimated launch times change. */ - void onEstimatedLaunchTimeChanged(@UserIdInt int userId, @NonNull String packageName, - @CurrentTimeMillisLong long newEstimatedLaunchTime); - } - - /** Register a listener that will be notified of every estimated launch time change. */ - public abstract void registerLaunchTimeChangedListener( - @NonNull EstimatedLaunchTimeChangedListener listener); - - /** Unregister a listener from being notified of every estimated launch time change. */ - public abstract void unregisterLaunchTimeChangedListener( - @NonNull EstimatedLaunchTimeChangedListener listener); } diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java index 0893e38c770f..98e089e0ab94 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java @@ -20,33 +20,15 @@ import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; -import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; -import static com.android.server.job.JobSchedulerService.sSystemClock; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import android.app.AlarmManager; -import android.app.job.JobInfo; -import android.app.usage.UsageStatsManagerInternal; -import android.app.usage.UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener; -import android.content.ComponentName; import android.content.Context; -import android.content.pm.ServiceInfo; -import android.os.Looper; import android.os.SystemClock; import android.provider.DeviceConfig; @@ -60,9 +42,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; -import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; @@ -75,26 +55,15 @@ import java.util.concurrent.Executor; @RunWith(AndroidJUnit4.class) public class PrefetchControllerTest { - private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests"; - private static final int SOURCE_USER_ID = 0; - private static final int CALLING_UID = 1000; - private static final long DEFAULT_WAIT_MS = 3000; - private static final String TAG_PREFETCH = "*job.prefetch*"; - private PrefetchController mPrefetchController; private PcConstants mPcConstants; private DeviceConfig.Properties.Builder mDeviceConfigPropertiesBuilder; - private EstimatedLaunchTimeChangedListener mEstimatedLaunchTimeChangedListener; private MockitoSession mMockingSession; @Mock - private AlarmManager mAlarmManager; - @Mock private Context mContext; @Mock private JobSchedulerService mJobSchedulerService; - @Mock - private UsageStatsManagerInternal mUsageStatsManagerInternal; @Before public void setUp() { @@ -108,11 +77,6 @@ public class PrefetchControllerTest { // Called in StateController constructor. when(mJobSchedulerService.getTestableContext()).thenReturn(mContext); when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService); - // Called in PrefetchController constructor. - doReturn(mUsageStatsManagerInternal) - .when(() -> LocalServices.getService(UsageStatsManagerInternal.class)); - when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper()); - when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); // Used in PrefetchController.PcConstants doAnswer((Answer<Void>) invocationOnMock -> null) .when(() -> DeviceConfig.addOnPropertiesChangedListener( @@ -129,7 +93,7 @@ public class PrefetchControllerTest { // Freeze the clocks at 24 hours after this moment in time. Several tests create sessions // in the past, and PrefetchController sometimes floors values at 0, so if the test time // causes sessions with negative timestamps, they will fail. - sSystemClock = + JobSchedulerService.sSystemClock = getShiftedClock(Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC), 24 * HOUR_IN_MILLIS); JobSchedulerService.sUptimeMillisClock = getShiftedClock( @@ -141,14 +105,8 @@ public class PrefetchControllerTest { // Initialize real objects. // Capture the listeners. - ArgumentCaptor<EstimatedLaunchTimeChangedListener> eltListenerCaptor = - ArgumentCaptor.forClass(EstimatedLaunchTimeChangedListener.class); mPrefetchController = new PrefetchController(mJobSchedulerService); mPcConstants = mPrefetchController.getPcConstants(); - - verify(mUsageStatsManagerInternal) - .registerLaunchTimeChangedListener(eltListenerCaptor.capture()); - mEstimatedLaunchTimeChangedListener = eltListenerCaptor.getValue(); } @After @@ -158,29 +116,6 @@ public class PrefetchControllerTest { } } - private JobStatus createJobStatus(String testTag, int jobId) { - JobInfo jobInfo = new JobInfo.Builder(jobId, - new ComponentName(mContext, "TestPrefetchJobService")) - .setPrefetch(true) - .build(); - return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, jobInfo); - } - - private static JobStatus createJobStatus(String testTag, String packageName, int callingUid, - JobInfo jobInfo) { - JobStatus js = JobStatus.createFromJobInfo( - jobInfo, callingUid, packageName, SOURCE_USER_ID, testTag); - js.serviceInfo = mock(ServiceInfo.class); - // Make sure Doze and background-not-restricted don't affect tests. - js.setDeviceNotDozingConstraintSatisfied(/* nowElapsed */ sElapsedRealtimeClock.millis(), - /* state */ true, /* allowlisted */false); - js.setBackgroundNotRestrictedConstraintSatisfied( - sElapsedRealtimeClock.millis(), true, false); - js.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), true); - js.setExpeditedJobTareApproved(sElapsedRealtimeClock.millis(), true); - return js; - } - private Clock getShiftedClock(Clock clock, long incrementMs) { return Clock.offset(clock, Duration.ofMillis(incrementMs)); } @@ -190,15 +125,6 @@ public class PrefetchControllerTest { synchronized (mPrefetchController.mLock) { mPrefetchController.prepareForUpdatedConstantsLocked(); mPcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key); - mPrefetchController.onConstantsUpdatedLocked(); - } - } - - private void trackJobs(JobStatus... jobs) { - for (JobStatus job : jobs) { - synchronized (mPrefetchController.mLock) { - mPrefetchController.maybeStartTrackingJobLocked(job, null); - } } } @@ -221,99 +147,4 @@ public class PrefetchControllerTest { assertEquals(24 * HOUR_IN_MILLIS, mPrefetchController.getLaunchTimeThresholdMs()); } - - @Test - public void testConstantsUpdating_ThresholdChangesAlarms() { - final long launchDelayMs = 11 * HOUR_IN_MILLIS; - setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 7 * HOUR_IN_MILLIS); - when(mUsageStatsManagerInternal - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID)) - .thenReturn(sSystemClock.millis() + launchDelayMs); - JobStatus jobStatus = createJobStatus("testConstantsUpdating_ThresholdChangesAlarms", 1); - trackJobs(jobStatus); - - InOrder inOrder = inOrder(mAlarmManager); - - inOrder.verify(mAlarmManager, timeout(DEFAULT_WAIT_MS).times(1)) - .setWindow( - anyInt(), eq(sElapsedRealtimeClock.millis() + 4 * HOUR_IN_MILLIS), - anyLong(), eq(TAG_PREFETCH), any(), any()); - - setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 3 * HOUR_IN_MILLIS); - inOrder.verify(mAlarmManager, timeout(DEFAULT_WAIT_MS).times(1)) - .setWindow( - anyInt(), eq(sElapsedRealtimeClock.millis() + 8 * HOUR_IN_MILLIS), - anyLong(), eq(TAG_PREFETCH), any(), any()); - } - - @Test - public void testConstraintNotSatisfiedWhenLaunchLate() { - setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 7 * HOUR_IN_MILLIS); - - final JobStatus job = createJobStatus("testConstraintNotSatisfiedWhenLaunchLate", 1); - when(mUsageStatsManagerInternal - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID)) - .thenReturn(sSystemClock.millis() + 10 * HOUR_IN_MILLIS); - trackJobs(job); - verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS)) - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID); - assertFalse(job.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH)); - } - - public void testConstraintSatisfiedWhenLaunchSoon() { - final JobStatus job = createJobStatus("testConstraintSatisfiedWhenLaunchSoon", 2); - when(mUsageStatsManagerInternal - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID)) - .thenReturn(sSystemClock.millis() + MINUTE_IN_MILLIS); - trackJobs(job); - verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS)) - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID); - assertTrue(job.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH)); - } - - @Test - public void testEstimatedLaunchTimeChangedToLate() { - setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 7 * HOUR_IN_MILLIS); - when(mUsageStatsManagerInternal - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID)) - .thenReturn(sSystemClock.millis() + HOUR_IN_MILLIS); - - InOrder inOrder = inOrder(mUsageStatsManagerInternal); - - JobStatus jobStatus = createJobStatus("testEstimatedLaunchTimeChangedToLate", 1); - trackJobs(jobStatus); - inOrder.verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS)) - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID); - assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH)); - - mEstimatedLaunchTimeChangedListener.onEstimatedLaunchTimeChanged(SOURCE_USER_ID, - SOURCE_PACKAGE, sSystemClock.millis() + 10 * HOUR_IN_MILLIS); - - inOrder.verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS).times(0)) - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID); - assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH)); - } - - @Test - public void testEstimatedLaunchTimeChangedToSoon() { - setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 7 * HOUR_IN_MILLIS); - when(mUsageStatsManagerInternal - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID)) - .thenReturn(sSystemClock.millis() + 10 * HOUR_IN_MILLIS); - - InOrder inOrder = inOrder(mUsageStatsManagerInternal); - - JobStatus jobStatus = createJobStatus("testEstimatedLaunchTimeChangedToSoon", 1); - trackJobs(jobStatus); - inOrder.verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS)) - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID); - assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH)); - - mEstimatedLaunchTimeChangedListener.onEstimatedLaunchTimeChanged(SOURCE_USER_ID, - SOURCE_PACKAGE, sSystemClock.millis() + MINUTE_IN_MILLIS); - - inOrder.verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS).times(0)) - .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID); - assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH)); - } } diff --git a/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java index 1542b01be8e1..24c58f49bed6 100644 --- a/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/usage/UserUsageStatsServiceTest.java @@ -18,11 +18,8 @@ package com.android.server.usage; import static android.app.usage.UsageEvents.Event.ACTIVITY_RESUMED; import static android.app.usage.UsageEvents.Event.APP_COMPONENT_USED; -import static android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mockitoSession; @@ -31,7 +28,6 @@ import android.app.usage.UsageEvents.Event; import android.content.Context; import android.os.SystemClock; import android.text.format.DateUtils; -import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -51,8 +47,6 @@ import java.util.HashMap; @RunWith(AndroidJUnit4.class) public class UserUsageStatsServiceTest { - private static final String TAG = UserUsageStatsServiceTest.class.getSimpleName(); - private static final int TEST_USER_ID = 0; private static final String TEST_PACKAGE_NAME = "test.package"; private static final long TIME_INTERVAL_MILLIS = DateUtils.DAY_IN_MILLIS; @@ -60,8 +54,6 @@ public class UserUsageStatsServiceTest { private UserUsageStatsService mService; private MockitoSession mMockitoSession; - private File mDir; - @Mock private Context mContext; @Mock @@ -74,11 +66,8 @@ public class UserUsageStatsServiceTest { .strictness(Strictness.LENIENT) .startMocking(); - // Deleting in tearDown() doesn't always work, so adding a unique suffix to each test - // directory to ensure sequential test runs don't interfere with each other. - mDir = new File(InstrumentationRegistry.getContext().getCacheDir(), - "test_" + System.currentTimeMillis()); - mService = new UserUsageStatsService(mContext, TEST_USER_ID, mDir, mStatsUpdatedListener); + File dir = new File(InstrumentationRegistry.getContext().getCacheDir(), "test"); + mService = new UserUsageStatsService(mContext, TEST_USER_ID, dir, mStatsUpdatedListener); HashMap<String, Long> installedPkgs = new HashMap<>(); installedPkgs.put(TEST_PACKAGE_NAME, System.currentTimeMillis()); @@ -88,9 +77,6 @@ public class UserUsageStatsServiceTest { @After public void tearDown() { - if (mDir != null && mDir.exists() && !mDir.delete()) { - Log.d(TAG, "Failed to delete test directory"); - } if (mMockitoSession != null) { mMockitoSession.finishMocking(); } @@ -102,9 +88,6 @@ public class UserUsageStatsServiceTest { event.mPackage = TEST_PACKAGE_NAME; mService.reportEvent(event); - // Force persist the event instead of waiting for it to be processed on the handler. - mService.persistActiveStats(); - long now = System.currentTimeMillis(); long startTime = now - TIME_INTERVAL_MILLIS; UsageEvents events = mService.queryEventsForPackage( @@ -129,9 +112,6 @@ public class UserUsageStatsServiceTest { event.mPackage = TEST_PACKAGE_NAME; mService.reportEvent(event); - // Force persist the event instead of waiting for it to be processed on the handler. - mService.persistActiveStats(); - long now = System.currentTimeMillis(); long startTime = now - TIME_INTERVAL_MILLIS; UsageEvents events = mService.queryEventsForPackage( @@ -147,36 +127,4 @@ public class UserUsageStatsServiceTest { } assertFalse(hasTestEvent); } - - @Test - public void testQueryEarliestEventsForPackage() { - Event event1 = new Event(NOTIFICATION_SEEN, SystemClock.elapsedRealtime()); - event1.mPackage = TEST_PACKAGE_NAME; - mService.reportEvent(event1); - Event event2 = new Event(ACTIVITY_RESUMED, SystemClock.elapsedRealtime()); - event2.mPackage = TEST_PACKAGE_NAME; - mService.reportEvent(event2); - - // Force persist the events instead of waiting for them to be processed on the handler. - mService.persistActiveStats(); - - long now = System.currentTimeMillis(); - long startTime = now - TIME_INTERVAL_MILLIS; - UsageEvents events = mService.queryEarliestEventsForPackage( - startTime, now, TEST_PACKAGE_NAME, ACTIVITY_RESUMED); - - assertNotNull(events); - boolean hasTestEvent = false; - int count = 0; - while (events.hasNextEvent()) { - count++; - Event outEvent = new Event(); - events.getNextEvent(outEvent); - if (outEvent.mEventType == ACTIVITY_RESUMED) { - hasTestEvent = true; - } - } - assertTrue(hasTestEvent); - assertEquals(2, count); - } } diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java index 75bd2ccbe635..b2dacab26365 100644 --- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java +++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java @@ -67,10 +67,9 @@ public class UsageStatsDatabaseTest { private static final UsageStatsDatabase.StatCombiner<IntervalStats> mIntervalStatsVerifier = new UsageStatsDatabase.StatCombiner<IntervalStats>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<IntervalStats> accResult) { accResult.add(stats); - return true; } }; diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index cc33f88d396d..ad042dddf03d 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -799,10 +799,8 @@ public class UsageStatsDatabase { * @param stats The {@link IntervalStats} object selected. * @param mutable Whether or not the data inside the stats object is mutable. * @param accumulatedResult The list to which to add extracted data. - * @return Whether or not to continue providing new stats to this combiner. If {@code false} - * is returned, then combine will no longer be called. */ - boolean combine(IntervalStats stats, boolean mutable, List<T> accumulatedResult); + void combine(IntervalStats stats, boolean mutable, List<T> accumulatedResult); } /** @@ -865,9 +863,8 @@ public class UsageStatsDatabase { try { readLocked(f, stats); - if (beginTime < stats.endTime - && !combiner.combine(stats, false, results)) { - break; + if (beginTime < stats.endTime) { + combiner.combine(stats, false, results); } } catch (Exception e) { Slog.e(TAG, "Failed to read usage stats file", e); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 6dbf4c56da3b..f0ceff15c763 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -29,10 +29,8 @@ import static android.app.usage.UsageEvents.Event.USER_STOPPED; import static android.app.usage.UsageEvents.Event.USER_UNLOCKED; import static android.app.usage.UsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY; import static android.app.usage.UsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; import android.Manifest; -import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -86,7 +84,6 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; @@ -97,7 +94,6 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; -import com.android.server.utils.AlarmQueue; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -138,15 +134,8 @@ public class UsageStatsService extends SystemService implements private static final long TEN_SECONDS = 10 * 1000; private static final long TWENTY_MINUTES = 20 * 60 * 1000; - private static final long ONE_DAY = 24 * HOUR_IN_MILLIS; - private static final long ONE_WEEK = 7 * ONE_DAY; private static final long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : TWENTY_MINUTES; static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds. - /** - * Used when we can't determine the next app launch time. Assume the app will get launched - * this amount of time in the future. - */ - private static final long UNKNOWN_LAUNCH_TIME_DELAY_MS = 365 * ONE_DAY; private static final boolean ENABLE_KERNEL_UPDATES = true; private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set"); @@ -171,9 +160,6 @@ public class UsageStatsService extends SystemService implements static final int MSG_UNLOCKED_USER = 5; static final int MSG_PACKAGE_REMOVED = 6; static final int MSG_ON_START = 7; - static final int MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK = 8; - static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED = 9; - static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 10; private final Object mLock = new Object(); Handler mHandler; @@ -208,12 +194,8 @@ public class UsageStatsService extends SystemService implements private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>(); final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray(); final SparseArray<ActivityData> mVisibleActivities = new SparseArray(); - @GuardedBy("mLock") - private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>(); private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners = new ArraySet<>(); - private final CopyOnWriteArraySet<UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener> - mEstimatedLaunchTimeChangedListeners = new CopyOnWriteArraySet<>(); private static class ActivityData { private final String mTaskRootPackage; @@ -387,11 +369,6 @@ public class UsageStatsService extends SystemService implements } mUserUnlockedStates.remove(userId); mUserState.put(userId, null); // release the service (mainly for GC) - LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue != null) { - alarmQueue.removeAllAlarms(); - mLaunchTimeAlarmQueues.remove(userId); - } } } @@ -438,8 +415,6 @@ public class UsageStatsService extends SystemService implements } reportEvent(unlockEvent, userId); - mHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); - // Remove all the stats stored in memory and in system DE. mReportedEvents.remove(userId); deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats")); @@ -462,7 +437,6 @@ public class UsageStatsService extends SystemService implements * <br/> * Note: DO NOT call this while holding the usage stats lock ({@code mLock}). */ - @Nullable private HashMap<String, Long> getInstalledPackages(int userId) { if (mPackageManager == null) { return null; @@ -498,33 +472,6 @@ public class UsageStatsService extends SystemService implements } } - private class LaunchTimeAlarmQueue extends AlarmQueue<String> { - private final int mUserId; - - LaunchTimeAlarmQueue(int userId, @NonNull Context context, @NonNull Looper looper) { - super(context, looper, "*usage.launchTime*", "Estimated launch times", true, 30_000L); - mUserId = userId; - } - - @Override - protected boolean isForUser(@NonNull String key, int userId) { - return mUserId == userId; - } - - @Override - protected void processExpiredAlarms(@NonNull ArraySet<String> expired) { - if (DEBUG) { - Slog.d(TAG, "Processing " + expired.size() + " expired alarms: " - + expired.toString()); - } - if (expired.size() > 0) { - mHandler.obtainMessage( - MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED, mUserId, 0, expired) - .sendToTarget(); - } - } - } - private class UserActionsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -575,8 +522,6 @@ public class UsageStatsService extends SystemService implements @Override public void onStatsReloaded() { - // This method ends up being called with the lock held, so we need to be careful how we - // call into other things. mAppStandby.postOneTimeCheckIdleStates(); } @@ -611,7 +556,7 @@ public class UsageStatsService extends SystemService implements /** * Obfuscate both {@link UsageEvents.Event#NOTIFICATION_SEEN} and * {@link UsageEvents.Event#NOTIFICATION_INTERRUPTION} events if the provided calling uid does - * not hold the {@link android.Manifest.permission#MANAGE_NOTIFICATIONS} permission. + * not hold the {@link android.Manifest.permission.MANAGE_NOTIFICATIONS} permission. */ private boolean shouldObfuscateNotificationEvents(int callingPid, int callingUid) { if (callingUid == Process.SYSTEM_UID) { @@ -1008,23 +953,6 @@ public class UsageStatsService extends SystemService implements event.mTaskRootClass, usageSourcePackage); resumedData.lastEvent = Event.ACTIVITY_RESUMED; mVisibleActivities.put(event.mInstanceId, resumedData); - final long estimatedLaunchTime = - mAppStandby.getEstimatedLaunchTime(event.mPackage, userId); - final long now = System.currentTimeMillis(); - if (estimatedLaunchTime < now || estimatedLaunchTime > now + ONE_WEEK) { - // If the estimated launch time is in the past or more than a week into - // the future, then we re-estimate a future launch time of less than a week - // from now, so notify listeners of an estimated launch time change. - // Clear the cached value. - if (DEBUG) { - Slog.d(TAG, event.getPackageName() - + " app launch resetting future launch estimate"); - } - mAppStandby.setEstimatedLaunchTime(event.mPackage, userId, 0); - mHandler.obtainMessage( - MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED, userId, 0, event.mPackage) - .sendToTarget(); - } break; case Event.ACTIVITY_PAUSED: ActivityData pausedData = mVisibleActivities.get(event.mInstanceId); @@ -1182,11 +1110,6 @@ public class UsageStatsService extends SystemService implements Slog.i(TAG, "Removing user " + userId + " and all data."); mUserState.remove(userId); mAppTimeLimit.onUserRemoved(userId); - final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue != null) { - alarmQueue.removeAllAlarms(); - mLaunchTimeAlarmQueues.remove(userId); - } } mAppStandby.onUserRemoved(userId); // Cancel any scheduled jobs for this user since the user is being removed. @@ -1206,10 +1129,6 @@ public class UsageStatsService extends SystemService implements // when the user service is initialized and package manager is queried. return; } - final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue != null) { - alarmQueue.removeAlarmForKey(packageName); - } final UserUsageStatsService userService = mUserState.get(userId); if (userService == null) { return; @@ -1355,7 +1274,6 @@ public class UsageStatsService extends SystemService implements /** * Called by the Binder stub. */ - @Nullable UsageEvents queryEventsForPackage(int userId, long beginTime, long endTime, String packageName, boolean includeTaskRoot) { synchronized (mLock) { @@ -1372,183 +1290,6 @@ public class UsageStatsService extends SystemService implements } } - @Nullable - private UsageEvents queryEarliestAppEvents(int userId, long beginTime, long endTime, - int eventType) { - synchronized (mLock) { - if (!mUserUnlockedStates.contains(userId)) { - Slog.w(TAG, "Failed to query earliest events for locked user " + userId); - return null; - } - - final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId); - if (service == null) { - return null; // user was stopped or removed - } - return service.queryEarliestAppEvents(beginTime, endTime, eventType); - } - } - - @Nullable - private UsageEvents queryEarliestEventsForPackage(int userId, long beginTime, long endTime, - @NonNull String packageName, int eventType) { - synchronized (mLock) { - if (!mUserUnlockedStates.contains(userId)) { - Slog.w(TAG, "Failed to query earliset package events for locked user " + userId); - return null; - } - - final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId); - if (service == null) { - return null; // user was stopped or removed - } - return service.queryEarliestEventsForPackage( - beginTime, endTime, packageName, eventType); - } - } - - @CurrentTimeMillisLong - long getEstimatedPackageLaunchTime(int userId, String packageName) { - long estimatedLaunchTime = mAppStandby.getEstimatedLaunchTime(packageName, userId); - final long now = System.currentTimeMillis(); - if (estimatedLaunchTime < now || estimatedLaunchTime == Long.MAX_VALUE) { - estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName); - mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime); - - synchronized (mLock) { - LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue == null) { - alarmQueue = new LaunchTimeAlarmQueue( - userId, getContext(), BackgroundThread.get().getLooper()); - mLaunchTimeAlarmQueues.put(userId, alarmQueue); - } - alarmQueue.addAlarm(packageName, - SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); - } - } - return estimatedLaunchTime; - } - - @CurrentTimeMillisLong - private long calculateEstimatedPackageLaunchTime(int userId, String packageName) { - synchronized (mLock) { - final long endTime = System.currentTimeMillis(); - final long beginTime = endTime - ONE_WEEK; - final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS; - final UsageEvents events = queryEarliestEventsForPackage( - userId, beginTime, endTime, packageName, Event.ACTIVITY_RESUMED); - if (events == null) { - if (DEBUG) { - Slog.d(TAG, "No events for " + userId + ":" + packageName); - } - return unknownTime; - } - final UsageEvents.Event event = new UsageEvents.Event(); - final boolean hasMoreThan24HoursOfHistory; - if (events.getNextEvent(event)) { - hasMoreThan24HoursOfHistory = endTime - event.getTimeStamp() > ONE_DAY; - if (DEBUG) { - Slog.d(TAG, userId + ":" + packageName + " history > 24 hours=" - + hasMoreThan24HoursOfHistory); - } - } else { - if (DEBUG) { - Slog.d(TAG, userId + ":" + packageName + " has no events"); - } - return unknownTime; - } - do { - if (event.getEventType() == Event.ACTIVITY_RESUMED) { - final long timestamp = event.getTimeStamp(); - final long nextLaunch = - calculateNextLaunchTime(hasMoreThan24HoursOfHistory, timestamp); - if (nextLaunch > endTime) { - return nextLaunch; - } - } - } while (events.getNextEvent(event)); - return unknownTime; - } - } - - @CurrentTimeMillisLong - private static long calculateNextLaunchTime( - boolean hasMoreThan24HoursOfHistory, long eventTimestamp) { - // For our estimates, we assume the user opens an app at consistent times - // (ie. like clockwork). - // If the app has more than 24 hours of history, then we assume the user will - // reopen the app at the same time on a specific day. - // If the app has less than 24 hours of history (meaning it was likely just - // installed), then we assume the user will open it at exactly the same time - // on the following day. - if (hasMoreThan24HoursOfHistory) { - return eventTimestamp + ONE_WEEK; - } else { - return eventTimestamp + ONE_DAY; - } - } - - private void handleEstimatedLaunchTimesOnUserUnlock(int userId) { - synchronized (mLock) { - final long nowElapsed = SystemClock.elapsedRealtime(); - final long now = System.currentTimeMillis(); - final long beginTime = now - ONE_WEEK; - final UsageEvents events = queryEarliestAppEvents( - userId, beginTime, now, Event.ACTIVITY_RESUMED); - if (events == null) { - return; - } - final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>(); - final UsageEvents.Event event = new UsageEvents.Event(); - LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue == null) { - alarmQueue = new LaunchTimeAlarmQueue( - userId, getContext(), BackgroundThread.get().getLooper()); - mLaunchTimeAlarmQueues.put(userId, alarmQueue); - } - final ArraySet<String> changedTimes = new ArraySet<>(); - for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent; - unprocessedEvent = events.getNextEvent(event)) { - final String packageName = event.getPackageName(); - if (!hasMoreThan24HoursOfHistory.containsKey(packageName)) { - boolean hasHistory = now - event.getTimeStamp() > ONE_DAY; - if (DEBUG) { - Slog.d(TAG, - userId + ":" + packageName + " history > 24 hours=" + hasHistory); - } - hasMoreThan24HoursOfHistory.put(packageName, hasHistory); - } - if (event.getEventType() == Event.ACTIVITY_RESUMED) { - long estimatedLaunchTime = - mAppStandby.getEstimatedLaunchTime(packageName, userId); - if (estimatedLaunchTime < now || estimatedLaunchTime == Long.MAX_VALUE) { - //noinspection ConstantConditions - estimatedLaunchTime = calculateNextLaunchTime( - hasMoreThan24HoursOfHistory.get(packageName), event.getTimeStamp()); - mAppStandby.setEstimatedLaunchTime( - packageName, userId, estimatedLaunchTime); - } - if (estimatedLaunchTime < now + ONE_WEEK) { - // Before a user is unlocked, we don't know when the app will be launched, - // so we give callers the UNKNOWN time. Now that we have a better estimate, - // we should notify them of the change. - if (DEBUG) { - Slog.d(TAG, "User " + userId + " unlock resulting in" - + " estimated launch time change for " + packageName); - } - changedTimes.add(packageName); - } - alarmQueue.addAlarm(packageName, nowElapsed + (estimatedLaunchTime - now)); - } - } - if (changedTimes.size() > 0) { - mHandler.obtainMessage( - MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED, userId, 0, changedTimes) - .sendToTarget(); - } - } - } - /** * Called via the local interface. */ @@ -1568,22 +1309,6 @@ public class UsageStatsService extends SystemService implements } } - /** - * Called via the local interface. - */ - private void registerLaunchTimeChangedListener( - @NonNull UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener listener) { - mEstimatedLaunchTimeChangedListeners.add(listener); - } - - /** - * Called via the local interface. - */ - private void unregisterLaunchTimeChangedListener( - @NonNull UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener listener) { - mEstimatedLaunchTimeChangedListeners.remove(listener); - } - private String buildFullToken(String packageName, String token) { final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1); sb.append(packageName); @@ -1839,44 +1564,6 @@ public class UsageStatsService extends SystemService implements loadGlobalComponentUsageLocked(); } break; - case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { - final int userId = msg.arg1; - handleEstimatedLaunchTimesOnUserUnlock(userId); - } - break; - case MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED: { - final int userId = msg.arg1; - final String pkgName = (String) msg.obj; - final long nextEstimatedLaunchTime = - getEstimatedPackageLaunchTime(userId, pkgName); - if (DEBUG) { - Slog.d(TAG, "Notifying listener for " + userId + ":" + pkgName); - } - for (UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener listener : - mEstimatedLaunchTimeChangedListeners) { - listener.onEstimatedLaunchTimeChanged( - userId, pkgName, nextEstimatedLaunchTime); - } - } - break; - case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: { - final int userId = msg.arg1; - final ArraySet<String> pkgNames = (ArraySet<String>) msg.obj; - if (DEBUG) { - Slog.d(TAG, "Notifying listeners for " + userId + "-->" + pkgNames); - } - for (int p = pkgNames.size() - 1; p >= 0; --p) { - final String pkgName = pkgNames.valueAt(p); - final long nextEstimatedLaunchTime = - getEstimatedPackageLaunchTime(userId, pkgName); - for (UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener listener : - mEstimatedLaunchTimeChangedListeners) { - listener.onEstimatedLaunchTimeChanged( - userId, pkgName, nextEstimatedLaunchTime); - } - } - } - break; default: super.handleMessage(msg); break; @@ -2776,11 +2463,6 @@ public class UsageStatsService extends SystemService implements } @Override - public long getEstimatedPackageLaunchTime(String packageName, int userId) { - return UsageStatsService.this.getEstimatedPackageLaunchTime(userId, packageName); - } - - @Override public long getTimeSinceLastJobRun(String packageName, int userId) { return mAppStandby.getTimeSinceLastJobRun(packageName, userId); } @@ -2845,18 +2527,6 @@ public class UsageStatsService extends SystemService implements public void unregisterListener(@NonNull UsageEventListener listener) { UsageStatsService.this.unregisterListener(listener); } - - @Override - public void registerLaunchTimeChangedListener( - @NonNull EstimatedLaunchTimeChangedListener listener) { - UsageStatsService.this.registerLaunchTimeChangedListener(listener); - } - - @Override - public void unregisterLaunchTimeChangedListener( - @NonNull EstimatedLaunchTimeChangedListener listener) { - UsageStatsService.this.unregisterLaunchTimeChangedListener(listener); - } } private class MyPackageMonitor extends PackageMonitor { diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index 23694fc5b418..c4a8e8148d22 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -29,8 +29,6 @@ import static android.app.usage.UsageStatsManager.INTERVAL_MONTHLY; import static android.app.usage.UsageStatsManager.INTERVAL_WEEKLY; import static android.app.usage.UsageStatsManager.INTERVAL_YEARLY; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.usage.ConfigurationStats; import android.app.usage.EventList; import android.app.usage.EventStats; @@ -367,46 +365,43 @@ class UserUsageStatsService { private static final StatCombiner<UsageStats> sUsageStatsCombiner = new StatCombiner<UsageStats>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<UsageStats> accResult) { if (!mutable) { accResult.addAll(stats.packageStats.values()); - return true; + return; } final int statCount = stats.packageStats.size(); for (int i = 0; i < statCount; i++) { accResult.add(new UsageStats(stats.packageStats.valueAt(i))); } - return true; } }; private static final StatCombiner<ConfigurationStats> sConfigStatsCombiner = new StatCombiner<ConfigurationStats>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<ConfigurationStats> accResult) { if (!mutable) { accResult.addAll(stats.configurations.values()); - return true; + return; } final int configCount = stats.configurations.size(); for (int i = 0; i < configCount; i++) { accResult.add(new ConfigurationStats(stats.configurations.valueAt(i))); } - return true; } }; private static final StatCombiner<EventStats> sEventStatsCombiner = new StatCombiner<EventStats>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<EventStats> accResult) { stats.addEventStatsTo(accResult); - return true; } }; @@ -419,7 +414,6 @@ class UserUsageStatsService { * and bucket, then calls the {@link com.android.server.usage.UsageStatsDatabase.StatCombiner} * provided to select the stats to use from the IntervalStats object. */ - @Nullable private <T> List<T> queryStats(int intervalType, final long beginTime, final long endTime, StatCombiner<T> combiner) { if (intervalType == INTERVAL_BEST) { @@ -516,16 +510,16 @@ class UserUsageStatsService { List<Event> results = queryStats(INTERVAL_DAILY, beginTime, endTime, new StatCombiner<Event>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<Event> accumulatedResult) { final int startIndex = stats.events.firstIndexOnOrAfter(beginTime); final int size = stats.events.size(); for (int i = startIndex; i < size; i++) { - Event event = stats.events.get(i); - if (event.mTimeStamp >= endTime) { - return false; + if (stats.events.get(i).mTimeStamp >= endTime) { + return; } + Event event = stats.events.get(i); final int eventType = event.mEventType; if (eventType == Event.SHORTCUT_INVOCATION && (flags & HIDE_SHORTCUT_EVENTS) == HIDE_SHORTCUT_EVENTS) { @@ -558,7 +552,6 @@ class UserUsageStatsService { } accumulatedResult.add(event); } - return true; } }); @@ -571,60 +564,6 @@ class UserUsageStatsService { return new UsageEvents(results, table, true); } - /** - * Returns a {@link UsageEvents} object whose events list contains only the earliest event seen - * for each app as well as the earliest event of {@code eventType} seen for each app. - */ - @Nullable - UsageEvents queryEarliestAppEvents(final long beginTime, final long endTime, - final int eventType) { - if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) { - return null; - } - final ArraySet<String> names = new ArraySet<>(); - final ArraySet<String> eventSuccess = new ArraySet<>(); - final List<Event> results = queryStats(INTERVAL_DAILY, - beginTime, endTime, (stats, mutable, accumulatedResult) -> { - final int startIndex = stats.events.firstIndexOnOrAfter(beginTime); - final int size = stats.events.size(); - for (int i = startIndex; i < size; i++) { - final Event event = stats.events.get(i); - if (event.getTimeStamp() >= endTime) { - return false; - } - if (event.getPackageName() == null) { - continue; - } - if (eventSuccess.contains(event.getPackageName())) { - continue; - } - - final boolean firstEvent = names.add(event.getPackageName()); - - if (event.getEventType() == eventType) { - accumulatedResult.add(event); - eventSuccess.add(event.getPackageName()); - } else if (firstEvent) { - // Save the earliest found event for the app, even if it doesn't match. - accumulatedResult.add(event); - } - } - return true; - }); - - if (results == null || results.isEmpty()) { - return null; - } - if (DEBUG) { - Slog.d(TAG, "Found " + results.size() + " early events for " + names.size() + " apps"); - } - - String[] table = names.toArray(new String[names.size()]); - Arrays.sort(table); - return new UsageEvents(results, table, false); - } - - @Nullable UsageEvents queryEventsForPackage(final long beginTime, final long endTime, final String packageName, boolean includeTaskRoot) { if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) { @@ -637,11 +576,11 @@ class UserUsageStatsService { final int startIndex = stats.events.firstIndexOnOrAfter(beginTime); final int size = stats.events.size(); for (int i = startIndex; i < size; i++) { - final Event event = stats.events.get(i); - if (event.mTimeStamp >= endTime) { - return false; + if (stats.events.get(i).mTimeStamp >= endTime) { + return; } + final Event event = stats.events.get(i); if (!packageName.equals(event.mPackage)) { continue; } @@ -656,7 +595,6 @@ class UserUsageStatsService { } accumulatedResult.add(event); } - return true; }); if (results == null || results.isEmpty()) { @@ -668,48 +606,6 @@ class UserUsageStatsService { return new UsageEvents(results, table, includeTaskRoot); } - /** - * Returns a {@link UsageEvents} object whose events list contains only the earliest event seen - * for the package as well as the earliest event of {@code eventType} seen for the package. - */ - @Nullable - UsageEvents queryEarliestEventsForPackage(final long beginTime, final long endTime, - @NonNull final String packageName, final int eventType) { - if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) { - return null; - } - final List<Event> results = queryStats(INTERVAL_DAILY, - beginTime, endTime, (stats, mutable, accumulatedResult) -> { - final int startIndex = stats.events.firstIndexOnOrAfter(beginTime); - final int size = stats.events.size(); - for (int i = startIndex; i < size; i++) { - final Event event = stats.events.get(i); - if (event.getTimeStamp() >= endTime) { - return false; - } - - if (!packageName.equals(event.getPackageName())) { - continue; - } - if (event.getEventType() == eventType) { - accumulatedResult.add(event); - // We've found the earliest of eventType. No need to keep going. - return false; - } else if (accumulatedResult.size() == 0) { - // Save the earliest found event, even if it doesn't match. - accumulatedResult.add(event); - } - } - return true; - }); - - if (results == null || results.isEmpty()) { - return null; - } - - return new UsageEvents(results, new String[]{packageName}, false); - } - void persistActiveStats() { if (mStatsChanged) { Slog.i(TAG, mLogPrefix + "Flushing usage stats to disk"); @@ -980,6 +876,7 @@ class UserUsageStatsService { return Long.toString(elapsedTime); } + void printEvent(IndentingPrintWriter pw, Event event, boolean prettyDates) { pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates)); pw.printPair("type", eventToString(event.mEventType)); @@ -1028,13 +925,13 @@ class UserUsageStatsService { List<Event> events = queryStats(INTERVAL_DAILY, beginTime, endTime, new StatCombiner<Event>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<Event> accumulatedResult) { final int startIndex = stats.events.firstIndexOnOrAfter(beginTime); final int size = stats.events.size(); for (int i = startIndex; i < size; i++) { if (stats.events.get(i).mTimeStamp >= endTime) { - return false; + return; } Event event = stats.events.get(i); @@ -1043,7 +940,6 @@ class UserUsageStatsService { } accumulatedResult.add(event); } - return true; } }); diff --git a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java index f695cbd5daf9..7e8a13470c35 100644 --- a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java +++ b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java @@ -62,13 +62,12 @@ public class UsageStatsDatabasePerfTest { private static final StatCombiner<UsageEvents.Event> sUsageStatsCombiner = new StatCombiner<UsageEvents.Event>() { @Override - public boolean combine(IntervalStats stats, boolean mutable, + public void combine(IntervalStats stats, boolean mutable, List<UsageEvents.Event> accResult) { final int size = stats.events.size(); for (int i = 0; i < size; i++) { accResult.add(stats.events.get(i)); } - return true; } }; |