Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6fe3ee1 authored by Zhen Zhang's avatar Zhen Zhang Committed by Automerger Merge Worker
Browse files

Merge "Create package-level last time usage stats for app hibernation" into sc-dev am: eed24982

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13933089

Change-Id: I0ba03547e92c28ee32d7938beca4f30b287f807c
parents fb2db193 eed24982
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1847,6 +1847,7 @@ package android.app.usage {
  public final class UsageStatsManager {
    method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getAppStandbyBucket(String);
    method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public java.util.Map<java.lang.String,java.lang.Integer> getAppStandbyBuckets();
    method @RequiresPermission(allOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long getLastTimeAnyComponentUsed(@NonNull String);
    method public int getUsageSource();
    method @RequiresPermission(android.Manifest.permission.BIND_CARRIER_SERVICES) public void onCarrierPrivilegedAppsChanged();
    method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @Nullable android.app.PendingIntent);
+1 −0
Original line number Diff line number Diff line
@@ -67,4 +67,5 @@ interface IUsageStatsManager {
    void reportUsageStop(in IBinder activity, String token, String callingPackage);
    int getUsageSource();
    void forceUsageSourceSettingRead();
    long getLastTimeAnyComponentUsed(String packageName);
}
+29 −0
Original line number Diff line number Diff line
@@ -1250,4 +1250,33 @@ public final class UsageStatsManager {
        } catch (RemoteException re) {
        }
    }

    /**
     * Get the last time a package is used by any users including explicit user interaction and
     * component usage, measured in milliseconds since the epoch and truncated to the boundary of
     * last day before the exact time. For packages that are never used, the time will be the epoch.
     * <p> Note that this usage stats is user-agnostic. </p>
     * <p>
     * Also note that component usage is only reported for component bindings (e.g. broadcast
     * receiver, service, content provider) and only when such a binding would cause an app to leave
     * the stopped state.
     * See {@link UsageEvents.Event.USER_INTERACTION}, {@link UsageEvents.Event.APP_COMPONENT_USED}.
     * </p>
     *
     * @param packageName The name of the package to be queried.
     * @return last time the queried package is used since the epoch.
     * @hide
     */
    @SystemApi
    @RequiresPermission(allOf = {
            android.Manifest.permission.INTERACT_ACROSS_USERS,
            android.Manifest.permission.PACKAGE_USAGE_STATS})
    public long getLastTimeAnyComponentUsed(@NonNull String packageName) {
        // TODO(b/183462940): This usage data is not persisted to disk yet.
        try {
            return mService.getLastTimeAnyComponentUsed(packageName);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -106,7 +106,9 @@ public class UserUsageStatsServiceTest {

    @Test
    public void testReportEvent_packageUsedEventNotTracked() {
        Event event = new Event(APP_COMPONENT_USED, SystemClock.elapsedRealtime());
        // For APP_COMPONENT_USED event, the time stamp should have been converted to current time
        // before reported here.
        Event event = new Event(APP_COMPONENT_USED, System.currentTimeMillis());
        event.mPackage = TEST_PACKAGE_NAME;
        mService.reportEvent(event);

+49 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Slog;
@@ -109,8 +110,10 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;

/**
 * A service that collects, aggregates, and persists application usage data.
@@ -166,6 +169,11 @@ public class UsageStatsService extends SystemService implements
    private final SparseIntArray mUidToKernelCounter = new SparseIntArray();
    int mUsageSource;

    private long mRealTimeSnapshot;
    private long mSystemTimeSnapshot;
    // A map storing last time global usage of packages, measured in milliseconds since the epoch.
    private final Map<String, Long> mLastTimeComponentUsedGlobal = new ArrayMap<>();

    /** Manages the standby state of apps. */
    AppStandbyInternal mAppStandby;

@@ -279,6 +287,9 @@ public class UsageStatsService extends SystemService implements
        getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter,
                null, mHandler);

        mRealTimeSnapshot = SystemClock.elapsedRealtime();
        mSystemTimeSnapshot = System.currentTimeMillis();

        publishLocalService(UsageStatsManagerInternal.class, new LocalService());
        publishLocalService(AppStandbyInternal.class, mAppStandby);
        publishBinderServices();
@@ -803,6 +814,28 @@ public class UsageStatsService extends SystemService implements
        }
    }

    /**
     * Assuming the event's timestamp is measured in milliseconds since boot,
     * convert it to a system wall time. System and real time snapshots are updated before
     * conversion.
     */
    private void convertToSystemTimeLocked(Event event) {
        final long actualSystemTime = System.currentTimeMillis();
        if (ENABLE_TIME_CHANGE_CORRECTION) {
            final long actualRealtime = SystemClock.elapsedRealtime();
            final long expectedSystemTime =
                    (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
            final long diffSystemTime = actualSystemTime - expectedSystemTime;
            if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
                // The time has changed.
                Slog.i(TAG, "Time changed in by " + (diffSystemTime / 1000) + " seconds");
                mRealTimeSnapshot = actualRealtime;
                mSystemTimeSnapshot = actualSystemTime;
            }
        }
        event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
    }

    /**
     * Called by the Binder stub.
     */
@@ -940,6 +973,12 @@ public class UsageStatsService extends SystemService implements
                        Slog.w(TAG, "Failed to note usage stop", iae);
                    }
                    break;
                case Event.USER_INTERACTION:
                    // Fall through
                case Event.APP_COMPONENT_USED:
                    convertToSystemTimeLocked(event);
                    mLastTimeComponentUsedGlobal.put(event.mPackage, event.mTimeStamp);
                    break;
            }

            final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
@@ -2094,6 +2133,16 @@ public class UsageStatsService extends SystemService implements
        public void forceUsageSourceSettingRead() {
            readUsageSourceSetting();
        }

        @Override
        public long getLastTimeAnyComponentUsed(String packageName) {
            synchronized (mLock) {
                // Truncate the returned milliseconds to the boundary of the last day before exact
                // time for privacy reasons.
                return mLastTimeComponentUsedGlobal.getOrDefault(packageName, 0L)
                        / TimeUnit.DAYS.toMillis(1) * TimeUnit.DAYS.toMillis(1);
            }
        }
    }

    void registerAppUsageObserver(int callingUid, int observerId, String[] packages,
Loading