summaryrefslogtreecommitdiff
path: root/services/java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-06-11 14:26:53 -0700
committerDianne Hackborn <hackbod@google.com>2013-06-11 14:26:53 -0700
commitcbfd23ee6f14445c3e17c5169abbc80c216fa137 (patch)
tree9e5063fe418c4df345b371a0678faa4a1fcb0c48 /services/java
parentbe4e6aaa0252dd7da28b7aa85beba982538efa46 (diff)
Add new API to retrieve a dumpsys of a single package.
Adds a platform API, and pm command. Fixes some issues with dumping per-package data in package manager, makes battery stats able to dump per-package state. Change-Id: I76ee6d059f0ba17f7a7061886792b1b716d46d2d
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/am/ActiveServices.java1
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java1
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java1
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java20
-rw-r--r--services/java/com/android/server/am/ProviderMap.java1
-rw-r--r--services/java/com/android/server/am/TransferPipe.java242
-rw-r--r--services/java/com/android/server/pm/KeySetManager.java44
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java32
-rw-r--r--services/java/com/android/server/pm/Settings.java10
9 files changed, 79 insertions, 273 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 98c43521208e..a5d64b2c89de 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -27,6 +27,7 @@ import java.util.Iterator;
import java.util.List;
import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.TransferPipe;
import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.am.ActivityManagerService.NeededUriGrants;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f06b9a62fc78..fc3183f401cf 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -32,6 +32,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessStats;
+import com.android.internal.os.TransferPipe;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.AppOpsService;
import com.android.server.AttributeCache;
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index af61bfb5802f..6fe28f4c884e 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -69,6 +69,7 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.app.HeavyWeightSwitcherActivity;
+import com.android.internal.os.TransferPipe;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.StackBox;
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 5a15f0bb8846..f143feb83363 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -27,6 +27,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.os.WorkSource;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
@@ -479,12 +480,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
private void dumpHelp(PrintWriter pw) {
pw.println("Battery stats (batteryinfo) dump options:");
- pw.println(" [--checkin] [--unplugged] [--reset] [--write] [-h]");
+ pw.println(" [--checkin] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
pw.println(" --checkin: format output for a checkin report.");
pw.println(" --unplugged: only output data since last unplugged.");
pw.println(" --reset: reset the stats, clearing all current data.");
pw.println(" --write: force write current collected stats to disk.");
pw.println(" -h: print this help text.");
+ pw.println(" <package.name>: optional name of package to filter output by.");
}
@Override
@@ -500,6 +502,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
boolean isCheckin = false;
boolean isUnpluggedOnly = false;
boolean noOutput = false;
+ int reqUid = -1;
if (args != null) {
for (String arg : args) {
if ("--checkin".equals(arg)) {
@@ -523,9 +526,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
return;
} else if ("-a".equals(arg)) {
// fall through
- } else {
+ } else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg);
dumpHelp(pw);
+ return;
+ } else {
+ // Not an option, last argument must be a package name.
+ try {
+ reqUid = mContext.getPackageManager().getPackageUid(arg,
+ UserHandle.getCallingUserId());
+ } catch (PackageManager.NameNotFoundException e) {
+ pw.println("Unknown package: " + arg);
+ dumpHelp(pw);
+ return;
+ }
}
}
}
@@ -539,7 +553,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
} else {
synchronized (mStats) {
- mStats.dumpLocked(pw, isUnpluggedOnly);
+ mStats.dumpLocked(pw, isUnpluggedOnly, reqUid);
}
}
}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 5759a4485e80..7da8c48dea35 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -22,6 +22,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.os.TransferPipe;
import java.io.FileDescriptor;
import java.io.IOException;
diff --git a/services/java/com/android/server/am/TransferPipe.java b/services/java/com/android/server/am/TransferPipe.java
deleted file mode 100644
index 055c577316fe..000000000000
--- a/services/java/com/android/server/am/TransferPipe.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.am;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Slog;
-
-/**
- * Helper for transferring data through a pipe from a client app.
- */
-final class TransferPipe implements Runnable {
- static final String TAG = "TransferPipe";
- static final boolean DEBUG = false;
-
- static final long DEFAULT_TIMEOUT = 5000; // 5 seconds
-
- final Thread mThread;;
- final ParcelFileDescriptor[] mFds;
-
- FileDescriptor mOutFd;
- long mEndTime;
- String mFailure;
- boolean mComplete;
-
- String mBufferPrefix;
-
- interface Caller {
- void go(IInterface iface, FileDescriptor fd, String prefix,
- String[] args) throws RemoteException;
- }
-
- TransferPipe() throws IOException {
- mThread = new Thread(this, "TransferPipe");
- mFds = ParcelFileDescriptor.createPipe();
- }
-
- ParcelFileDescriptor getReadFd() {
- return mFds[0];
- }
-
- ParcelFileDescriptor getWriteFd() {
- return mFds[1];
- }
-
- void setBufferPrefix(String prefix) {
- mBufferPrefix = prefix;
- }
-
- static void go(Caller caller, IInterface iface, FileDescriptor out,
- String prefix, String[] args) throws IOException, RemoteException {
- go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
- }
-
- static void go(Caller caller, IInterface iface, FileDescriptor out,
- String prefix, String[] args, long timeout) throws IOException, RemoteException {
- if ((iface.asBinder()) instanceof Binder) {
- // This is a local object... just call it directly.
- try {
- caller.go(iface, out, prefix, args);
- } catch (RemoteException e) {
- }
- return;
- }
-
- TransferPipe tp = new TransferPipe();
- try {
- caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
- tp.go(out, timeout);
- } finally {
- tp.kill();
- }
- }
-
- static void goDump(IBinder binder, FileDescriptor out,
- String[] args) throws IOException, RemoteException {
- goDump(binder, out, args, DEFAULT_TIMEOUT);
- }
-
- static void goDump(IBinder binder, FileDescriptor out,
- String[] args, long timeout) throws IOException, RemoteException {
- if (binder instanceof Binder) {
- // This is a local object... just call it directly.
- try {
- binder.dump(out, args);
- } catch (RemoteException e) {
- }
- return;
- }
-
- TransferPipe tp = new TransferPipe();
- try {
- binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
- tp.go(out, timeout);
- } finally {
- tp.kill();
- }
- }
-
- void go(FileDescriptor out) throws IOException {
- go(out, DEFAULT_TIMEOUT);
- }
-
- void go(FileDescriptor out, long timeout) throws IOException {
- try {
- synchronized (this) {
- mOutFd = out;
- mEndTime = SystemClock.uptimeMillis() + timeout;
-
- if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd()
- + " out=" + out);
-
- // Close the write fd, so we know when the other side is done.
- closeFd(1);
-
- mThread.start();
-
- while (mFailure == null && !mComplete) {
- long waitTime = mEndTime - SystemClock.uptimeMillis();
- if (waitTime <= 0) {
- if (DEBUG) Slog.i(TAG, "TIMEOUT!");
- mThread.interrupt();
- throw new IOException("Timeout");
- }
-
- try {
- wait(waitTime);
- } catch (InterruptedException e) {
- }
- }
-
- if (DEBUG) Slog.i(TAG, "Finished: " + mFailure);
- if (mFailure != null) {
- throw new IOException(mFailure);
- }
- }
- } finally {
- kill();
- }
- }
-
- void closeFd(int num) {
- if (mFds[num] != null) {
- if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]);
- try {
- mFds[num].close();
- } catch (IOException e) {
- }
- mFds[num] = null;
- }
- }
-
- void kill() {
- closeFd(0);
- closeFd(1);
- }
-
- @Override
- public void run() {
- final byte[] buffer = new byte[1024];
- final FileInputStream fis = new FileInputStream(getReadFd().getFileDescriptor());
- final FileOutputStream fos = new FileOutputStream(mOutFd);
-
- if (DEBUG) Slog.i(TAG, "Ready to read pipe...");
- byte[] bufferPrefix = null;
- boolean needPrefix = true;
- if (mBufferPrefix != null) {
- bufferPrefix = mBufferPrefix.getBytes();
- }
-
- int size;
- try {
- while ((size=fis.read(buffer)) > 0) {
- if (DEBUG) Slog.i(TAG, "Got " + size + " bytes");
- if (bufferPrefix == null) {
- fos.write(buffer, 0, size);
- } else {
- int start = 0;
- for (int i=0; i<size; i++) {
- if (buffer[i] != '\n') {
- if (i > start) {
- fos.write(buffer, start, i-start);
- }
- start = i;
- if (needPrefix) {
- fos.write(bufferPrefix);
- needPrefix = false;
- }
- do {
- i++;
- } while (i<size && buffer[i] != '\n');
- if (i < size) {
- needPrefix = true;
- }
- }
- }
- if (size > start) {
- fos.write(buffer, start, size-start);
- }
- }
- }
- if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size);
- if (mThread.isInterrupted()) {
- if (DEBUG) Slog.i(TAG, "Interrupted!");
- }
- } catch (IOException e) {
- synchronized (this) {
- mFailure = e.toString();
- notifyAll();
- return;
- }
- }
-
- synchronized (this) {
- mComplete = true;
- notifyAll();
- }
- }
-}
diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/java/com/android/server/pm/KeySetManager.java
index f154ab3a0d88..8272c1579768 100644
--- a/services/java/com/android/server/pm/KeySetManager.java
+++ b/services/java/com/android/server/pm/KeySetManager.java
@@ -399,24 +399,50 @@ public class KeySetManager {
return new String(Base64.encode(k.getEncoded(), 0));
}
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, String packageName,
+ PackageManagerService.DumpState dumpState) {
synchronized (mLockObject) {
- pw.println(" Dumping KeySetManager");
+ boolean printedHeader = false;
for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) {
- String packageName = e.getKey();
+ String keySetPackage = e.getKey();
+ if (packageName != null && !packageName.equals(keySetPackage)) {
+ continue;
+ }
+ if (!printedHeader) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Key Set Manager:");
+ printedHeader = true;
+ }
PackageSetting pkg = e.getValue();
- pw.print(" ["); pw.print(packageName); pw.println("]");
+ pw.print(" ["); pw.print(keySetPackage); pw.println("]");
if (pkg.keySetData != null) {
- pw.print(" Defined KeySets:");
+ boolean printedLabel = false;
for (long keySetId : pkg.keySetData.getDefinedKeySets()) {
- pw.print(" "); pw.print(Long.toString(keySetId));
+ if (!printedLabel) {
+ pw.print(" Defined KeySets: ");
+ printedLabel = true;
+ } else {
+ pw.print(", ");
+ }
+ pw.print(Long.toString(keySetId));
+ }
+ if (printedLabel) {
+ pw.println("");
}
- pw.println("");
- pw.print(" Signing KeySets:");
+ printedLabel = false;
for (long keySetId : pkg.keySetData.getSigningKeySets()) {
+ if (!printedLabel) {
+ pw.print(" Signing KeySets:");
+ printedLabel = true;
+ } else {
+ pw.print(", ");
+ }
pw.print(" "); pw.print(Long.toString(keySetId));
}
- pw.println("");
+ if (printedLabel) {
+ pw.println("");
+ }
}
}
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 07805f9d35c5..5e6e0553c3a1 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -10041,6 +10041,9 @@ public class PackageManagerService extends IPackageManager.Stub {
// Is this a package name?
if ("android".equals(cmd) || cmd.contains(".")) {
packageName = cmd;
+ // When dumping a single package, we always dump all of its
+ // filter information since the amount of data will be reasonable.
+ dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
} else if ("l".equals(cmd) || "libraries".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_LIBS);
} else if ("f".equals(cmd) || "features".equals(cmd)) {
@@ -10076,7 +10079,7 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Verifiers:");
pw.print(" Required: ");
pw.print(mRequiredVerifierPackage);
@@ -10086,16 +10089,20 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
- if (dumpState.onTitlePrinted())
- pw.println(" ");
- pw.println("Libraries:");
+ boolean printedHeader = false;
final Iterator<String> it = mSharedLibraries.keySet().iterator();
while (it.hasNext()) {
String name = it.next();
+ SharedLibraryEntry ent = mSharedLibraries.get(name);
+ if (!printedHeader) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Libraries:");
+ printedHeader = true;
+ }
pw.print(" ");
pw.print(name);
pw.print(" -> ");
- SharedLibraryEntry ent = mSharedLibraries.get(name);
if (ent.path != null) {
pw.print("(jar) ");
pw.print(ent.path);
@@ -10109,7 +10116,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Features:");
Iterator<String> it = mAvailableFeatures.keySet().iterator();
while (it.hasNext()) {
@@ -10185,7 +10192,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Registered ContentProviders:");
printedSomething = true;
}
@@ -10200,7 +10207,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("ContentProvider Authorities:");
printedSomething = true;
}
@@ -10214,10 +10221,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
- if (dumpState.onTitlePrinted()) {
- pw.println(" ");
- }
- mSettings.mKeySetManager.dump(pw);
+ mSettings.mKeySetManager.dump(pw, packageName, dumpState);
}
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
@@ -10230,10 +10234,10 @@ public class PackageManagerService extends IPackageManager.Stub {
if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
mSettings.dumpReadMessagesLPr(pw, dumpState);
- pw.println(" ");
+ pw.println();
pw.println("Package warning messages:");
final File fname = getSettingsProblemFile();
FileInputStream in = null;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index a9c2ea17c174..b7810ba8d75a 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -2893,7 +2893,7 @@ final class Settings {
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Packages:");
printedSomething = true;
}
@@ -2909,7 +2909,7 @@ final class Settings {
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Renamed packages:");
printedSomething = true;
}
@@ -2929,7 +2929,7 @@ final class Settings {
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Hidden system packages:");
printedSomething = true;
}
@@ -2946,7 +2946,7 @@ final class Settings {
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Permissions:");
printedSomething = true;
}
@@ -2980,7 +2980,7 @@ final class Settings {
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
- pw.println(" ");
+ pw.println();
pw.println("Shared users:");
printedSomething = true;
}