diff options
| author | Collin Fijalkovich <cfijalkovich@google.com> | 2020-04-29 16:02:07 -0700 |
|---|---|---|
| committer | Collin Fijalkovich <cfijalkovich@google.com> | 2020-05-13 11:15:22 -0700 |
| commit | ceefcec397fedca948ab7a710e42ec635591f9b2 (patch) | |
| tree | 5b3ac105f046b40179b53b93d9ca3cdc13541a6e /core/java | |
| parent | 8c239da8d54bc2ac93fe666a7ca7825f0e82b923 (diff) | |
Add cache debugging information to bugreports.
Following the model for dumpsys gfxinfo, this patchset adds a
CacheBinder service that dumps cache state information from each
process.
Bug: 153661880
Test: adb shell dumpsys cacheinfo
Test: adb bugreport
Change-Id: Ie7cce70e56777a200e3e3e92ab895126b6f29032
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 6 | ||||
| -rw-r--r-- | core/java/android/app/IApplicationThread.aidl | 1 | ||||
| -rw-r--r-- | core/java/android/app/PropertyInvalidatedCache.java | 88 |
3 files changed, 94 insertions, 1 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index c6e2d5290d2e..ab82eb026b51 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1538,6 +1538,12 @@ public final class ActivityThread extends ClientTransactionHandler { IoUtils.closeQuietly(pfd); } + @Override + public void dumpCacheInfo(ParcelFileDescriptor pfd, String[] args) { + PropertyInvalidatedCache.dumpCacheInfo(pfd.getFileDescriptor(), args); + IoUtils.closeQuietly(pfd); + } + private File getDatabasesDir(Context context) { // There's no simple way to get the databases/ path, so do it this way. return context.getDatabasePath("a").getParentFile(); diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl index 1f6e4cac199a..6e9157e2a8c3 100644 --- a/core/java/android/app/IApplicationThread.aidl +++ b/core/java/android/app/IApplicationThread.aidl @@ -119,6 +119,7 @@ oneway interface IApplicationThread { boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable, in String[] args); void dumpGfxInfo(in ParcelFileDescriptor fd, in String[] args); + void dumpCacheInfo(in ParcelFileDescriptor fd, in String[] args); void dumpProvider(in ParcelFileDescriptor fd, IBinder servicetoken, in String[] args); void dumpDbInfo(in ParcelFileDescriptor fd, in String[] args); diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java index 58705434f774..01cf2b94a842 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -26,13 +26,19 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.FastPrintWriter; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; import java.util.Random; +import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicLong; @@ -235,6 +241,11 @@ public abstract class PropertyInvalidatedCache<Query, Result> { private boolean mDisabled = false; /** + * Maximum number of entries the cache will maintain. + */ + private final int mMaxEntries; + + /** * Make a new property invalidated cache. * * @param maxEntries Maximum number of entries to cache; LRU discard @@ -242,6 +253,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> { */ public PropertyInvalidatedCache(int maxEntries, @NonNull String propertyName) { mPropertyName = propertyName; + mMaxEntries = maxEntries; mCache = new LinkedHashMap<Query, Result>( 2 /* start small */, 0.75f /* default load factor */, @@ -728,11 +740,85 @@ public abstract class PropertyInvalidatedCache<Query, Result> { } /** - * Return a list of caches alive at the current time. + * Returns a list of caches alive at the current time. */ public static ArrayList<PropertyInvalidatedCache> getActiveCaches() { synchronized (sCorkLock) { return new ArrayList<PropertyInvalidatedCache>(sCaches.keySet()); } } + + /** + * Returns a list of the active corks in a process. + */ + public static ArrayList<Map.Entry<String, Integer>> getActiveCorks() { + synchronized (sCorkLock) { + return new ArrayList<Map.Entry<String, Integer>>(sCorks.entrySet()); + } + } + + private void dumpContents(PrintWriter pw, String[] args) { + synchronized (mLock) { + pw.println(String.format(" Cache Property Name: %s", cacheName())); + pw.println(String.format(" Last Observed Nonce: %d", mLastSeenNonce)); + pw.println(String.format(" Current Size: %d, Max Size: %d", + mCache.entrySet().size(), mMaxEntries)); + pw.println(String.format(" Enabled: %s", mDisabled ? "false" : "true")); + + Set<Map.Entry<Query, Result>> cacheEntries = mCache.entrySet(); + if (cacheEntries.size() == 0) { + pw.println(""); + return; + } + + pw.println(""); + pw.println(" Contents:"); + for (Map.Entry<Query, Result> entry : cacheEntries) { + String key = Objects.toString(entry.getKey()); + String value = Objects.toString(entry.getValue()); + + pw.println(String.format(" Key: %s\n Value: %s\n", key, value)); + } + } + } + + /** + * Dumps contents of every cache in the process to the provided FileDescriptor. + */ + public static void dumpCacheInfo(FileDescriptor fd, String[] args) { + ArrayList<PropertyInvalidatedCache> activeCaches; + ArrayList<Map.Entry<String, Integer>> activeCorks; + + try ( + FileOutputStream fout = new FileOutputStream(fd); + PrintWriter pw = new FastPrintWriter(fout); + ) { + if (!sEnabled) { + pw.println(" Caching is disabled in this process."); + return; + } + + synchronized (sCorkLock) { + activeCaches = getActiveCaches(); + activeCorks = getActiveCorks(); + + if (activeCorks.size() > 0) { + pw.println(" Corking Status:"); + for (int i = 0; i < activeCorks.size(); i++) { + Map.Entry<String, Integer> entry = activeCorks.get(i); + pw.println(String.format(" Property Name: %s Count: %d", + entry.getKey(), entry.getValue())); + } + } + } + + for (int i = 0; i < activeCaches.size(); i++) { + PropertyInvalidatedCache currentCache = activeCaches.get(i); + currentCache.dumpContents(pw, args); + pw.flush(); + } + } catch (IOException e) { + Log.e(TAG, "Failed to dump PropertyInvalidatedCache instances"); + } + } } |
