Merge changes from topic "dump-cacheinfo" into rvc-dev am: acb2bba925 am: 5f2f1b3feb

Change-Id: I031d992befa4e942e01f646531ef93211bd95fba
This commit is contained in:
Collin Fijalkovich
2020-05-18 21:03:35 +00:00
committed by Automerger Merge Worker
5 changed files with 194 additions and 28 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;
@@ -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.
*
@@ -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");
}
}
}

View File

@@ -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 {

View File

@@ -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);
@@ -2191,16 +2192,18 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"meminfo", pw)) return;
PriorityDump.dump(mPriorityDumper, fd, pw, args);
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"meminfo", pw)) return;
PriorityDump.dump(mPriorityDumper, fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
}
}
}
@@ -2213,16 +2216,18 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"gfxinfo", pw)) return;
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"gfxinfo", pw)) return;
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
}
}
}
@@ -2235,16 +2240,18 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
try {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(false);
}
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"dbinfo", pw)) return;
mActivityManagerService.dumpDbInfo(fd, pw, args);
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
"dbinfo", pw)) return;
mActivityManagerService.dumpDbInfo(fd, pw, args);
} finally {
if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
Process.enableFreezer(true);
}
}
}
}
@@ -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;
@@ -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) {