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

Commit 41ec7a8e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add device config parameters to DiscreteRegistry." into sc-dev

parents 80e87134 3c46aca4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -646,7 +646,7 @@ public final class DeviceConfig {
     * @param name      The name of the property to look up.
     * @param defaultValue The value to return if the property does not exist or has no non-null
     *                     value.
     * @return the corresponding value, or defaultValue if none exists.
     * @return the correspondfing value, or defaultValue if none exists.
     * @hide
     */
    @SystemApi
+70 −11
Original line number Diff line number Diff line
@@ -31,14 +31,18 @@ import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.flagsToString;
import static android.app.AppOpsManager.getUidStateName;

import static java.lang.Long.min;
import static java.lang.Math.max;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.TypedXmlPullParser;
@@ -82,8 +86,16 @@ final class DiscreteRegistry {
    static final String TIMELINE_FILE_SUFFIX = "tl";
    private static final String TAG = DiscreteRegistry.class.getSimpleName();

    private static final long TIMELINE_HISTORY_CUTOFF = Duration.ofHours(24).toMillis();
    private static final long TIMELINE_QUANTIZATION = Duration.ofMinutes(1).toMillis();
    private static final String PROPERTY_DISCRETE_HISTORY_CUTOFF = "discrete_history_cutoff_millis";
    private static final String PROPERTY_DISCRETE_HISTORY_QUANTIZATION =
            "discrete_history_quantization_millis";
    private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofHours(24).toMillis();
    private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis();
    private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION =
            Duration.ofMinutes(1).toMillis();

    private static long sDiscreteHistoryCutoff;
    private static long sDiscreteHistoryQuantization;

    private static final String TAG_HISTORY = "h";
    private static final String ATTR_VERSION = "v";
@@ -116,7 +128,7 @@ final class DiscreteRegistry {
    private final @NonNull Object mInMemoryLock;

    @GuardedBy("mOnDiskLock")
    private final File mDiscreteAccessDir;
    private File mDiscreteAccessDir;

    @GuardedBy("mInMemoryLock")
    private DiscreteOps mDiscreteOps;
@@ -126,11 +138,43 @@ final class DiscreteRegistry {

    DiscreteRegistry(Object inMemoryLock) {
        mInMemoryLock = inMemoryLock;
    }

    void systemReady() {
        synchronized (mOnDiskLock) {
            mDiscreteAccessDir = new File(new File(Environment.getDataSystemDirectory(), "appops"),
                    "discrete");
        createDiscreteAccessDir();
            createDiscreteAccessDirLocked();
            mDiscreteOps = new DiscreteOps();
        }
        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
                AsyncTask.THREAD_POOL_EXECUTOR, (DeviceConfig.Properties p) -> {
                    setDiscreteHistoryParameters(p);
                });
        sDiscreteHistoryCutoff = DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY,
                PROPERTY_DISCRETE_HISTORY_CUTOFF, DEFAULT_DISCRETE_HISTORY_CUTOFF);
        sDiscreteHistoryQuantization = DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY,
                PROPERTY_DISCRETE_HISTORY_QUANTIZATION, DEFAULT_DISCRETE_HISTORY_QUANTIZATION);
    }

    private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
        if (p.getKeyset().contains(PROPERTY_DISCRETE_HISTORY_CUTOFF)) {
            sDiscreteHistoryCutoff = p.getLong(PROPERTY_DISCRETE_HISTORY_CUTOFF,
                    DEFAULT_DISCRETE_HISTORY_CUTOFF);
            if (!Build.IS_DEBUGGABLE) {
                sDiscreteHistoryCutoff = min(MAXIMUM_DISCRETE_HISTORY_CUTOFF,
                        sDiscreteHistoryCutoff);
            }
        }
        if (p.getKeyset().contains(PROPERTY_DISCRETE_HISTORY_QUANTIZATION)) {
            sDiscreteHistoryQuantization = p.getLong(PROPERTY_DISCRETE_HISTORY_QUANTIZATION,
                    DEFAULT_DISCRETE_HISTORY_QUANTIZATION);
            if (!Build.IS_DEBUGGABLE) {
                sDiscreteHistoryQuantization = max(DEFAULT_DISCRETE_HISTORY_QUANTIZATION,
                        sDiscreteHistoryQuantization);
            }
        }
    }

    private void createDiscreteAccessDir() {
        if (!mDiscreteAccessDir.exists()) {
@@ -142,6 +186,7 @@ final class DiscreteRegistry {
        }
    }

    /* can be called only after HistoricalRegistry.isPersistenceInitialized() check */
    void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag,
            @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime,
            long accessDuration) {
@@ -156,6 +201,10 @@ final class DiscreteRegistry {

    void writeAndClearAccessHistory() {
        synchronized (mOnDiskLock) {
            if (mDiscreteAccessDir == null) {
                Slog.e(TAG, "State not saved - persistence not initialized.");
                return;
            }
            final File[] files = mDiscreteAccessDir.listFiles();
            if (files != null && files.length > 0) {
                for (File f : files) {
@@ -166,7 +215,7 @@ final class DiscreteRegistry {
                    try {
                        long timestamp = Long.valueOf(fileName.substring(0,
                                fileName.length() - TIMELINE_FILE_SUFFIX.length()));
                        if (Instant.now().minus(TIMELINE_HISTORY_CUTOFF,
                        if (Instant.now().minus(sDiscreteHistoryCutoff,
                                ChronoUnit.MILLIS).toEpochMilli() > timestamp) {
                            f.delete();
                            Slog.e(TAG, "Deleting file " + fileName);
@@ -229,7 +278,7 @@ final class DiscreteRegistry {

    private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
        synchronized (mOnDiskLock) {
            long beginTimeMillis = Instant.now().minus(TIMELINE_HISTORY_CUTOFF,
            long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
                    ChronoUnit.MILLIS).toEpochMilli();

            final File[] files = mDiscreteAccessDir.listFiles();
@@ -423,6 +472,16 @@ final class DiscreteRegistry {
        }
    }

    private void createDiscreteAccessDirLocked() {
        if (!mDiscreteAccessDir.exists()) {
            if (!mDiscreteAccessDir.mkdirs()) {
                Slog.e(TAG, "Failed to create DiscreteRegistry directory");
            }
            FileUtils.setPermissions(mDiscreteAccessDir.getPath(),
                    FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
        }
    }

    private final class DiscreteUidOps {
        ArrayMap<String, DiscretePackageOps> mPackages;

@@ -663,7 +722,7 @@ final class DiscreteRegistry {
                long accessTime, long accessDuration) {
            List<DiscreteOpEvent> attributedOps = getOrCreateDiscreteOpEventsList(
                    attributionTag);
            accessTime = accessTime / TIMELINE_QUANTIZATION * TIMELINE_QUANTIZATION;
            accessTime = accessTime / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;

            int nAttributedOps = attributedOps.size();
            int i = nAttributedOps;
@@ -674,7 +733,7 @@ final class DiscreteRegistry {
                }
                if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState) {
                    if (accessDuration != previousOp.mNoteDuration
                            && accessDuration > TIMELINE_QUANTIZATION) {
                            && accessDuration > sDiscreteHistoryQuantization) {
                        break;
                    } else {
                        return;
+1 −0
Original line number Diff line number Diff line
@@ -246,6 +246,7 @@ final class HistoricalRegistry {
                                    + " by which to push history on next write");
                        }
                    }
                    mDiscreteRegistry.systemReady();
                }
            }
        }