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

Commit f2aa49fb authored by Nate Myren's avatar Nate Myren Committed by Automerger Merge Worker
Browse files

Merge "Keep track of and persist largest AttributionChainId." into sc-dev am: c1f345fe

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

Change-Id: I926eb15d1931adfcf1376137a19caf8aa66921db
parents e6a8019f c1f345fe
Loading
Loading
Loading
Loading
+95 −17
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.appop;
package com.android.server.appop;


import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG;
import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG;
import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
@@ -58,7 +59,9 @@ import com.android.internal.util.XmlUtils;


import java.io.File;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Duration;
@@ -138,6 +141,7 @@ final class DiscreteRegistry {


    private static final String TAG_HISTORY = "h";
    private static final String TAG_HISTORY = "h";
    private static final String ATTR_VERSION = "v";
    private static final String ATTR_VERSION = "v";
    private static final String ATTR_LARGEST_CHAIN_ID = "lc";
    private static final int CURRENT_VERSION = 1;
    private static final int CURRENT_VERSION = 1;


    private static final String TAG_UID = "u";
    private static final String TAG_UID = "u";
@@ -182,6 +186,16 @@ final class DiscreteRegistry {


    DiscreteRegistry(Object inMemoryLock) {
    DiscreteRegistry(Object inMemoryLock) {
        mInMemoryLock = inMemoryLock;
        mInMemoryLock = inMemoryLock;
        synchronized (mOnDiskLock) {
            mDiscreteAccessDir = new File(
                    new File(Environment.getDataSystemDirectory(), "appops"),
                    "discrete");
            createDiscreteAccessDirLocked();
            int largestChainId = readLargestChainIdFromDiskLocked();
            synchronized (mInMemoryLock) {
                mDiscreteOps = new DiscreteOps(largestChainId);
            }
        }
    }
    }


    void systemReady() {
    void systemReady() {
@@ -190,15 +204,6 @@ final class DiscreteRegistry {
                    setDiscreteHistoryParameters(p);
                    setDiscreteHistoryParameters(p);
                });
                });
        setDiscreteHistoryParameters(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_PRIVACY));
        setDiscreteHistoryParameters(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_PRIVACY));
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
                mDiscreteAccessDir = new File(
                        new File(Environment.getDataSystemDirectory(), "appops"),
                        "discrete");
                createDiscreteAccessDirLocked();
                mDiscreteOps = new DiscreteOps();
            }
        }
    }
    }


    private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
    private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
@@ -251,7 +256,7 @@ final class DiscreteRegistry {
            DiscreteOps discreteOps;
            DiscreteOps discreteOps;
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
                discreteOps = mDiscreteOps;
                discreteOps = mDiscreteOps;
                mDiscreteOps = new DiscreteOps();
                mDiscreteOps = new DiscreteOps(discreteOps.mChainIdOffset);
                mCachedOps = null;
                mCachedOps = null;
            }
            }
            deleteOldDiscreteHistoryFilesLocked();
            deleteOldDiscreteHistoryFilesLocked();
@@ -275,6 +280,50 @@ final class DiscreteRegistry {
        return;
        return;
    }
    }


    private int readLargestChainIdFromDiskLocked() {
        final File[] files = mDiscreteAccessDir.listFiles();
        if (files != null && files.length > 0) {
            File latestFile = null;
            long latestFileTimestamp = 0;
            for (File f : files) {
                final String fileName = f.getName();
                if (!fileName.endsWith(DISCRETE_HISTORY_FILE_SUFFIX)) {
                    continue;
                }
                long timestamp = Long.valueOf(fileName.substring(0,
                        fileName.length() - DISCRETE_HISTORY_FILE_SUFFIX.length()));
                if (latestFileTimestamp < timestamp) {
                    latestFile = f;
                    latestFileTimestamp = timestamp;
                }
            }
            if (latestFile == null) {
                return 0;
            }
            FileInputStream stream;
            try {
                stream = new FileInputStream(latestFile);
            } catch (FileNotFoundException e) {
                return 0;
            }
            try {
                TypedXmlPullParser parser = Xml.resolvePullParser(stream);
                XmlUtils.beginDocument(parser, TAG_HISTORY);

                final int largestChainId = parser.getAttributeInt(null, ATTR_LARGEST_CHAIN_ID, 0);
                return largestChainId;
            } catch (Throwable t) {
                return 0;
            } finally {
                try {
                    stream.close();
                } catch (IOException e) { }
            }
        } else {
            return 0;
        }
    }

    private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
    private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
            long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
