Loading core/java/android/app/ActivityThread.java +6 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading core/java/android/app/IApplicationThread.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/android/app/PropertyInvalidatedCache.java +87 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -234,6 +240,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. * Loading @@ -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 */, Loading Loading @@ -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"); } } } core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +5 −0 Original line number Diff line number Diff line Loading @@ -562,6 +562,11 @@ public class TransactionParcelTests { throws RemoteException { } @Override public void dumpCacheInfo(ParcelFileDescriptor parcelFileDescriptor, String[] strings) throws RemoteException { } @Override public void dumpProvider(ParcelFileDescriptor parcelFileDescriptor, IBinder iBinder, String[] strings) throws RemoteException { Loading services/core/java/com/android/server/am/ActivityManagerService.java +95 −27 Original line number Diff line number Diff line Loading @@ -2098,6 +2098,7 @@ public class ActivityManagerService extends IActivityManager.Stub } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); ServiceManager.addService("cacheinfo", new CacheBinder(this)); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); Loading Loading @@ -2191,6 +2192,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } Loading @@ -2198,12 +2200,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "meminfo", pw)) return; PriorityDump.dump(mPriorityDumper, fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } static class GraphicsBinder extends Binder { ActivityManagerService mActivityManagerService; Loading @@ -2213,6 +2216,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } Loading @@ -2220,12 +2224,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "gfxinfo", pw)) return; mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } static class DbBinder extends Binder { ActivityManagerService mActivityManagerService; Loading @@ -2235,6 +2240,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } Loading @@ -2242,12 +2248,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "dbinfo", pw)) return; mActivityManagerService.dumpDbInfo(fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } static class CpuBinder extends Binder { ActivityManagerService mActivityManagerService; Loading Loading @@ -2280,6 +2287,34 @@ public class ActivityManagerService extends IActivityManager.Stub } } static class CacheBinder extends Binder { ActivityManagerService mActivityManagerService; CacheBinder(ActivityManagerService activityManagerService) { mActivityManagerService = activityManagerService; } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "cacheinfo", pw)) { return; } mActivityManagerService.dumpBinderCacheContents(fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; private static ActivityTaskManagerService sAtm; Loading Loading @@ -12722,6 +12757,39 @@ public class ActivityManagerService extends IActivityManager.Stub } } final void dumpBinderCacheContents(FileDescriptor fd, PrintWriter pw, String[] args) { ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); if (procs == null) { pw.println("No process found for: " + args[0]); return; } pw.println("Per-process Binder Cache Contents"); for (int i = procs.size() - 1; i >= 0; i--) { ProcessRecord r = procs.get(i); if (r.thread != null) { pw.println("\n\n** Cache info for pid " + r.pid + " [" + r.processName + "] **"); pw.flush(); try { TransferPipe tp = new TransferPipe(); try { r.thread.dumpCacheInfo(tp.getWriteFd(), args); tp.go(fd); } finally { tp.kill(); } } catch (IOException e) { pw.println("Failure while dumping the app " + r); pw.flush(); } catch (RemoteException e) { pw.println("Got a RemoteException while dumping the app " + r); pw.flush(); } } } } final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); if (procs == null) { Loading
core/java/android/app/ActivityThread.java +6 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading
core/java/android/app/IApplicationThread.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/android/app/PropertyInvalidatedCache.java +87 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -234,6 +240,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. * Loading @@ -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 */, Loading Loading @@ -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"); } } }
core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +5 −0 Original line number Diff line number Diff line Loading @@ -562,6 +562,11 @@ public class TransactionParcelTests { throws RemoteException { } @Override public void dumpCacheInfo(ParcelFileDescriptor parcelFileDescriptor, String[] strings) throws RemoteException { } @Override public void dumpProvider(ParcelFileDescriptor parcelFileDescriptor, IBinder iBinder, String[] strings) throws RemoteException { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +95 −27 Original line number Diff line number Diff line Loading @@ -2098,6 +2098,7 @@ public class ActivityManagerService extends IActivityManager.Stub } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); ServiceManager.addService("cacheinfo", new CacheBinder(this)); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); Loading Loading @@ -2191,6 +2192,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } Loading @@ -2198,12 +2200,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "meminfo", pw)) return; PriorityDump.dump(mPriorityDumper, fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } static class GraphicsBinder extends Binder { ActivityManagerService mActivityManagerService; Loading @@ -2213,6 +2216,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } Loading @@ -2220,12 +2224,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "gfxinfo", pw)) return; mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } static class DbBinder extends Binder { ActivityManagerService mActivityManagerService; Loading @@ -2235,6 +2240,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } Loading @@ -2242,12 +2248,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "dbinfo", pw)) return; mActivityManagerService.dumpDbInfo(fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } static class CpuBinder extends Binder { ActivityManagerService mActivityManagerService; Loading Loading @@ -2280,6 +2287,34 @@ public class ActivityManagerService extends IActivityManager.Stub } } static class CacheBinder extends Binder { ActivityManagerService mActivityManagerService; CacheBinder(ActivityManagerService activityManagerService) { mActivityManagerService = activityManagerService; } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(false); } if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "cacheinfo", pw)) { return; } mActivityManagerService.dumpBinderCacheContents(fd, pw, args); } finally { if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { Process.enableFreezer(true); } } } } public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; private static ActivityTaskManagerService sAtm; Loading Loading @@ -12722,6 +12757,39 @@ public class ActivityManagerService extends IActivityManager.Stub } } final void dumpBinderCacheContents(FileDescriptor fd, PrintWriter pw, String[] args) { ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); if (procs == null) { pw.println("No process found for: " + args[0]); return; } pw.println("Per-process Binder Cache Contents"); for (int i = procs.size() - 1; i >= 0; i--) { ProcessRecord r = procs.get(i); if (r.thread != null) { pw.println("\n\n** Cache info for pid " + r.pid + " [" + r.processName + "] **"); pw.flush(); try { TransferPipe tp = new TransferPipe(); try { r.thread.dumpCacheInfo(tp.getWriteFd(), args); tp.go(fd); } finally { tp.kill(); } } catch (IOException e) { pw.println("Failure while dumping the app " + r); pw.flush(); } catch (RemoteException e) { pw.println("Got a RemoteException while dumping the app " + r); pw.flush(); } } } } final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); if (procs == null) {