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

Commit dc408dea authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes I8dc57930,Ia993613f,I111cc425 into sc-dev am: 209a1ee0 am: f6e311c9

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

Change-Id: I0b3188f54e49b584bbbac05d516c7c02aa3cbf77
parents 1d6c8b46 f6e311c9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ public final class DumpState {
    private boolean mTitlePrinted;
    private boolean mFullPreferred;
    private boolean mCheckIn;
    private boolean mBrief;

    private String mTargetPackageName;

@@ -128,4 +129,12 @@ public final class DumpState {
    public void setCheckIn(boolean checkIn) {
        mCheckIn = checkIn;
    }

    public boolean isBrief() {
        return mBrief;
    }

    public void setBrief(boolean brief) {
        mBrief = brief;
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;

import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.utils.WatchedArrayMap;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -65,7 +66,7 @@ public class KeySetManagerService {

    protected final LongSparseArray<ArraySet<Long>> mKeySetMapping;

    private final ArrayMap<String, PackageSetting> mPackages;
    private final WatchedArrayMap<String, PackageSetting> mPackages;

    private long lastIssuedKeySetId = 0;

@@ -114,7 +115,7 @@ public class KeySetManagerService {
        }
    }

    public KeySetManagerService(ArrayMap<String, PackageSetting> packages) {
    public KeySetManagerService(WatchedArrayMap<String, PackageSetting> packages) {
        mKeySets = new LongSparseArray<KeySetHandle>();
        mPublicKeys = new LongSparseArray<PublicKeyHandle>();
        mKeySetMapping = new LongSparseArray<ArraySet<Long>>();
+99 −29
Original line number Diff line number Diff line
@@ -404,6 +404,7 @@ import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
import com.android.server.rollback.RollbackManagerInternal;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.SnapshotCache;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.utils.Watchable;
import com.android.server.utils.Watched;
@@ -871,12 +872,17 @@ public class PackageManagerService extends IPackageManager.Stub
    @Watched
    @GuardedBy("mLock")
    final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>();
    private final SnapshotCache<WatchedArrayMap<String, AndroidPackage>> mPackagesSnapshot =
            new SnapshotCache.Auto(mPackages, mPackages, "PackageManagerService.mPackages");
    // Keys are isolated uids and values are the uid of the application
    // that created the isolated process.
    @Watched
    @GuardedBy("mLock")
    final WatchedSparseIntArray mIsolatedOwners = new WatchedSparseIntArray();
    private final SnapshotCache<WatchedSparseIntArray> mIsolatedOwnersSnapshot =
            new SnapshotCache.Auto(mIsolatedOwners, mIsolatedOwners,
                                   "PackageManagerService.mIsolatedOwners");
    /**
     * Tracks new system packages [received in an OTA] that we expect to
@@ -1309,14 +1315,17 @@ public class PackageManagerService extends IPackageManager.Stub
            // Avoid invalidation-thrashing by preventing cache invalidations from causing property
            // writes if the cache isn't enabled yet.  We re-enable writes later when we're
            // done initializing.
            sSnapshotCorked = true;
            sSnapshotCorked.incrementAndGet();
            PackageManager.corkPackageInfoCache();
        }
        @Override
        public void enablePackageCaches() {
            // Uncork cache invalidations and allow clients to cache package information.
            sSnapshotCorked = false;
            int corking = sSnapshotCorked.decrementAndGet();
            if (TRACE_SNAPSHOTS && corking == 0) {
                Log.i(TAG, "snapshot: corking returns to 0");
            }
            PackageManager.uncorkPackageInfoCache();
        }
    }
@@ -1395,14 +1404,27 @@ public class PackageManagerService extends IPackageManager.Stub
    @Watched
    final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
            mSharedLibraries = new WatchedArrayMap<>();
    private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
            mSharedLibrariesSnapshot =
            new SnapshotCache.Auto<>(mSharedLibraries, mSharedLibraries,
                                     "PackageManagerService.mSharedLibraries");
    @Watched
    final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
            mStaticLibsByDeclaringPackage = new WatchedArrayMap<>();
    private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
            mStaticLibsByDeclaringPackageSnapshot =
            new SnapshotCache.Auto<>(mSharedLibraries, mSharedLibraries,
                                     "PackageManagerService.mSharedLibraries");
    // Mapping from instrumentation class names to info about them.
    @Watched
    final WatchedArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation =
            new WatchedArrayMap<>();
    private final SnapshotCache<WatchedArrayMap<ComponentName, ParsedInstrumentation>>
            mInstrumentationSnapshot =
            new SnapshotCache.Auto<>(mInstrumentation, mInstrumentation,
                                     "PackageManagerService.mInstrumentation");
    // Packages whose data we have transfered into another package, thus
    // should no longer exist.
@@ -1588,6 +1610,7 @@ public class PackageManagerService extends IPackageManager.Stub
    static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
    static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
    static final int DOMAIN_VERIFICATION = 27;
    static final int SNAPSHOT_UNCORK = 28;
    static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
@@ -1834,11 +1857,11 @@ public class PackageManagerService extends IPackageManager.Stub
        Snapshot(int type) {
            if (type == Snapshot.SNAPPED) {
                settings = mSettings.snapshot();
                isolatedOwners = mIsolatedOwners.snapshot();
                packages = mPackages.snapshot();
                sharedLibs = mSharedLibraries.snapshot();
                staticLibs = mStaticLibsByDeclaringPackage.snapshot();
                instrumentation = mInstrumentation.snapshot();
                isolatedOwners = mIsolatedOwnersSnapshot.snapshot();
                packages = mPackagesSnapshot.snapshot();
                sharedLibs = mSharedLibrariesSnapshot.snapshot();
                staticLibs = mStaticLibsByDeclaringPackageSnapshot.snapshot();
                instrumentation = mInstrumentationSnapshot.snapshot();
                resolveComponentName = mResolveComponentName.clone();
                resolveActivity = new ActivityInfo(mResolveActivity);
                instantAppInstallerActivity =
@@ -4874,12 +4897,16 @@ public class PackageManagerService extends IPackageManager.Stub
    // A lock-free cache for frequently called functions.
    private volatile Computer mSnapshotComputer;
    // If true, the snapshot is invalid (stale).  The attribute is static since it may be
    // set from outside classes.
    private static volatile boolean sSnapshotInvalid = true;
    // set from outside classes.  The attribute may be set to true anywhere, although it
    // should only be set true while holding mLock.  However, the attribute id guaranteed
    // to be set false only while mLock and mSnapshotLock are both held.
    private static AtomicBoolean sSnapshotInvalid = new AtomicBoolean(true);
    // The package manager that is using snapshots.
    private static PackageManagerService sSnapshotConsumer = null;
    // If true, the snapshot is corked.  Do not create a new snapshot but use the live
    // computer.  This throttles snapshot creation during periods of churn in Package
    // Manager.
    private static volatile boolean sSnapshotCorked = false;
    private static AtomicInteger sSnapshotCorked = new AtomicInteger(0);
    /**
     * This lock is used to make reads from {@link #sSnapshotInvalid} and
@@ -4897,7 +4924,10 @@ public class PackageManagerService extends IPackageManager.Stub
    // The snapshot disable/enable switch.  An image with the flag set true uses snapshots
    // and an image with the flag set false does not use snapshots.
    private static final boolean SNAPSHOT_ENABLED = false;
    private static final boolean SNAPSHOT_ENABLED = true;
    // The default auto-cork delay for snapshots.  This is 1s.
    private static final long SNAPSHOT_AUTOCORK_DELAY_MS = TimeUnit.SECONDS.toMillis(1);
    // The per-instance snapshot disable/enable flag.  This is generally set to false in
    // test instances and set to SNAPSHOT_ENABLED in operational instances.
@@ -4922,15 +4952,16 @@ public class PackageManagerService extends IPackageManager.Stub
            // If the current thread holds mLock then it may have modified state but not
            // yet invalidated the snapshot.  Always give the thread the live computer.
            return mLiveComputer;
        } else if (sSnapshotCorked.get() > 0) {
            // Snapshots are corked, which means new ones should not be built right now.
            mSnapshotStatistics.corked();
            return mLiveComputer;
        }
        synchronized (mSnapshotLock) {
            // This synchronization block serializes access to the snapshot computer and
            // to the code that samples mSnapshotInvalid.
            Computer c = mSnapshotComputer;
            if (sSnapshotCorked && (c != null)) {
                // Snapshots are corked, which means new ones should not be built right now.
                c.use();
                return c;
            }
            if (sSnapshotInvalid || (c == null)) {
            if (sSnapshotInvalid.getAndSet(false) || (c == null)) {
                // The snapshot is invalid if it is marked as invalid or if it is null.  If it
                // is null, then it is currently being rebuilt by rebuildSnapshot().
                synchronized (mLock) {
@@ -4938,9 +4969,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    // invalidated as it is rebuilt.  However, the snapshot is still
                    // self-consistent (the lock is being held) and is current as of the time
                    // this function is entered.
                    if (sSnapshotInvalid) {
                    rebuildSnapshot();
                    }
                    // Guaranteed to be non-null.  mSnapshotComputer is only be set to null
                    // temporarily in rebuildSnapshot(), which is guarded by mLock().  Since
@@ -4958,12 +4987,11 @@ public class PackageManagerService extends IPackageManager.Stub
     * Rebuild the cached computer.  mSnapshotComputer is temporarily set to null to block other
     * threads from using the invalid computer until it is rebuilt.
     */
    @GuardedBy("mLock")
    @GuardedBy({ "mLock", "mSnapshotLock"})
    private void rebuildSnapshot() {
        final long now = SystemClock.currentTimeMicro();
        final int hits = mSnapshotComputer == null ? -1 : mSnapshotComputer.getUsed();
        mSnapshotComputer = null;
        sSnapshotInvalid = false;
        final Snapshot args = new Snapshot(Snapshot.SNAPPED);
        mSnapshotComputer = new ComputerEngine(args);
        final long done = SystemClock.currentTimeMicro();
@@ -4971,6 +4999,30 @@ public class PackageManagerService extends IPackageManager.Stub
        mSnapshotStatistics.rebuild(now, done, hits);
    }
    /**
     * Create a new snapshot.  Used for testing only.  This does collect statistics or
     * update the snapshot used by other actors.  It does not alter the invalidation
     * flag.  This method takes the mLock internally.
     */
    private Computer createNewSnapshot() {
        synchronized (mLock) {
            final Snapshot args = new Snapshot(Snapshot.SNAPPED);
            return new ComputerEngine(args);
        }
    }
    /**
     * Cork snapshots.  This times out after the programmed delay.
     */
    private void corkSnapshots(int multiplier) {
        int corking = sSnapshotCorked.getAndIncrement();
        if (TRACE_SNAPSHOTS && corking == 0) {
            Log.i(TAG, "snapshot: corking goes positive");
        }
        Message message = mHandler.obtainMessage(SNAPSHOT_UNCORK);
        mHandler.sendMessageDelayed(message, SNAPSHOT_AUTOCORK_DELAY_MS * multiplier);
    }
    /**
     * Create a live computer
     */
@@ -4986,9 +5038,9 @@ public class PackageManagerService extends IPackageManager.Stub
     */
    public static void onChange(@Nullable Watchable what) {
        if (TRACE_SNAPSHOTS) {
            Log.e(TAG, "snapshot: onChange(" + what + ")");
            Log.i(TAG, "snapshot: onChange(" + what + ")");
        }
        sSnapshotInvalid = true;
        sSnapshotInvalid.set(true);
    }
    /**
@@ -5367,6 +5419,13 @@ public class PackageManagerService extends IPackageManager.Stub
                    mDomainVerificationManager.runMessage(messageCode, object);
                    break;
                }
                case SNAPSHOT_UNCORK: {
                    int corking = sSnapshotCorked.decrementAndGet();
                    if (TRACE_SNAPSHOTS && corking == 0) {
                        Log.e(TAG, "snapshot: corking goes to zero in message handler");
                    }
                    break;
                }
            }
        }
    }
@@ -6383,12 +6442,13 @@ public class PackageManagerService extends IPackageManager.Stub
            // constructor, at which time the invalidation method updates it.  The cache is
            // corked initially to ensure a cached computer is not built until the end of the
            // constructor.
            mSnapshotEnabled = SNAPSHOT_ENABLED;
            sSnapshotCorked = true;
            sSnapshotInvalid = true;
            mSnapshotStatistics = new SnapshotStatistics();
            sSnapshotConsumer = this;
            sSnapshotCorked.set(1);
            sSnapshotInvalid.set(true);
            mLiveComputer = createLiveComputer();
            mSnapshotComputer = null;
            mSnapshotEnabled = SNAPSHOT_ENABLED;
            registerObserver();
        }
@@ -18521,7 +18581,7 @@ public class PackageManagerService extends IPackageManager.Stub
        }
    }
    @GuardedBy({"mInstallLock", "mLock"})
    @GuardedBy("mInstallLock")
    private void installPackagesTracedLI(List<InstallRequest> requests) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
@@ -24018,6 +24078,15 @@ public class PackageManagerService extends IPackageManager.Stub
                dumpState.setDump(DumpState.DUMP_PER_UID_READ_TIMEOUTS);
            } else if ("snapshot".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_SNAPSHOT_STATISTICS);
                if (opti < args.length) {
                    if ("--full".equals(args[opti])) {
                        dumpState.setBrief(false);
                        opti++;
                    } else if ("--brief".equals(args[opti])) {
                        dumpState.setBrief(true);
                        opti++;
                    }
                }
            } else if ("write".equals(cmd)) {
                synchronized (mLock) {
                    writeSettingsLPrTEMP();
@@ -24353,13 +24422,14 @@ public class PackageManagerService extends IPackageManager.Stub
                pw.println("  Snapshots disabled");
            } else {
                int hits = 0;
                int level = sSnapshotCorked.get();
                synchronized (mSnapshotLock) {
                    if (mSnapshotComputer != null) {
                        hits = mSnapshotComputer.getUsed();
                    }
                }
                final long now = SystemClock.currentTimeMicro();
                mSnapshotStatistics.dump(pw, "  ", now, hits, true);
                mSnapshotStatistics.dump(pw, "  ", now, hits, level, dumpState.isBrief());
            }
        }
    }
+92 −60

File changed.

Preview size limit exceeded, changes collapsed.

+35 −7
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;

import com.android.internal.annotations.GuardedBy;
import com.android.server.EventLogTags;

import java.io.PrintWriter;
@@ -238,6 +239,11 @@ public class SnapshotStatistics {
         */
        public int mTotalUsed = 0;

        /**
         * The total number of times a snapshot was bypassed because corking was in effect.
         */
        public int mTotalCorked = 0;

        /**
         * The total number of builds that count as big, which means they took longer than
         * SNAPSHOT_BIG_BUILD_TIME_NS.
@@ -291,6 +297,13 @@ public class SnapshotStatistics {
            }
        }

        /**
         * Record a cork.
         */
        private void corked() {
            mTotalCorked++;
        }

        private Stats(long now) {
            mStartTimeUs = now;
            mTimes = new int[mTimeBins.count()];
@@ -308,6 +321,7 @@ public class SnapshotStatistics {
            mUsed = Arrays.copyOf(orig.mUsed, orig.mUsed.length);
            mTotalBuilds = orig.mTotalBuilds;
            mTotalUsed = orig.mTotalUsed;
            mTotalCorked = orig.mTotalCorked;
            mBigBuilds = orig.mBigBuilds;
            mShortLived = orig.mShortLived;
            mTotalTimeUs = orig.mTotalTimeUs;
@@ -365,6 +379,7 @@ public class SnapshotStatistics {
         * Dump the summary statistics record.  Choose the header or the data.
         *    number of builds
         *    number of uses
         *    number of corks
         *    number of big builds
         *    number of short lifetimes
         *    cumulative build time, in seconds
@@ -373,13 +388,13 @@ public class SnapshotStatistics {
        private void dumpStats(PrintWriter pw, String indent, long now, boolean header) {
            dumpPrefix(pw, indent, now, header, "Summary stats");
            if (header) {
                pw.format(Locale.US, "  %10s  %10s  %10s  %10s  %10s  %10s",
                          "TotBlds", "TotUsed", "BigBlds", "ShortLvd",
                pw.format(Locale.US, "  %10s  %10s  %10s  %10s  %10s  %10s  %10s",
                          "TotBlds", "TotUsed", "TotCork", "BigBlds", "ShortLvd",
                          "TotTime", "MaxTime");
            } else {
                pw.format(Locale.US,
                        "  %10d  %10d  %10d  %10d  %10d  %10d",
                        mTotalBuilds, mTotalUsed, mBigBuilds, mShortLived,
                        "  %10d  %10d  %10d  %10d  %10d  %10d  %10d",
                        mTotalBuilds, mTotalUsed, mTotalCorked, mBigBuilds, mShortLived,
                        mTotalTimeUs / 1000, mMaxBuildTimeUs / 1000);
            }
            pw.println();
@@ -516,7 +531,7 @@ public class SnapshotStatistics {
     * @param done The time at which the snapshot rebuild completed, in ns.
     * @param hits The number of times the previous snapshot was used.
     */
    public void rebuild(long now, long done, int hits) {
    public final void rebuild(long now, long done, int hits) {
        // The duration has a span of about 2000s
        final int duration = (int) (done - now);
        boolean reportEvent = false;
@@ -543,10 +558,21 @@ public class SnapshotStatistics {
        }
    }

    /**
     * Record a corked snapshot request.
     */
    public final void corked() {
        synchronized (mLock) {
            mShort[0].corked();
            mLong[0].corked();
        }
    }

    /**
     * Roll a stats array.  Shift the elements up an index and create a new element at
     * index zero.  The old element zero is completed with the specified time.
     */
    @GuardedBy("mLock")
    private void shift(Stats[] s, long now) {
        s[0].complete(now);
        for (int i = s.length - 1; i > 0; i--) {
@@ -598,7 +624,8 @@ public class SnapshotStatistics {
     * Dump the statistics.  The format is compatible with the PackageManager dumpsys
     * output.
     */
    public void dump(PrintWriter pw, String indent, long now, int unrecorded, boolean full) {
    public void dump(PrintWriter pw, String indent, long now, int unrecorded,
                     int corkLevel, boolean full) {
        // Grab the raw statistics under lock, but print them outside of the lock.
        Stats[] l;
        Stats[] s;
@@ -608,7 +635,8 @@ public class SnapshotStatistics {
            s = Arrays.copyOf(mShort, mShort.length);
            s[0] = new Stats(s[0]);
        }
        pw.format(Locale.US, "%s Unrecorded hits %d", indent, unrecorded);
        pw.format(Locale.US, "%s Unrecorded-hits: %d  Cork-level: %d", indent,
                  unrecorded, corkLevel);
        pw.println();
        dump(pw, indent, now, l, s, "stats");
        if (!full) {
Loading