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

Commit bd45b826 authored by Stanislav Zholnin's avatar Stanislav Zholnin Committed by Android (Google) Code Review
Browse files

Merge "Bug fixes and testing support for DiscreteRegistry" into sc-dev

parents da3d4e86 c5f09f68
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -6511,13 +6511,21 @@ public class AppOpsManager {
            NoteOpEvent note = new NoteOpEvent(discreteAccessTime, discreteAccessDuration, null);
            accessEvents.append(key, note);
            AttributedOpEntry access = new AttributedOpEntry(mOp, false, accessEvents, null);
            for (int i = discreteAccesses.size() - 1; i >= 0; i--) {
                if (discreteAccesses.get(i).getLastAccessTime(OP_FLAGS_ALL) < discreteAccessTime) {
                    discreteAccesses.add(i + 1, access);
                    return;
            int insertionPoint = discreteAccesses.size() - 1;
            for (; insertionPoint >= 0; insertionPoint--) {
                if (discreteAccesses.get(insertionPoint).getLastAccessTime(OP_FLAGS_ALL)
                        < discreteAccessTime) {
                    break;
                }
            }
            discreteAccesses.add(0, access);
            insertionPoint++;
            if (insertionPoint < discreteAccesses.size() && discreteAccesses.get(
                    insertionPoint).getLastAccessTime(OP_FLAGS_ALL) == discreteAccessTime) {
                discreteAccesses.set(insertionPoint, mergeAttributedOpEntries(
                        Arrays.asList(discreteAccesses.get(insertionPoint), access)));
            } else {
                discreteAccesses.add(insertionPoint, access);
            }
        }

        /**
@@ -9858,8 +9866,11 @@ public class AppOpsManager {
                NoteOpEvent reject = a.getLastRejectEvent(uidState, uidState, flags);

                if (access != null) {
                    NoteOpEvent existingAccess = accessEvents.get(key);
                    if (existingAccess == null || existingAccess.getDuration() == -1) {
                        accessEvents.append(key, access);
                    }
                }
                if (reject != null) {
                    rejectEvents.append(key, reject);
                }
+73 −22
Original line number Diff line number Diff line
@@ -92,8 +92,8 @@ final class DiscreteRegistry {
            "discrete_history_quantization_millis";
    private static final String PROPERTY_DISCRETE_FLAGS = "discrete_history_op_flags";
    private static final String PROPERTY_DISCRETE_OPS_LIST = "discrete_history_ops_cslist";
    private static final String DEFAULT_DISCRETE_OPS = OP_CAMERA + "," + OP_RECORD_AUDIO + ","
            + OP_FINE_LOCATION + "," + OP_COARSE_LOCATION;
    private static final String DEFAULT_DISCRETE_OPS = OP_FINE_LOCATION + "," + OP_COARSE_LOCATION
            + "," + OP_CAMERA + "," + OP_RECORD_AUDIO;
    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 =
@@ -104,7 +104,6 @@ final class DiscreteRegistry {
    private static int[] sDiscreteOps;
    private static int sDiscreteFlags;


    private static final String TAG_HISTORY = "h";
    private static final String ATTR_VERSION = "v";
    private static final int CURRENT_VERSION = 1;
@@ -144,6 +143,8 @@ final class DiscreteRegistry {
    @GuardedBy("mOnDiskLock")
    private DiscreteOps mCachedOps = null;

    private boolean mDebugMode = false;

    DiscreteRegistry(Object inMemoryLock) {
        mInMemoryLock = inMemoryLock;
    }
@@ -159,40 +160,35 @@ final class DiscreteRegistry {
                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);
        sDiscreteFlags = DeviceConfig.getInt(DeviceConfig.NAMESPACE_PRIVACY,
                PROPERTY_DISCRETE_FLAGS, OP_FLAGS_DISCRETE);
        sDiscreteOps = parseOpsList(DeviceConfig.getString(DeviceConfig.NAMESPACE_PRIVACY,
                PROPERTY_DISCRETE_OPS_LIST, DEFAULT_DISCRETE_OPS));
        setDiscreteHistoryParameters(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_PRIVACY));
    }

    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) {
            if (!Build.IS_DEBUGGABLE && !mDebugMode) {
                sDiscreteHistoryCutoff = min(MAXIMUM_DISCRETE_HISTORY_CUTOFF,
                        sDiscreteHistoryCutoff);
            }
        } else {
            sDiscreteHistoryCutoff = DEFAULT_DISCRETE_HISTORY_CUTOFF;
        }
        if (p.getKeyset().contains(PROPERTY_DISCRETE_HISTORY_QUANTIZATION)) {
            sDiscreteHistoryQuantization = p.getLong(PROPERTY_DISCRETE_HISTORY_QUANTIZATION,
                    DEFAULT_DISCRETE_HISTORY_QUANTIZATION);
            if (!Build.IS_DEBUGGABLE) {
            if (!Build.IS_DEBUGGABLE && !mDebugMode) {
                sDiscreteHistoryQuantization = max(DEFAULT_DISCRETE_HISTORY_QUANTIZATION,
                        sDiscreteHistoryQuantization);
            }
        } else {
            sDiscreteHistoryQuantization = DEFAULT_DISCRETE_HISTORY_QUANTIZATION;
        }
        if (p.getKeyset().contains(PROPERTY_DISCRETE_FLAGS)) {
            sDiscreteFlags = p.getInt(PROPERTY_DISCRETE_FLAGS, OP_FLAGS_DISCRETE);
        }
        if (p.getKeyset().contains(PROPERTY_DISCRETE_OPS_LIST)) {
            sDiscreteOps = parseOpsList(p.getString(PROPERTY_DISCRETE_OPS_LIST,
                    DEFAULT_DISCRETE_OPS));
        }
        sDiscreteFlags = p.getKeyset().contains(PROPERTY_DISCRETE_FLAGS) ? sDiscreteFlags =
                p.getInt(PROPERTY_DISCRETE_FLAGS, OP_FLAGS_DISCRETE) : OP_FLAGS_DISCRETE;
        sDiscreteOps = p.getKeyset().contains(PROPERTY_DISCRETE_OPS_LIST) ? parseOpsList(
                p.getString(PROPERTY_DISCRETE_OPS_LIST, DEFAULT_DISCRETE_OPS)) : parseOpsList(
                DEFAULT_DISCRETE_OPS);
    }

    void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag,
@@ -232,6 +228,8 @@ final class DiscreteRegistry {
            @Nullable String packageNameFilter, @Nullable String[] opNamesFilter,
            @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) {
        DiscreteOps discreteOps = getAllDiscreteOps();
        beginTimeMillis = max(beginTimeMillis, Instant.now().minus(sDiscreteHistoryCutoff,
                ChronoUnit.MILLIS).toEpochMilli());
        discreteOps.filter(beginTimeMillis, endTimeMillis, filter, uidFilter, packageNameFilter,
                opNamesFilter, attributionTagFilter, flagsFilter);
        discreteOps.applyToHistoricalOps(result);
@@ -282,6 +280,18 @@ final class DiscreteRegistry {
        }
    }

    void offsetHistory(long offset) {
        synchronized (mOnDiskLock) {
            DiscreteOps discreteOps;
            synchronized (mInMemoryLock) {
                discreteOps = getAllDiscreteOps();
                clearHistory();
            }
            discreteOps.offsetHistory(offset);
            persistDiscreteOpsLocked(discreteOps);
        }
    }

    void dump(@NonNull PrintWriter pw, int uidFilter, @Nullable String packageNameFilter,
            @Nullable String attributionTagFilter,
            @AppOpsManager.HistoricalOpsRequestFilter int filter, int dumpOp,
@@ -363,6 +373,13 @@ final class DiscreteRegistry {
            }
        }

        private void offsetHistory(long offset) {
            int nUids = mUids.size();
            for (int i = 0; i < nUids; i++) {
                mUids.valueAt(i).offsetHistory(offset);
            }
        }

        private void clearHistory(int uid, String packageName) {
            if (mUids.containsKey(uid)) {
                mUids.get(uid).clearPackage(packageName);
@@ -549,6 +566,13 @@ final class DiscreteRegistry {
            }
        }

        private void offsetHistory(long offset) {
            int nPackages = mPackages.size();
            for (int i = 0; i < nPackages; i++) {
                mPackages.valueAt(i).offsetHistory(offset);
            }
        }

        private void clearPackage(String packageName) {
            mPackages.remove(packageName);
        }
@@ -656,6 +680,13 @@ final class DiscreteRegistry {
            }
        }

        private void offsetHistory(long offset) {
            int nOps = mPackageOps.size();
            for (int i = 0; i < nOps; i++) {
                mPackageOps.valueAt(i).offsetHistory(offset);
            }
        }

        private DiscreteOp getOrCreateDiscreteOp(int op) {
            DiscreteOp result = mPackageOps.get(op);
            if (result == null) {
@@ -749,12 +780,29 @@ final class DiscreteRegistry {
            }
        }

        private void offsetHistory(long offset) {
            int nTags = mAttributedOps.size();
            for (int i = 0; i < nTags; i++) {
                List<DiscreteOpEvent> list = mAttributedOps.valueAt(i);

                int n = list.size();
                for (int j = 0; j < n; j++) {
                    DiscreteOpEvent event = list.get(j);
                    list.set(j, new DiscreteOpEvent(event.mNoteTime - offset, event.mNoteDuration,
                            event.mUidState, event.mOpFlag));
                }
            }
        }

        void addDiscreteAccess(@Nullable String attributionTag,
                @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
                long accessTime, long accessDuration) {
            List<DiscreteOpEvent> attributedOps = getOrCreateDiscreteOpEventsList(
                    attributionTag);
            accessTime = accessTime / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
            accessDuration = accessDuration == -1 ? -1
                    : (accessDuration + sDiscreteHistoryQuantization - 1)
                            / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;

            int nAttributedOps = attributedOps.size();
            int i = nAttributedOps;
@@ -764,8 +812,7 @@ final class DiscreteRegistry {
                    break;
                }
                if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState) {
                    if (accessDuration != previousOp.mNoteDuration
                            && accessDuration > sDiscreteHistoryQuantization) {
                    if (accessDuration != previousOp.mNoteDuration) {
                        break;
                    } else {
                        return;
@@ -983,5 +1030,9 @@ final class DiscreteRegistry {
        }
        return true;
    }

    void setDebugMode(boolean debugMode) {
        this.mDebugMode = debugMode;
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -553,6 +553,11 @@ final class HistoricalRegistry {
                    if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
                        clearHistoryOnDiskDLocked();
                    }
                    if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_PASSIVE) {
                        mDiscreteRegistry.setDebugMode(true);
                    } else {
                        mDiscreteRegistry.setDebugMode(false);
                    }
                }
                if (mBaseSnapshotInterval != baseSnapshotInterval) {
                    mBaseSnapshotInterval = baseSnapshotInterval;
@@ -591,6 +596,7 @@ final class HistoricalRegistry {
                mPersistence.persistHistoricalOpsDLocked(history);
            }
        }
        mDiscreteRegistry.offsetHistory(offsetMillis);
    }

    void addHistoricalOps(HistoricalOps ops) {