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

Commit 4bf375b8 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Add a hidden API to query appstandby constants.

This will allow the tests to query the value for
appstandby constants that are last known to
the AppStandbyController.

Bug: 221176951
Test: atest ./tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
Change-Id: I8175c9f0acbc44b25606b477c6db8b0edf85991d
parent f4ca3897
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package com.android.server.usage;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager.ProcessState;
import android.app.usage.AppStandbyInfo;
@@ -237,4 +238,11 @@ public interface AppStandbyInternal {
     */
    @ProcessState
    int getBroadcastResponseFgThresholdState();

    /**
     * Return the last known value corresponding to the {@code key} from
     * {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController.
     */
    @Nullable
    String getAppStandbyConstant(@NonNull String key);
}
+18 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Slog;
@@ -129,6 +130,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

@@ -372,6 +374,15 @@ public class AppStandbyController
    volatile int mBroadcastResponseFgThresholdState =
            ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE;

    /**
     * Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}.
     *
     * Note: We are intentionally not guarding this by any lock since this is only updated on
     * a handler thread and when querying, if we do end up seeing slightly older values, it is fine
     * since the values are only used in tests and doesn't need to be queried in any other cases.
     */
    private final Map<String, String> mAppStandbyProperties = new ArrayMap<>();

    /**
     * Whether we should allow apps into the
     * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not.
@@ -1832,6 +1843,12 @@ public class AppStandbyController
        return mBroadcastResponseFgThresholdState;
    }

    @Override
    @Nullable
    public String getAppStandbyConstant(@NonNull String key) {
        return mAppStandbyProperties.get(key);
    }

    @Override
    public void flushToDisk() {
        synchronized (mAppIdleLock) {
@@ -2733,6 +2750,7 @@ public class AppStandbyController
                            }
                            break;
                    }
                    mAppStandbyProperties.put(name, properties.getString(name, null));
                }
            }
        }
+2 −0
Original line number Diff line number Diff line
@@ -82,4 +82,6 @@ interface IUsageStatsManager {
            int userId);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
    void clearBroadcastEvents(String callingPackage, int userId);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG)")
    String getAppStandbyConstant(String key);
}
+12 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app.usage;

import android.Manifest;
import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -1505,4 +1506,15 @@ public final class UsageStatsManager {
            throw re.rethrowFromSystemServer();
        }
    }

    /** @hide */
    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
    @Nullable
    public String getAppStandbyConstant(@NonNull String key) {
        try {
            return mService.getAppStandbyConstant(key);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }
}
+15 −5
Original line number Diff line number Diff line
@@ -2015,7 +2015,7 @@ public class UsageStatsService extends SystemService implements
                    == PackageManager.PERMISSION_GRANTED;
        }

        private boolean hasPermissions(String callingPackage, String... permissions) {
        private boolean hasPermissions(String... permissions) {
            final int callingUid = Binder.getCallingUid();
            if (callingUid == Process.SYSTEM_UID) {
                // Caller is the system, so proceed.
@@ -2578,7 +2578,7 @@ public class UsageStatsService extends SystemService implements
                String callingPackage) {
            final int callingUid = Binder.getCallingUid();
            final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
            if (!hasPermissions(callingPackage,
            if (!hasPermissions(
                    Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)
                    && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) {
                throw new SecurityException("Caller must be the active supervision app or "
@@ -2605,7 +2605,7 @@ public class UsageStatsService extends SystemService implements
        public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) {
            final int callingUid = Binder.getCallingUid();
            final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
            if (!hasPermissions(callingPackage,
            if (!hasPermissions(
                    Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)
                    && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) {
                throw new SecurityException("Caller must be the active supervision app or "
@@ -2703,8 +2703,7 @@ public class UsageStatsService extends SystemService implements

        @Override
        public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) {
            if (!hasPermissions(
                    callingPackage, android.Manifest.permission.INTERACT_ACROSS_USERS)) {
            if (!hasPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS)) {
                throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission");
            }
            if (!hasPermission(callingPackage)) {
@@ -2787,6 +2786,17 @@ public class UsageStatsService extends SystemService implements
                    "clearBroadcastResponseStats" /* name */, callingPackage);
            mResponseStatsTracker.clearBroadcastEvents(callingUid, userId);
        }

        @Override
        @Nullable
        public String getAppStandbyConstant(@NonNull String key) {
            Objects.requireNonNull(key);

            if (!hasPermissions(Manifest.permission.READ_DEVICE_CONFIG)) {
                throw new SecurityException("Caller doesn't have READ_DEVICE_CONFIG permission");
            }
            return mAppStandby.getAppStandbyConstant(key);
        }
    }

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