@@ -301,7 +350,7 @@ final class DiscreteRegistry {
    void clearHistory() {
    void clearHistory() {
        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
                mDiscreteOps = new DiscreteOps();
                mDiscreteOps = new DiscreteOps(0);
            }
            }
            clearOnDiskHistoryLocked();
            clearOnDiskHistoryLocked();
        }
        }
@@ -341,6 +390,10 @@ final class DiscreteRegistry {
                : new String[]{AppOpsManager.opToPublicName(dumpOp)};
                : new String[]{AppOpsManager.opToPublicName(dumpOp)};
        discreteOps.filter(0, Instant.now().toEpochMilli(), filter, uidFilter, packageNameFilter,
        discreteOps.filter(0, Instant.now().toEpochMilli(), filter, uidFilter, packageNameFilter,
                opNamesFilter, attributionTagFilter, OP_FLAGS_ALL);
                opNamesFilter, attributionTagFilter, OP_FLAGS_ALL);
        pw.print(prefix);
        pw.print("Largest chain id: ");
        pw.print(mDiscreteOps.mLargestChainId);
        pw.println();
        discreteOps.dump(pw, sdf, date, prefix, nDiscreteOps);
        discreteOps.dump(pw, sdf, date, prefix, nDiscreteOps);
    }
    }


