Merge "Prevent authenticators from using Settings to launch arbitrary activities." into klp-dev
diff --git a/Android.mk b/Android.mk
index 13b717a..49dc6af 100644
--- a/Android.mk
+++ b/Android.mk
@@ -433,6 +433,7 @@
non_base_dirs := \
../../external/apache-http/src/org/apache/http \
+ ../opt/telephony/src/java/android/provider \
../opt/telephony/src/java/android/telephony \
../opt/telephony/src/java/android/telephony/gsm \
../opt/net/voip/src/java/android/net/rtp \
diff --git a/api/current.txt b/api/current.txt
index 37881e6..f4f3602 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21727,6 +21727,277 @@
method public static void update(android.content.ContentProviderClient, android.net.Uri, byte[]) throws android.os.RemoteException;
}
+ public final class Telephony {
+ }
+
+ public static abstract interface Telephony.BaseMmsColumns implements android.provider.BaseColumns {
+ field public static final java.lang.String CONTENT_CLASS = "ct_cls";
+ field public static final java.lang.String CONTENT_LOCATION = "ct_l";
+ field public static final java.lang.String CONTENT_TYPE = "ct_t";
+ field public static final java.lang.String DATE = "date";
+ field public static final java.lang.String DATE_SENT = "date_sent";
+ field public static final java.lang.String DELIVERY_REPORT = "d_rpt";
+ field public static final java.lang.String DELIVERY_TIME = "d_tm";
+ field public static final java.lang.String EXPIRY = "exp";
+ field public static final java.lang.String LOCKED = "locked";
+ field public static final java.lang.String MESSAGE_BOX = "msg_box";
+ field public static final int MESSAGE_BOX_ALL = 0; // 0x0
+ field public static final int MESSAGE_BOX_DRAFTS = 3; // 0x3
+ field public static final int MESSAGE_BOX_INBOX = 1; // 0x1
+ field public static final int MESSAGE_BOX_OUTBOX = 4; // 0x4
+ field public static final int MESSAGE_BOX_SENT = 2; // 0x2
+ field public static final java.lang.String MESSAGE_CLASS = "m_cls";
+ field public static final java.lang.String MESSAGE_ID = "m_id";
+ field public static final java.lang.String MESSAGE_SIZE = "m_size";
+ field public static final java.lang.String MESSAGE_TYPE = "m_type";
+ field public static final java.lang.String MMS_VERSION = "v";
+ field public static final java.lang.String PRIORITY = "pri";
+ field public static final java.lang.String READ = "read";
+ field public static final java.lang.String READ_REPORT = "rr";
+ field public static final java.lang.String READ_STATUS = "read_status";
+ field public static final java.lang.String REPORT_ALLOWED = "rpt_a";
+ field public static final java.lang.String RESPONSE_STATUS = "resp_st";
+ field public static final java.lang.String RESPONSE_TEXT = "resp_txt";
+ field public static final java.lang.String RETRIEVE_STATUS = "retr_st";
+ field public static final java.lang.String RETRIEVE_TEXT = "retr_txt";
+ field public static final java.lang.String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
+ field public static final java.lang.String SEEN = "seen";
+ field public static final java.lang.String STATUS = "st";
+ field public static final java.lang.String SUBJECT = "sub";
+ field public static final java.lang.String SUBJECT_CHARSET = "sub_cs";
+ field public static final java.lang.String TEXT_ONLY = "text_only";
+ field public static final java.lang.String THREAD_ID = "thread_id";
+ field public static final java.lang.String TRANSACTION_ID = "tr_id";
+ }
+
+ public static abstract interface Telephony.CanonicalAddressesColumns implements android.provider.BaseColumns {
+ field public static final java.lang.String ADDRESS = "address";
+ }
+
+ public static final class Telephony.Carriers implements android.provider.BaseColumns {
+ field public static final java.lang.String APN = "apn";
+ field public static final java.lang.String AUTH_TYPE = "authtype";
+ field public static final java.lang.String BEARER = "bearer";
+ field public static final java.lang.String CARRIER_ENABLED = "carrier_enabled";
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String CURRENT = "current";
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "name ASC";
+ field public static final java.lang.String MCC = "mcc";
+ field public static final java.lang.String MMSC = "mmsc";
+ field public static final java.lang.String MMSPORT = "mmsport";
+ field public static final java.lang.String MMSPROXY = "mmsproxy";
+ field public static final java.lang.String MNC = "mnc";
+ field public static final java.lang.String MVNO_MATCH_DATA = "mvno_match_data";
+ field public static final java.lang.String MVNO_TYPE = "mvno_type";
+ field public static final java.lang.String NAME = "name";
+ field public static final java.lang.String NUMERIC = "numeric";
+ field public static final java.lang.String PASSWORD = "password";
+ field public static final java.lang.String PORT = "port";
+ field public static final java.lang.String PROTOCOL = "protocol";
+ field public static final java.lang.String PROXY = "proxy";
+ field public static final java.lang.String ROAMING_PROTOCOL = "roaming_protocol";
+ field public static final java.lang.String SERVER = "server";
+ field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String USER = "user";
+ }
+
+ public static final class Telephony.Mms implements android.provider.Telephony.BaseMmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ field public static final android.net.Uri REPORT_REQUEST_URI;
+ field public static final android.net.Uri REPORT_STATUS_URI;
+ }
+
+ public static final class Telephony.Mms.Addr implements android.provider.BaseColumns {
+ field public static final java.lang.String ADDRESS = "address";
+ field public static final java.lang.String CHARSET = "charset";
+ field public static final java.lang.String CONTACT_ID = "contact_id";
+ field public static final java.lang.String MSG_ID = "msg_id";
+ field public static final java.lang.String TYPE = "type";
+ }
+
+ public static final class Telephony.Mms.Draft implements android.provider.Telephony.BaseMmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Mms.Inbox implements android.provider.Telephony.BaseMmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Mms.Intents {
+ field public static final java.lang.String CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
+ field public static final java.lang.String DELETED_CONTENTS = "deleted_contents";
+ }
+
+ public static final class Telephony.Mms.Outbox implements android.provider.Telephony.BaseMmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Mms.Part implements android.provider.BaseColumns {
+ field public static final java.lang.String CHARSET = "chset";
+ field public static final java.lang.String CONTENT_DISPOSITION = "cd";
+ field public static final java.lang.String CONTENT_ID = "cid";
+ field public static final java.lang.String CONTENT_LOCATION = "cl";
+ field public static final java.lang.String CONTENT_TYPE = "ct";
+ field public static final java.lang.String CT_START = "ctt_s";
+ field public static final java.lang.String CT_TYPE = "ctt_t";
+ field public static final java.lang.String FILENAME = "fn";
+ field public static final java.lang.String MSG_ID = "mid";
+ field public static final java.lang.String NAME = "name";
+ field public static final java.lang.String SEQ = "seq";
+ field public static final java.lang.String TEXT = "text";
+ field public static final java.lang.String _DATA = "_data";
+ }
+
+ public static final class Telephony.Mms.Rate {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String SENT_TIME = "sent_time";
+ }
+
+ public static final class Telephony.Mms.Sent implements android.provider.Telephony.BaseMmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.MmsSms implements android.provider.BaseColumns {
+ field public static final android.net.Uri CONTENT_CONVERSATIONS_URI;
+ field public static final android.net.Uri CONTENT_DRAFT_URI;
+ field public static final android.net.Uri CONTENT_FILTER_BYPHONE_URI;
+ field public static final android.net.Uri CONTENT_LOCKED_URI;
+ field public static final android.net.Uri CONTENT_UNDELIVERED_URI;
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final int ERR_TYPE_GENERIC = 1; // 0x1
+ field public static final int ERR_TYPE_GENERIC_PERMANENT = 10; // 0xa
+ field public static final int ERR_TYPE_MMS_PROTO_PERMANENT = 12; // 0xc
+ field public static final int ERR_TYPE_MMS_PROTO_TRANSIENT = 3; // 0x3
+ field public static final int ERR_TYPE_SMS_PROTO_PERMANENT = 11; // 0xb
+ field public static final int ERR_TYPE_SMS_PROTO_TRANSIENT = 2; // 0x2
+ field public static final int ERR_TYPE_TRANSPORT_FAILURE = 4; // 0x4
+ field public static final int MMS_PROTO = 1; // 0x1
+ field public static final int NO_ERROR = 0; // 0x0
+ field public static final android.net.Uri SEARCH_URI;
+ field public static final int SMS_PROTO = 0; // 0x0
+ field public static final java.lang.String TYPE_DISCRIMINATOR_COLUMN = "transport_type";
+ }
+
+ public static final class Telephony.MmsSms.PendingMessages implements android.provider.BaseColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DUE_TIME = "due_time";
+ field public static final java.lang.String ERROR_CODE = "err_code";
+ field public static final java.lang.String ERROR_TYPE = "err_type";
+ field public static final java.lang.String LAST_TRY = "last_try";
+ field public static final java.lang.String MSG_ID = "msg_id";
+ field public static final java.lang.String MSG_TYPE = "msg_type";
+ field public static final java.lang.String PROTO_TYPE = "proto_type";
+ field public static final java.lang.String RETRY_INDEX = "retry_index";
+ }
+
+ public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+ method public static java.lang.String getDefaultSmsPackage(android.content.Context);
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Sms.Conversations implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ field public static final java.lang.String MESSAGE_COUNT = "msg_count";
+ field public static final java.lang.String SNIPPET = "snippet";
+ }
+
+ public static final class Telephony.Sms.Draft implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Sms.Inbox implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Sms.Intents {
+ method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
+ field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+ field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+ field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
+ field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
+ field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
+ field public static final int RESULT_SMS_HANDLED = 1; // 0x1
+ field public static final int RESULT_SMS_OUT_OF_MEMORY = 3; // 0x3
+ field public static final int RESULT_SMS_UNSUPPORTED = 4; // 0x4
+ field public static final java.lang.String SIM_FULL_ACTION = "android.provider.Telephony.SIM_FULL";
+ field public static final java.lang.String SMS_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_CB_RECEIVED";
+ field public static final java.lang.String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER";
+ field public static final java.lang.String SMS_EMERGENCY_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
+ field public static final java.lang.String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
+ field public static final java.lang.String SMS_REJECTED_ACTION = "android.provider.Telephony.SMS_REJECTED";
+ field public static final java.lang.String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION = "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
+ field public static final java.lang.String WAP_PUSH_DELIVER_ACTION = "android.provider.Telephony.WAP_PUSH_DELIVER";
+ field public static final java.lang.String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
+ }
+
+ public static final class Telephony.Sms.Outbox implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static final class Telephony.Sms.Sent implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+ }
+
+ public static abstract interface Telephony.TextBasedSmsColumns {
+ field public static final java.lang.String ADDRESS = "address";
+ field public static final java.lang.String BODY = "body";
+ field public static final java.lang.String DATE = "date";
+ field public static final java.lang.String DATE_SENT = "date_sent";
+ field public static final java.lang.String ERROR_CODE = "error_code";
+ field public static final java.lang.String LOCKED = "locked";
+ field public static final int MESSAGE_TYPE_ALL = 0; // 0x0
+ field public static final int MESSAGE_TYPE_DRAFT = 3; // 0x3
+ field public static final int MESSAGE_TYPE_FAILED = 5; // 0x5
+ field public static final int MESSAGE_TYPE_INBOX = 1; // 0x1
+ field public static final int MESSAGE_TYPE_OUTBOX = 4; // 0x4
+ field public static final int MESSAGE_TYPE_QUEUED = 6; // 0x6
+ field public static final int MESSAGE_TYPE_SENT = 2; // 0x2
+ field public static final java.lang.String PERSON = "person";
+ field public static final java.lang.String PROTOCOL = "protocol";
+ field public static final java.lang.String READ = "read";
+ field public static final java.lang.String REPLY_PATH_PRESENT = "reply_path_present";
+ field public static final java.lang.String SEEN = "seen";
+ field public static final java.lang.String SERVICE_CENTER = "service_center";
+ field public static final java.lang.String STATUS = "status";
+ field public static final int STATUS_COMPLETE = 0; // 0x0
+ field public static final int STATUS_FAILED = 64; // 0x40
+ field public static final int STATUS_NONE = -1; // 0xffffffff
+ field public static final int STATUS_PENDING = 32; // 0x20
+ field public static final java.lang.String SUBJECT = "subject";
+ field public static final java.lang.String THREAD_ID = "thread_id";
+ field public static final java.lang.String TYPE = "type";
+ }
+
+ public static final class Telephony.Threads implements android.provider.Telephony.ThreadsColumns {
+ field public static final int BROADCAST_THREAD = 1; // 0x1
+ field public static final int COMMON_THREAD = 0; // 0x0
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final android.net.Uri OBSOLETE_THREADS_URI;
+ }
+
+ public static abstract interface Telephony.ThreadsColumns implements android.provider.BaseColumns {
+ field public static final java.lang.String DATE = "date";
+ field public static final java.lang.String ERROR = "error";
+ field public static final java.lang.String HAS_ATTACHMENT = "has_attachment";
+ field public static final java.lang.String MESSAGE_COUNT = "message_count";
+ field public static final java.lang.String READ = "read";
+ field public static final java.lang.String RECIPIENT_IDS = "recipient_ids";
+ field public static final java.lang.String SNIPPET = "snippet";
+ field public static final java.lang.String SNIPPET_CHARSET = "snippet_cs";
+ field public static final java.lang.String TYPE = "type";
+ }
+
public class UserDictionary {
ctor public UserDictionary();
field public static final java.lang.String AUTHORITY = "user_dictionary";
diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java
index 6432a37..d32b71b 100644
--- a/core/java/android/print/PrinterDiscoverySession.java
+++ b/core/java/android/print/PrinterDiscoverySession.java
@@ -28,6 +28,7 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
/**
@@ -40,8 +41,8 @@
private static final int MSG_PRINTERS_ADDED = 1;
private static final int MSG_PRINTERS_REMOVED = 2;
- private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
- new ArrayMap<PrinterId, PrinterInfo>();
+ private final LinkedHashMap<PrinterId, PrinterInfo> mPrinters =
+ new LinkedHashMap<PrinterId, PrinterInfo>();
private final IPrintManager mPrintManager;
@@ -218,9 +219,7 @@
}
// Update printers we already have.
- final int oldPrinterCount = mPrinters.size();
- for (int i = 0; i < oldPrinterCount; i++) {
- PrinterId oldPrinterId = mPrinters.keyAt(i);
+ for (PrinterId oldPrinterId : mPrinters.keySet()) {
PrinterInfo updatedPrinter = addedPrintersMap.remove(oldPrinterId);
if (updatedPrinter != null) {
mPrinters.put(oldPrinterId, updatedPrinter);
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index a281f7c..a95bac8 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -47,6 +47,10 @@
public static final String SERVICE_NAME = "procstats";
+ // How often the service commits its data, giving the minimum batching
+ // that is done.
+ public static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours
+
public static final int STATE_NOTHING = -1;
public static final int STATE_PERSISTENT = 0;
public static final int STATE_TOP = 1;
@@ -1015,7 +1019,7 @@
pkgMap.removeAt(ip);
}
}
- mStartTime = SystemClock.uptimeMillis();
+ mStartTime = now;
if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
}
@@ -1449,7 +1453,7 @@
mReadError = "bad uid: " + uid;
return;
}
- PackageState pkgState = new PackageState(uid);
+ PackageState pkgState = new PackageState(pkgName, uid);
mPackages.put(pkgName, uid, pkgState);
int NPROCS = in.readInt();
if (NPROCS < 0) {
@@ -1620,7 +1624,7 @@
if (as != null) {
return as;
}
- as = new PackageState(uid);
+ as = new PackageState(packageName, uid);
mPackages.put(packageName, uid, as);
return as;
}
@@ -1646,11 +1650,22 @@
// but it was created for a different package than the caller.
// We need to convert it to a multi-package process.
commonProc.mMultiPackage = true;
- // The original package it was created for now needs to point
- // to its own copy.
+ // To do this, we need to make two new process states, one a copy
+ // of the current state for the process under the original package
+ // name, and the second a free new process state for it as the
+ // new package name.
long now = SystemClock.uptimeMillis();
- pkgState.mProcesses.put(commonProc.mName, commonProc.clone(
- commonProc.mPackage, now));
+ // First let's make a copy of the current process state and put
+ // that under the now unique state for its original package name.
+ final PackageState commonPkgState = getPackageStateLocked(commonProc.mPackage, uid);
+ if (commonPkgState != null) {
+ commonPkgState.mProcesses.put(commonProc.mName, commonProc.clone(
+ commonProc.mPackage, now));
+ } else {
+ Slog.w(TAG, "Cloning proc state: no package state " + commonProc.mPackage
+ + "/" + uid + " for proc " + commonProc.mName);
+ }
+ // And now make a fresh new process state for the new package name.
ps = new ProcessState(commonProc, packageName, uid, processName, now);
}
} else {
@@ -1677,6 +1692,32 @@
return ss;
}
+ private void dumpProcessInternalLocked(PrintWriter pw, String prefix, ProcessState proc,
+ boolean dumpAll) {
+ if (dumpAll) {
+ pw.print(prefix); pw.print("myID=");
+ pw.print(Integer.toHexString(System.identityHashCode(proc)));
+ pw.print(" mCommonProcess=");
+ pw.print(Integer.toHexString(System.identityHashCode(proc.mCommonProcess)));
+ pw.print(" mPackage="); pw.println(proc.mPackage);
+ if (proc.mMultiPackage) {
+ pw.print(prefix); pw.print("mMultiPackage="); pw.println(proc.mMultiPackage);
+ }
+ if (proc != proc.mCommonProcess) {
+ pw.print(prefix); pw.print("Common Proc: "); pw.print(proc.mCommonProcess.mName);
+ pw.print("/"); pw.print(proc.mCommonProcess.mUid);
+ pw.print(" pkg="); pw.println(proc.mCommonProcess.mPackage);
+ }
+ }
+ pw.print(prefix); pw.print("mActive="); pw.println(proc.mActive);
+ if (proc.mDead) {
+ pw.print(prefix); pw.print("mDead="); pw.println(proc.mDead);
+ }
+ pw.print(prefix); pw.print("mNumActiveServices="); pw.print(proc.mNumActiveServices);
+ pw.print(" mNumStartedServices=");
+ pw.println(proc.mNumStartedServices);
+ }
+
public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
boolean dumpAll) {
long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
@@ -1715,10 +1756,7 @@
ALL_PROC_STATES, now);
dumpProcessPss(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
ALL_PROC_STATES);
- pw.print(" mActive="); pw.println(proc.mActive);
- pw.print(" mNumActiveServices="); pw.print(proc.mNumActiveServices);
- pw.print(" mNumStartedServices=");
- pw.println(proc.mNumStartedServices);
+ dumpProcessInternalLocked(pw, " ", proc, dumpAll);
}
} else {
ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
@@ -1737,6 +1775,7 @@
pw.print(pkgState.mServices.keyAt(isvc));
pw.println(":");
ServiceState svc = pkgState.mServices.valueAt(isvc);
+ pw.print(" Process: "); pw.println(svc.mProcessName);
dumpServiceStats(pw, " ", " ", " ", "Running", svc,
svc.mRunCount, ServiceState.SERVICE_RUN, svc.mRunState,
svc.mRunStartTime, now, totalTime, !dumpSummary || dumpAll);
@@ -1759,16 +1798,19 @@
if (reqPackage == null) {
ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
printedHeader = false;
+ int numShownProcs = 0, numTotalProcs = 0;
for (int ip=0; ip<procMap.size(); ip++) {
String procName = procMap.keyAt(ip);
SparseArray<ProcessState> uids = procMap.valueAt(ip);
for (int iu=0; iu<uids.size(); iu++) {
int uid = uids.keyAt(iu);
+ numTotalProcs++;
ProcessState proc = uids.valueAt(iu);
if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
&& proc.mPssTableSize == 0) {
continue;
}
+ numShownProcs++;
if (!printedHeader) {
pw.println();
pw.println("Per-Process Stats:");
@@ -1783,13 +1825,15 @@
dumpProcessPss(pw, " ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
ALL_PROC_STATES);
if (dumpAll) {
- pw.print(" mActive="); pw.println(proc.mActive);
- pw.print(" mNumActiveServices="); pw.print(proc.mNumActiveServices);
- pw.print(" mNumStartedServices=");
- pw.println(proc.mNumStartedServices);
+ dumpProcessInternalLocked(pw, " ", proc, dumpAll);
}
}
}
+ if (dumpAll) {
+ pw.println();
+ pw.print(" Total procs: "); pw.print(numShownProcs);
+ pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
+ }
pw.println();
if (dumpSummary) {
@@ -1876,7 +1920,7 @@
long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
mStartTime, now);
dumpFilteredSummaryLocked(pw, null, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- NON_CACHED_PROC_STATES, now, totalTime, reqPackage);
+ ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage);
pw.println();
dumpTotalsLocked(pw, now);
}
@@ -1916,22 +1960,22 @@
}
void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
- int[] screenStates, int[] memStates, int[] procStates, long now, long totalTime,
- String reqPackage) {
+ int[] screenStates, int[] memStates, int[] procStates,
+ int[] sortProcStates, long now, long totalTime, String reqPackage) {
ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
- procStates, now, reqPackage);
+ procStates, sortProcStates, now, reqPackage);
if (procs.size() > 0) {
if (header != null) {
pw.println();
pw.println(header);
}
- dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates, procStates,
- now, totalTime);
+ dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates,
+ sortProcStates, now, totalTime);
}
}
public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
- int[] procStates, long now, String reqPackage) {
+ int[] procStates, int sortProcStates[], long now, String reqPackage) {
ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
for (int ip=0; ip<pkgMap.size(); ip++) {
@@ -1953,6 +1997,9 @@
if (computeProcessTimeLocked(proc, screenStates, memStates,
procStates, now) > 0) {
outProcs.add(proc);
+ if (procStates != sortProcStates) {
+ computeProcessTimeLocked(proc, screenStates, memStates, sortProcStates, now);
+ }
}
}
Collections.sort(outProcs, new Comparator<ProcessState>() {
@@ -2134,15 +2181,97 @@
pw.println();
}
- public static final class ProcessState {
+ public static class DurationsTable {
public final ProcessStats mStats;
+ public final String mName;
+ public int[] mDurationsTable;
+ public int mDurationsTableSize;
+
+ public DurationsTable(ProcessStats stats, String name) {
+ mStats = stats;
+ mName = name;
+ }
+
+ void copyDurationsTo(DurationsTable other) {
+ if (mDurationsTable != null) {
+ mStats.mAddLongTable = new int[mDurationsTable.length];
+ mStats.mAddLongTableSize = 0;
+ for (int i=0; i<mDurationsTableSize; i++) {
+ int origEnt = mDurationsTable[i];
+ int type = (origEnt>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+ int newOff = mStats.addLongData(i, type, 1);
+ mStats.mAddLongTable[i] = newOff | type;
+ mStats.setLong(newOff, 0, mStats.getLong(origEnt, 0));
+ }
+ other.mDurationsTable = mStats.mAddLongTable;
+ other.mDurationsTableSize = mStats.mAddLongTableSize;
+ } else {
+ other.mDurationsTable = null;
+ other.mDurationsTableSize = 0;
+ }
+ }
+
+ void addDurations(DurationsTable other) {
+ for (int i=0; i<other.mDurationsTableSize; i++) {
+ int ent = other.mDurationsTable[i];
+ int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+ if (DEBUG) Slog.d(TAG, "Adding state " + state + " duration "
+ + other.mStats.getLong(ent, 0));
+ addDuration(state, other.mStats.getLong(ent, 0));
+ }
+ }
+
+ void resetDurationsSafely() {
+ mDurationsTable = null;
+ mDurationsTableSize = 0;
+ }
+
+ void writeDurationsToParcel(Parcel out) {
+ out.writeInt(mDurationsTableSize);
+ for (int i=0; i<mDurationsTableSize; i++) {
+ if (DEBUG) Slog.i(TAG, "Writing in " + mName + " dur #" + i + ": "
+ + printLongOffset(mDurationsTable[i]));
+ out.writeInt(mDurationsTable[i]);
+ }
+ }
+
+ boolean readDurationsFromParcel(Parcel in) {
+ mDurationsTable = mStats.readTableFromParcel(in, mName, "durations");
+ if (mDurationsTable == BAD_TABLE) {
+ return false;
+ }
+ mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
+ return true;
+ }
+
+ void addDuration(int state, long dur) {
+ int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
+ int off;
+ if (idx >= 0) {
+ off = mDurationsTable[idx];
+ } else {
+ mStats.mAddLongTable = mDurationsTable;
+ mStats.mAddLongTableSize = mDurationsTableSize;
+ off = mStats.addLongData(~idx, state, 1);
+ mDurationsTable = mStats.mAddLongTable;
+ mDurationsTableSize = mStats.mAddLongTableSize;
+ }
+ long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+ if (DEBUG) Slog.d(TAG, "Duration of " + mName + " state " + state + " inc by " + dur
+ + " from " + longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK]);
+ longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += dur;
+ }
+
+ long getDuration(int state, long now) {
+ int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
+ return idx >= 0 ? mStats.getLong(mDurationsTable[idx], 0) : 0;
+ }
+ }
+
+ public static final class ProcessState extends DurationsTable {
public final ProcessState mCommonProcess;
public final String mPackage;
public final int mUid;
- public final String mName;
-
- int[] mDurationsTable;
- int mDurationsTableSize;
//final long[] mDurations = new long[STATE_COUNT*ADJ_COUNT];
int mCurState = STATE_NOTHING;
@@ -2175,11 +2304,10 @@
* a single package running in a process. The initial state is not running.
*/
public ProcessState(ProcessStats processStats, String pkg, int uid, String name) {
- mStats = processStats;
+ super(processStats, name);
mCommonProcess = this;
mPackage = pkg;
mUid = uid;
- mName = name;
}
/**
@@ -2189,30 +2317,17 @@
*/
public ProcessState(ProcessState commonProcess, String pkg, int uid, String name,
long now) {
- mStats = commonProcess.mStats;
+ super(commonProcess.mStats, name);
mCommonProcess = commonProcess;
mPackage = pkg;
mUid = uid;
- mName = name;
mCurState = commonProcess.mCurState;
mStartTime = now;
}
ProcessState clone(String pkg, long now) {
ProcessState pnew = new ProcessState(this, pkg, mUid, mName, now);
- if (mDurationsTable != null) {
- mStats.mAddLongTable = new int[mDurationsTable.length];
- mStats.mAddLongTableSize = 0;
- for (int i=0; i<mDurationsTableSize; i++) {
- int origEnt = mDurationsTable[i];
- int type = (origEnt>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- int newOff = mStats.addLongData(i, type, 1);
- mStats.mAddLongTable[i] = newOff | type;
- mStats.setLong(newOff, 0, mStats.getLong(origEnt, 0));
- }
- pnew.mDurationsTable = mStats.mAddLongTable;
- pnew.mDurationsTableSize = mStats.mAddLongTableSize;
- }
+ copyDurationsTo(pnew);
if (mPssTable != null) {
mStats.mAddLongTable = new int[mPssTable.length];
mStats.mAddLongTableSize = 0;
@@ -2240,13 +2355,7 @@
}
void add(ProcessState other) {
- for (int i=0; i<other.mDurationsTableSize; i++) {
- int ent = other.mDurationsTable[i];
- int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- if (DEBUG) Slog.d(TAG, "Adding state " + state + " duration "
- + other.mStats.getLong(ent, 0));
- addDuration(state, other.mStats.getLong(ent, 0));
- }
+ addDurations(other);
for (int i=0; i<other.mPssTableSize; i++) {
int ent = other.mPssTable[i];
int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
@@ -2267,8 +2376,7 @@
}
void resetSafely(long now) {
- mDurationsTable = null;
- mDurationsTableSize = 0;
+ resetDurationsSafely();
mStartTime = now;
mLastPssState = STATE_NOTHING;
mLastPssTime = 0;
@@ -2294,12 +2402,7 @@
void writeToParcel(Parcel out, long now) {
out.writeInt(mMultiPackage ? 1 : 0);
- out.writeInt(mDurationsTableSize);
- for (int i=0; i<mDurationsTableSize; i++) {
- if (DEBUG) Slog.i(TAG, "Writing in " + mName + " dur #" + i + ": "
- + printLongOffset(mDurationsTable[i]));
- out.writeInt(mDurationsTable[i]);
- }
+ writeDurationsToParcel(out);
out.writeInt(mPssTableSize);
for (int i=0; i<mPssTableSize; i++) {
if (DEBUG) Slog.i(TAG, "Writing in " + mName + " pss #" + i + ": "
@@ -2322,11 +2425,9 @@
mMultiPackage = multiPackage;
}
if (DEBUG) Slog.d(TAG, "Reading durations table...");
- mDurationsTable = mStats.readTableFromParcel(in, mName, "durations");
- if (mDurationsTable == BAD_TABLE) {
+ if (!readDurationsFromParcel(in)) {
return false;
}
- mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
if (DEBUG) Slog.d(TAG, "Reading pss table...");
mPssTable = mStats.readTableFromParcel(in, mName, "pss");
if (mPssTable == BAD_TABLE) {
@@ -2411,24 +2512,6 @@
mStartTime = now;
}
- void addDuration(int state, long dur) {
- int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
- int off;
- if (idx >= 0) {
- off = mDurationsTable[idx];
- } else {
- mStats.mAddLongTable = mDurationsTable;
- mStats.mAddLongTableSize = mDurationsTableSize;
- off = mStats.addLongData(~idx, state, 1);
- mDurationsTable = mStats.mAddLongTable;
- mDurationsTableSize = mStats.mAddLongTableSize;
- }
- long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- if (DEBUG) Slog.d(TAG, "Duration of " + mName + " state " + state + " inc by " + dur
- + " from " + longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK]);
- longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += dur;
- }
-
void incActiveServices() {
if (mCommonProcess != this) {
mCommonProcess.incActiveServices();
@@ -2470,7 +2553,8 @@
}
}
- public void addPss(long pss, long uss, boolean always) {
+ public void addPss(long pss, long uss, boolean always,
+ ArrayMap<String, ProcessState> pkgList) {
ensureNotDead();
if (!always) {
if (mLastPssState == mCurState && SystemClock.uptimeMillis()
@@ -2481,7 +2565,20 @@
mLastPssState = mCurState;
mLastPssTime = SystemClock.uptimeMillis();
if (mCurState != STATE_NOTHING) {
- addPss(mCurState, 1, pss, pss, pss, uss, uss, uss);
+ // First update the common process.
+ mCommonProcess.addPss(mCurState, 1, pss, pss, pss, uss, uss, uss);
+
+ // If the common process is not multi-package, there is nothing else to do.
+ if (!mCommonProcess.mMultiPackage) {
+ return;
+ }
+
+ if (pkgList != null) {
+ for (int ip=pkgList.size()-1; ip>=0; ip--) {
+ pullFixedProc(pkgList, ip).addPss(mCurState, 1,
+ pss, pss, pss, uss, uss, uss);
+ }
+ }
}
}
@@ -2632,8 +2729,7 @@
}
long getDuration(int state, long now) {
- int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
- long time = idx >= 0 ? mStats.getLong(mDurationsTable[idx], 0) : 0;
+ long time = super.getDuration(state, now);
if (mCurState == state) {
time += now - mStartTime;
}
@@ -2676,10 +2772,8 @@
}
}
- public static final class ServiceState {
- final ProcessStats mStats;
+ public static final class ServiceState extends DurationsTable {
public final String mPackage;
- public final String mName;
public final String mProcessName;
ProcessState mProc;
@@ -2691,9 +2785,6 @@
public static final int SERVICE_EXEC = 3;
static final int SERVICE_COUNT = 4;
- int[] mDurationsTable;
- int mDurationsTableSize;
-
int mRunCount;
public int mRunState = STATE_NOTHING;
long mRunStartTime;
@@ -2712,9 +2803,8 @@
public ServiceState(ProcessStats processStats, String pkg, String name,
String processName, ProcessState proc) {
- mStats = processStats;
+ super(processStats, name);
mPackage = pkg;
- mName = name;
mProcessName = processName;
mProc = proc;
}
@@ -2743,11 +2833,7 @@
}
void add(ServiceState other) {
- for (int i=0; i<other.mDurationsTableSize; i++) {
- int ent = other.mDurationsTable[i];
- int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
- addStateTime(state, other.mStats.getLong(ent, 0));
- }
+ addDurations(other);
mRunCount += other.mRunCount;
mStartedCount += other.mStartedCount;
mBoundCount += other.mBoundCount;
@@ -2755,22 +2841,16 @@
}
void resetSafely(long now) {
- mDurationsTable = null;
- mDurationsTableSize = 0;
+ resetDurationsSafely();
mRunCount = mRunState != STATE_NOTHING ? 1 : 0;
mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0;
mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0;
mExecCount = mExecState != STATE_NOTHING ? 1 : 0;
- mStartedStartTime = mBoundStartTime = mExecStartTime = now;
+ mRunStartTime = mStartedStartTime = mBoundStartTime = mExecStartTime = now;
}
void writeToParcel(Parcel out, long now) {
- out.writeInt(mDurationsTableSize);
- for (int i=0; i<mDurationsTableSize; i++) {
- if (DEBUG) Slog.i(TAG, "Writing service in " + mPackage + " dur #" + i + ": "
- + printLongOffset(mDurationsTable[i]));
- out.writeInt(mDurationsTable[i]);
- }
+ writeDurationsToParcel(out);
out.writeInt(mRunCount);
out.writeInt(mStartedCount);
out.writeInt(mBoundCount);
@@ -2778,12 +2858,9 @@
}
boolean readFromParcel(Parcel in) {
- if (DEBUG) Slog.d(TAG, "Reading durations table...");
- mDurationsTable = mStats.readTableFromParcel(in, mPackage, "service");
- if (mDurationsTable == BAD_TABLE) {
+ if (!readDurationsFromParcel(in)) {
return false;
}
- mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
mRunCount = in.readInt();
mStartedCount = in.readInt();
mBoundCount = in.readInt();
@@ -2791,40 +2868,22 @@
return true;
}
- void addStateTime(int state, long time) {
- if (time > 0) {
- int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
- int off;
- if (idx >= 0) {
- off = mDurationsTable[idx];
- } else {
- mStats.mAddLongTable = mDurationsTable;
- mStats.mAddLongTableSize = mDurationsTableSize;
- off = mStats.addLongData(~idx, state, 1);
- mDurationsTable = mStats.mAddLongTable;
- mDurationsTableSize = mStats.mAddLongTableSize;
- }
- long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
- longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += time;
- }
- }
-
void commitStateTime(long now) {
if (mRunState != STATE_NOTHING) {
- addStateTime(SERVICE_RUN + (mRunState*SERVICE_COUNT), now - mRunStartTime);
+ addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT), now - mRunStartTime);
mRunStartTime = now;
}
if (mStartedState != STATE_NOTHING) {
- addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
+ addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
now - mStartedStartTime);
mStartedStartTime = now;
}
if (mBoundState != STATE_NOTHING) {
- addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT), now - mBoundStartTime);
+ addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT), now - mBoundStartTime);
mBoundStartTime = now;
}
if (mExecState != STATE_NOTHING) {
- addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
+ addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
mExecStartTime = now;
}
}
@@ -2834,7 +2893,7 @@
|| mExecState != STATE_NOTHING) ? memFactor : STATE_NOTHING;
if (mRunState != state) {
if (mRunState != STATE_NOTHING) {
- addStateTime(SERVICE_RUN + (mRunState*SERVICE_COUNT),
+ addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT),
now - mRunStartTime);
} else if (state != STATE_NOTHING) {
mRunCount++;
@@ -2852,7 +2911,7 @@
final int state = started ? memFactor : STATE_NOTHING;
if (mStartedState != state) {
if (mStartedState != STATE_NOTHING) {
- addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
+ addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
now - mStartedStartTime);
} else if (started) {
mStartedCount++;
@@ -2878,7 +2937,7 @@
final int state = bound ? memFactor : STATE_NOTHING;
if (mBoundState != state) {
if (mBoundState != STATE_NOTHING) {
- addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
+ addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
now - mBoundStartTime);
} else if (bound) {
mBoundCount++;
@@ -2896,7 +2955,7 @@
final int state = executing ? memFactor : STATE_NOTHING;
if (mExecState != state) {
if (mExecState != STATE_NOTHING) {
- addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
+ addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
} else if (executing) {
mExecCount++;
}
@@ -2909,8 +2968,7 @@
private long getDuration(int opType, int curState, long startTime, int memFactor,
long now) {
int state = opType + (memFactor*SERVICE_COUNT);
- int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
- long time = idx >= 0 ? mStats.getLong(mDurationsTable[idx], 0) : 0;
+ long time = getDuration(state, now);
if (curState == memFactor) {
time += now - startTime;
}
@@ -2923,10 +2981,12 @@
= new ArrayMap<String, ProcessState>();
public final ArrayMap<String, ServiceState> mServices
= new ArrayMap<String, ServiceState>();
- final int mUid;
+ public final String mPackageName;
+ public final int mUid;
- public PackageState(int uid) {
+ public PackageState(String packageName, int uid) {
mUid = uid;
+ mPackageName = packageName;
}
}
@@ -2951,6 +3011,9 @@
}
void print(PrintWriter pw, long overallTime, boolean full) {
+ if (totalTime > overallTime) {
+ pw.print("*");
+ }
printPercent(pw, (double) totalTime / (double) overallTime);
if (numPss > 0) {
pw.print(" (");
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 15792e8..62f057f 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -156,31 +156,32 @@
* Uses libmemtrack to retrieve graphics memory that the process is using.
* Any graphics memory reported in /proc/pid/smaps is not included here.
*/
-static int read_memtrack_memory(struct memtrack_proc* p, int pid, struct graphics_memory_pss* graphics_mem)
+static int read_memtrack_memory(struct memtrack_proc* p, int pid,
+ struct graphics_memory_pss* graphics_mem)
{
int err = memtrack_proc_get(p, pid);
if (err != 0) {
- ALOGE("failed to get memory consumption info: %d", err);
+ ALOGW("failed to get memory consumption info: %d", err);
return err;
}
ssize_t pss = memtrack_proc_graphics_pss(p);
if (pss < 0) {
- ALOGE("failed to get graphics pss: %d", pss);
+ ALOGW("failed to get graphics pss: %d", pss);
return pss;
}
graphics_mem->graphics = pss / 1024;
pss = memtrack_proc_gl_pss(p);
if (pss < 0) {
- ALOGE("failed to get gl pss: %d", pss);
+ ALOGW("failed to get gl pss: %d", pss);
return pss;
}
graphics_mem->gl = pss / 1024;
pss = memtrack_proc_other_pss(p);
if (pss < 0) {
- ALOGE("failed to get other pss: %d", pss);
+ ALOGW("failed to get other pss: %d", pss);
return pss;
}
graphics_mem->other = pss / 1024;
@@ -199,7 +200,7 @@
struct memtrack_proc* p = memtrack_proc_new();
if (p == NULL) {
- ALOGE("failed to create memtrack_proc");
+ ALOGW("failed to create memtrack_proc");
return -1;
}
@@ -418,8 +419,6 @@
stats[HEAP_GL].privateDirty = graphics_mem.gl;
stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other;
stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other;
- } else {
- ALOGE("Failed to read gpu memory");
}
for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) {
@@ -623,7 +622,7 @@
close(fd);
if (len > 0) {
buffer[len] = 0;
- mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer);
+ mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer)/1024;
}
}
@@ -633,7 +632,7 @@
}
jlong* outArray = env->GetLongArrayElements(out, 0);
if (outArray != NULL) {
- for (int i=0; i<maxNum && tags[i]; i++) {
+ for (int i=0; i<maxNum; i++) {
outArray[i] = mem[i];
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 49777d4..932fe20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -123,7 +123,7 @@
protected int mCurrentUserId = 0;
- protected int mLayoutDirection;
+ protected int mLayoutDirection = -1; // invalid
private Locale mLocale;
protected boolean mUseHeadsUp = false;
@@ -299,8 +299,6 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mBroadcastReceiver, filter);
-
- mLocale = mContext.getResources().getConfiguration().locale;
}
public void userSwitched(int newUserId) {
@@ -320,11 +318,17 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
- final Locale newLocale = mContext.getResources().getConfiguration().locale;
- if (! newLocale.equals(mLocale)) {
- mLocale = newLocale;
- mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
- refreshLayout(mLayoutDirection);
+ final Locale locale = mContext.getResources().getConfiguration().locale;
+ final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
+ if (! locale.equals(mLocale) || ld != mLayoutDirection) {
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection,
+ locale, ld));
+ }
+ mLocale = locale;
+ mLayoutDirection = ld;
+ refreshLayout(ld);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java b/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
index ecf7b35..16fe1aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.content.res.Configuration;
import android.provider.Settings;
import android.util.Log;
@@ -70,6 +71,13 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ if (mStatusBar != null) {
+ mStatusBar.onConfigurationChanged(newConfig);
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mStatusBar != null) {
mStatusBar.dump(fd, pw, args);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index fbc94b1..c47d0eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -38,6 +38,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Canvas;
@@ -633,7 +634,6 @@
// receive broadcasts
IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
@@ -2433,17 +2433,6 @@
notifyNavigationBarScreenOn(false);
notifyHeadsUpScreenOn(false);
}
- else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
- if (DEBUG) {
- Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
- }
- mDisplay.getSize(mCurrentDisplaySize);
-
- updateResources();
- repositionNavigationBar();
- updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
- updateShowSearchHoldoff();
- }
else if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenOn = true;
// work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
@@ -2466,6 +2455,22 @@
}
};
+ // SystemUIService notifies SystemBars of configuration changes, which then calls down here
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig); // calls refreshLayout
+
+ if (DEBUG) {
+ Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
+ }
+ mDisplay.getSize(mCurrentDisplaySize);
+
+ updateResources();
+ repositionNavigationBar();
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+ updateShowSearchHoldoff();
+ }
+
@Override
public void userSwitched(int newUserId) {
if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a14d729..ddb6d1a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1689,7 +1689,7 @@
&& proc.pid == pid) {
num++;
proc.lastPssTime = SystemClock.uptimeMillis();
- proc.baseProcessTracker.addPss(pss, tmp[0], true);
+ proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
+ ": " + pss + " lastPss=" + proc.lastPss
+ " state=" + ProcessList.makeProcStateString(procState));
@@ -2705,18 +2705,6 @@
return intent;
}
- String getHomePackageName() {
- Intent intent = getHomeIntent();
- ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, mCurrentUserId);
- if (aInfo != null) {
- final String homePackageName = aInfo.applicationInfo.packageName;
- if (!ResolverActivity.class.getName().equals(homePackageName)) {
- return homePackageName;
- }
- }
- return null;
- }
-
boolean startHomeActivityLocked(int userId) {
if (mHeadless) {
// Added because none of the other calls to ensureBootCompleted seem to fire
@@ -4278,7 +4266,7 @@
if (proc.thread != null && proc.setAdj == oomAdj) {
// Record this for posterity if the process has been stable.
proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
- infos[i].getTotalUss(), false);
+ infos[i].getTotalUss(), false, proc.pkgList);
}
}
}
@@ -4305,7 +4293,7 @@
synchronized (this) {
if (proc.thread != null && proc.setAdj == oomAdj) {
// Record this for posterity if the process has been stable.
- proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false);
+ proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
}
}
}
@@ -6786,6 +6774,10 @@
// Kill the running processes.
for (int i=0; i<procs.size(); i++) {
ProcessRecord pr = procs.get(i);
+ if (pr == mHomeProcess) {
+ // Don't kill the home process along with tasks from the same package.
+ continue;
+ }
if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
killUnneededProcessLocked(pr, "remove task");
} else {
@@ -11748,7 +11740,7 @@
synchronized (this) {
if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
// Record this for posterity if the process has been stable.
- r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true);
+ r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
}
}
@@ -11909,7 +11901,7 @@
if (memInfo.getZramTotalSizeKb() != 0) {
if (!isCompact) {
pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
- pw.print(" kB used for ");
+ pw.print(" kB physical used for ");
pw.print(memInfo.getSwapTotalSizeKb()
- memInfo.getSwapFreeSizeKb());
pw.print(" kB in swap (");
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 4359895..2c0b83b 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -58,6 +58,7 @@
final class ActivityRecord {
static final String TAG = ActivityManagerService.TAG;
static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE;
+ final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recent";
final ActivityManagerService service; // owner
final IApplicationToken.Stub appToken; // window manager token
@@ -443,25 +444,18 @@
noDisplay = ent != null && ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
- // If we know the system has determined the component, then
- // we can consider this to be a home activity...
- String homePackageName = supervisor.getHomePackageName();
- if (homePackageName != null && homePackageName.equals(packageName)) {
- mActivityType = HOME_ACTIVITY_TYPE;
- } else if ((!_componentSpecified || _launchedFromUid == Process.myUid()
+ if ((!_componentSpecified || _launchedFromUid == Process.myUid()
|| _launchedFromUid == 0) &&
Intent.ACTION_MAIN.equals(_intent.getAction()) &&
_intent.hasCategory(Intent.CATEGORY_HOME) &&
_intent.getCategories().size() == 1 &&
_intent.getData() == null &&
_intent.getType() == null &&
- (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+ (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
+ isNotResolverActivity()) {
// This sure looks like a home activity!
mActivityType = HOME_ACTIVITY_TYPE;
- if (isNotResolverActivity()) {
- supervisor.setHomePackageName(userId, packageName);
- }
- } else if (realActivity.getClassName().contains("com.android.systemui.recent")) {
+ } else if (realActivity.getClassName().contains(RECENTS_PACKAGE_NAME)) {
mActivityType = RECENTS_ACTIVITY_TYPE;
} else {
mActivityType = APPLICATION_ACTIVITY_TYPE;
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index bf91904..f718706 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -203,12 +203,6 @@
*/
final PowerManager.WakeLock mGoingToSleep;
- /**
- * The name of the current home activity for each user.
- * TODO: Remove entries when user is deleted.
- */
- final SparseArray<String> mHomePackageNames = new SparseArray<String>();
-
public ActivityStackSupervisor(ActivityManagerService service, Context context,
Looper looper) {
mService = service;
@@ -2285,11 +2279,6 @@
boolean switchUserLocked(int userId, UserStartedState uss) {
mCurrentUser = userId;
- final String homePackageName = mService.getHomePackageName();
- if (homePackageName != null) {
- setHomePackageName(mCurrentUser, homePackageName);
- }
-
mStartingUsers.add(uss);
boolean haveActivities = false;
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -2391,12 +2380,6 @@
pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
- pw.print(prefix); pw.print("mHomePackageNames:");
- for (int i = 0; i < mHomePackageNames.size(); ++i) {
- pw.print(" ("); pw.print(mHomePackageNames.keyAt(i)); pw.print(",");
- pw.print(mHomePackageNames.valueAt(i)); pw.print(")");
- }
- pw.println();
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
@@ -2653,14 +2636,4 @@
}
}
}
-
- String getHomePackageName() {
- return mHomePackageNames.get(mCurrentUser);
- }
-
- void setHomePackageName(int userId, String homePackageName) {
- if (DEBUG_SWITCH) Slog.d(TAG, "setHomePackageName: user=" + userId + " package="
- + homePackageName);
- mHomePackageNames.put(userId, homePackageName);
- }
}
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index be08973..2c49bb9 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -61,7 +61,6 @@
static final String STATE_FILE_SUFFIX = ".bin"; // Suffix to use for state filenames.
static final String STATE_FILE_CHECKIN_SUFFIX = ".ci"; // State files that have checked in.
static long WRITE_PERIOD = 30*60*1000; // Write file every 30 minutes or so.
- static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours.
final ActivityManagerService mAm;
final File mBaseDir;
@@ -160,7 +159,7 @@
public boolean shouldWriteNowLocked(long now) {
if (now > (mLastWriteTime+WRITE_PERIOD)) {
if (SystemClock.elapsedRealtime()
- > (mProcessStats.mTimePeriodStartRealtime+COMMIT_PERIOD)) {
+ > (mProcessStats.mTimePeriodStartRealtime+ProcessStats.COMMIT_PERIOD)) {
mCommitPending = true;
}
return true;
@@ -358,7 +357,7 @@
boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
boolean sepProcStates, int[] procStates, long now, String reqPackage) {
ArrayList<ProcessStats.ProcessState> procs = mProcessStats.collectProcessesLocked(
- screenStates, memStates, procStates, now, reqPackage);
+ screenStates, memStates, procStates, procStates, now, reqPackage);
if (procs.size() > 0) {
if (header != null) {
pw.println(header);
@@ -457,7 +456,7 @@
if (curTime < minTime) {
// Need to add in older stats to reach desired time.
ArrayList<String> files = getCommittedFiles(0, false, true);
- if (files.size() > 0) {
+ if (files != null && files.size() > 0) {
current.setDataPosition(0);
ProcessStats stats = ProcessStats.CREATOR.createFromParcel(current);
current.recycle();
@@ -520,7 +519,7 @@
static private void dumpHelp(PrintWriter pw) {
pw.println("Process stats (procstats) dump options:");
pw.println(" [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
- pw.println(" [--details] [--full-details] [--current] [--one-day]");
+ pw.println(" [--details] [--full-details] [--current] [--hours]");
pw.println(" [--commit] [--reset] [--clear] [--write] [-h] [<package.name>]");
pw.println(" --checkin: perform a checkin: print and delete old committed states.");
pw.println(" --c: print only state in checkin format.");
@@ -532,7 +531,7 @@
pw.println(" --details: dump all execution details, not just summary.");
pw.println(" --full-details: dump only detail information, for all saved state.");
pw.println(" --current: only dump current state.");
- pw.println(" --one-day: dump stats aggregated across about one day.");
+ pw.println(" --hours: aggregate over about N last hours.");
pw.println(" --commit: commit current stats to disk and reset to start new stats.");
pw.println(" --reset: reset current stats, without committing.");
pw.println(" --clear: clear all stats; does both --reset and deletes old stats.");
@@ -562,7 +561,7 @@
boolean dumpDetails = false;
boolean dumpFullDetails = false;
boolean dumpAll = false;
- boolean oneDay = false;
+ int aggregateHours = 0;
String reqPackage = null;
boolean csvSepScreenStats = false;
int[] csvScreenStats = new int[] { ProcessStats.ADJ_SCREEN_OFF, ProcessStats.ADJ_SCREEN_ON};
@@ -632,8 +631,20 @@
dumpDetails = true;
} else if ("--full-details".equals(arg)) {
dumpFullDetails = true;
- } else if ("--one-day".equals(arg)) {
- oneDay = true;
+ } else if ("--hours".equals(arg)) {
+ i++;
+ if (i >= args.length) {
+ pw.println("Error: argument required for --hours");
+ dumpHelp(pw);
+ return;
+ }
+ try {
+ aggregateHours = Integer.parseInt(args[i]);
+ } catch (NumberFormatException e) {
+ pw.println("Error: --hours argument not an int -- " + args[i]);
+ dumpHelp(pw);
+ return;
+ }
} else if ("--current".equals(arg)) {
currentOnly = true;
} else if ("--commit".equals(arg)) {
@@ -750,8 +761,9 @@
*/
}
return;
- } else if (oneDay) {
- ParcelFileDescriptor pfd = getStatsOverTime(24*60*60*1000);
+ } else if (aggregateHours != 0) {
+ ParcelFileDescriptor pfd = getStatsOverTime(aggregateHours*60*60*1000
+ - (ProcessStats.COMMIT_PERIOD/2));
if (pfd == null) {
pw.println("Unable to build stats!");
return;
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 8a9324c..385253e 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -428,6 +428,7 @@
pw.print(prefix); pw.print("numActivities="); pw.print(numActivities);
pw.print(" rootWasReset="); pw.print(rootWasReset);
pw.print(" userId="); pw.print(userId);
+ pw.print(" mTaskType="); pw.print(mTaskType);
pw.print(" numFullscreen="); pw.print(numFullscreen);
pw.print(" mOnTopOfHome="); pw.println(mOnTopOfHome);
}
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index beeb899..2798104 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -162,6 +162,7 @@
void moveStack(TaskStack stack, boolean toTop) {
mStackHistory.remove(stack);
mStackHistory.add(toTop ? mStackHistory.size() : 0, stack);
+ mService.moveStackWindowsLocked(stack);
}
public boolean isPrivate() {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 680b44e..80c50cc 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4715,7 +4715,7 @@
}
}
- private void moveStackWindowsLocked(TaskStack stack) {
+ void moveStackWindowsLocked(TaskStack stack) {
DisplayContent displayContent = stack.getDisplayContent();
// First remove all of the windows from the list.
@@ -4782,7 +4782,6 @@
}
stack.moveTaskToTop(task);
displayContent.moveStack(stack, true);
- moveStackWindowsLocked(stack);
}
} finally {
Binder.restoreCallingIdentity(origId);