@@ -351,14 +404,14 @@ final class DiscreteRegistry {
    }
    }


    private DiscreteOps getAllDiscreteOps() {
    private DiscreteOps getAllDiscreteOps() {
        DiscreteOps discreteOps = new DiscreteOps();
        DiscreteOps discreteOps = new DiscreteOps(0);


        synchronized (mOnDiskLock) {
        synchronized (mOnDiskLock) {
            synchronized (mInMemoryLock) {
            synchronized (mInMemoryLock) {
                discreteOps.merge(mDiscreteOps);
                discreteOps.merge(mDiscreteOps);
            }
            }
            if (mCachedOps == null) {
            if (mCachedOps == null) {
                mCachedOps = new DiscreteOps();
                mCachedOps = new DiscreteOps(0);
                readDiscreteOpsFromDisk(mCachedOps);
                readDiscreteOpsFromDisk(mCachedOps);
            }
            }
            discreteOps.merge(mCachedOps);
            discreteOps.merge(mCachedOps);
@@ -368,9 +421,13 @@ final class DiscreteRegistry {


    private final class DiscreteOps {
    private final class DiscreteOps {
        ArrayMap<Integer, DiscreteUidOps> mUids;
        ArrayMap<Integer, DiscreteUidOps> mUids;
        int mChainIdOffset;
        int mLargestChainId;


        DiscreteOps() {
        DiscreteOps(int chainIdOffset) {
            mUids = new ArrayMap<>();
            mUids = new ArrayMap<>();
            mChainIdOffset = chainIdOffset;
            mLargestChainId = chainIdOffset;
        }
        }


        boolean isEmpty() {
        boolean isEmpty() {
@@ -378,6 +435,7 @@ final class DiscreteRegistry {
        }
        }


        void merge(DiscreteOps other) {
        void merge(DiscreteOps other) {
            mLargestChainId = max(mLargestChainId, other.mLargestChainId);
            int nUids = other.mUids.size();
            int nUids = other.mUids.size();
            for (int i = 0; i < nUids; i++) {
            for (int i = 0; i < nUids; i++) {
                int uid = other.mUids.keyAt(i);
                int uid = other.mUids.keyAt(i);
@@ -390,6 +448,17 @@ final class DiscreteRegistry {
                @Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
                @Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
                @AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
                @AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
                @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
                @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
            if (attributionChainId != ATTRIBUTION_CHAIN_ID_NONE) {
                attributionChainId += mChainIdOffset;
                if (attributionChainId < 0) {
                    attributionChainId -= mChainIdOffset;
                    mChainIdOffset = 0;
                    mLargestChainId = attributionChainId;
                }
                if (attributionChainId > mLargestChainId) {
                    mLargestChainId = attributionChainId;
                }
            }
            getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags,
            getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags,
                    uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
                    uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
        }
        }
@@ -442,6 +511,7 @@ final class DiscreteRegistry {
            out.startDocument(null, true);
            out.startDocument(null, true);
            out.startTag(null, TAG_HISTORY);
            out.startTag(null, TAG_HISTORY);
            out.attributeInt(null, ATTR_VERSION, CURRENT_VERSION);
            out.attributeInt(null, ATTR_VERSION, CURRENT_VERSION);
            out.attributeInt(null, ATTR_LARGEST_CHAIN_ID, mLargestChainId);


            int nUids = mUids.size();
            int nUids = mUids.size();
            for (int i = 0; i < nUids; i++) {
            for (int i = 0; i < nUids; i++) {
@@ -476,8 +546,13 @@ final class DiscreteRegistry {
        }
        }


        private void readFromFile(File f, long beginTimeMillis) {
        private void readFromFile(File f, long beginTimeMillis) {
            FileInputStream stream;
            try {
                stream = new FileInputStream(f);
            } catch (FileNotFoundException e) {
                return;
            }
            try {
            try {
                FileInputStream stream = new FileInputStream(f);
                TypedXmlPullParser parser = Xml.resolvePullParser(stream);
                TypedXmlPullParser parser = Xml.resolvePullParser(stream);
                XmlUtils.beginDocument(parser, TAG_HISTORY);
                XmlUtils.beginDocument(parser, TAG_HISTORY);


@@ -487,7 +562,6 @@ final class DiscreteRegistry {
                if (version != CURRENT_VERSION) {
                if (version != CURRENT_VERSION) {
                    throw new IllegalStateException("Dropping unsupported discrete history " + f);
                    throw new IllegalStateException("Dropping unsupported discrete history " + f);
                }
                }

                int depth = parser.getDepth();
                int depth = parser.getDepth();
                while (XmlUtils.nextElementWithin(parser, depth)) {
                while (XmlUtils.nextElementWithin(parser, depth)) {
                    if (TAG_UID.equals(parser.getName())) {
                    if (TAG_UID.equals(parser.getName())) {
@@ -498,8 +572,12 @@ final class DiscreteRegistry {
            } catch (Throwable t) {
            } catch (Throwable t) {
                Slog.e(TAG, "Failed to read file " + f.getName() + " " + t.getMessage() + " "
                Slog.e(TAG, "Failed to read file " + f.getName() + " " + t.getMessage() + " "
                        + Arrays.toString(t.getStackTrace()));
                        + Arrays.toString(t.getStackTrace()));
            } finally {
                try {
                    stream.close();
                } catch (IOException e) {
                }
            }
            }

        }
        }
    }
    }


+1 −0
Original line number Original line Diff line number Diff line
@@ -209,6 +209,7 @@ final class HistoricalRegistry {
        mMode = other.mMode;
        mMode = other.mMode;
        mBaseSnapshotInterval = other.mBaseSnapshotInterval;
        mBaseSnapshotInterval = other.mBaseSnapshotInterval;
        mIntervalCompressionMultiplier = other.mIntervalCompressionMultiplier;
        mIntervalCompressionMultiplier = other.mIntervalCompressionMultiplier;
        mDiscreteRegistry = other.mDiscreteRegistry;
    }
    }


    void systemReady(@NonNull ContentResolver resolver) {
    void systemReady(@NonNull ContentResolver resolver) {