summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-09-04 18:31:29 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-09-04 18:31:29 -0700
commitec4f5ed1a95bd26e68766252f19c407b1479bb83 (patch)
treefe7ebd9914dc30432f3b95b1d5aa89dc19f3ed70 /src/com/android
parent8ed62da68b1682245e2c8d093c96a6a3f169679a (diff)
parentdd600b603d98e28219a9a38a62f2527db05736bb (diff)
downloadpackages_apps_Settings-ec4f5ed1a95bd26e68766252f19c407b1479bb83.zip
packages_apps_Settings-ec4f5ed1a95bd26e68766252f19c407b1479bb83.tar.gz
packages_apps_Settings-ec4f5ed1a95bd26e68766252f19c407b1479bb83.tar.bz2
am dd600b60: Merge "Add details screen to proc stats." into klp-dev
* commit 'dd600b603d98e28219a9a38a62f2527db05736bb': Add details screen to proc stats.
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/settings/applications/ProcStatsEntry.java214
-rw-r--r--src/com/android/settings/applications/ProcessStatsDetail.java258
-rw-r--r--src/com/android/settings/applications/ProcessStatsPreference.java8
-rw-r--r--src/com/android/settings/applications/ProcessStatsUi.java120
4 files changed, 484 insertions, 116 deletions
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
index e180205..cbbfbb7 100644
--- a/src/com/android/settings/applications/ProcStatsEntry.java
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -16,11 +16,22 @@
package com.android.settings.applications;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.app.ProcessStats;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public final class ProcStatsEntry implements Parcelable {
+ private static final String TAG = "ProcStatsEntry";
-public final class ProcStatsEntry {
final String mPackage;
final int mUid;
final String mName;
@@ -29,7 +40,14 @@ public final class ProcStatsEntry {
final long mAvgPss;
final long mWeight;
- ArrayList<Service> mServices;
+ String mBestTargetPackage;
+
+ ArrayList<Service> mServices = new ArrayList<Service>(2);
+
+ public ApplicationInfo mUiTargetApp;
+ public String mUiLabel;
+ public String mUiBaseLabel;
+ public String mUiPackage;
public ProcStatsEntry(ProcessStats.ProcessState proc,
ProcessStats.ProcessDataCollection tmpTotals) {
@@ -43,18 +61,156 @@ public final class ProcStatsEntry {
mWeight = mDuration * mAvgPss;
}
+ public ProcStatsEntry(Parcel in) {
+ mPackage = in.readString();
+ mUid = in.readInt();
+ mName = in.readString();
+ mUnique = in.readInt() != 0;
+ mDuration = in.readLong();
+ mAvgPss = in.readLong();
+ mWeight = in.readLong();
+ mBestTargetPackage = in.readString();
+ in.readTypedList(mServices, Service.CREATOR);
+ }
+
+ public void evaluateTargetPackage(ProcessStats stats,
+ ProcessStats.ProcessDataCollection totals, Comparator<ProcStatsEntry> compare) {
+ mBestTargetPackage = null;
+ if (mUnique) {
+ mBestTargetPackage = mPackage;
+ addServices(stats.getPackageStateLocked(mPackage, mUid));
+ } else {
+ // See if there is one significant package that was running here.
+ ArrayList<ProcStatsEntry> subProcs = new ArrayList<ProcStatsEntry>();
+ for (int ipkg=0, NPKG=stats.mPackages.getMap().size(); ipkg<NPKG; ipkg++) {
+ SparseArray<ProcessStats.PackageState> uids
+ = stats.mPackages.getMap().valueAt(ipkg);
+ for (int iu=0, NU=uids.size(); iu<NU; iu++) {
+ if (uids.keyAt(iu) != mUid) {
+ continue;
+ }
+ ProcessStats.PackageState pkgState = uids.valueAt(iu);
+ boolean match = false;
+ for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
+ ProcessStats.ProcessState subProc =
+ pkgState.mProcesses.valueAt(iproc);
+ if (subProc.mName.equals(mName)) {
+ match = true;
+ subProcs.add(new ProcStatsEntry(subProc, totals));
+ }
+ }
+ if (match) {
+ addServices(stats.getPackageStateLocked(mPackage, mUid));
+ }
+ }
+ }
+ if (subProcs.size() > 1) {
+ Collections.sort(subProcs, compare);
+ if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
+ mBestTargetPackage = subProcs.get(0).mPackage;
+ }
+ }
+ }
+ }
+
+ public void retrieveUiData(PackageManager pm) {
+ mUiTargetApp = null;
+ mUiLabel = mUiBaseLabel = mName;
+ mUiPackage = mBestTargetPackage;
+ if (mUiPackage != null) {
+ // Only one app associated with this process.
+ try {
+ mUiTargetApp = pm.getApplicationInfo(mUiPackage,
+ PackageManager.GET_DISABLED_COMPONENTS |
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ String name = mUiBaseLabel = mUiTargetApp.loadLabel(pm).toString();
+ if (mName.equals(mUiPackage)) {
+ mUiLabel = name;
+ } else {
+ if (mName.startsWith(mUiPackage)) {
+ int off = mUiPackage.length();
+ if (mName.length() > off) {
+ off++;
+ }
+ mUiLabel = name + " (" + mName.substring(off) + ")";
+ } else {
+ mUiLabel = name + " (" + mName + ")";
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ if (mUiTargetApp == null) {
+ String[] packages = pm.getPackagesForUid(mUid);
+ if (packages != null) {
+ for (String curPkg : packages) {
+ try {
+ final PackageInfo pi = pm.getPackageInfo(curPkg,
+ PackageManager.GET_DISABLED_COMPONENTS |
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ if (pi.sharedUserLabel != 0) {
+ mUiTargetApp = pi.applicationInfo;
+ final CharSequence nm = pm.getText(curPkg,
+ pi.sharedUserLabel, pi.applicationInfo);
+ if (nm != null) {
+ mUiBaseLabel = nm.toString();
+ mUiLabel = mUiBaseLabel + " (" + mName + ")";
+ } else {
+ mUiBaseLabel = mUiTargetApp.loadLabel(pm).toString();
+ mUiLabel = mUiBaseLabel + " (" + mName + ")";
+ }
+ break;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ } else {
+ // no current packages for this uid, typically because of uninstall
+ Log.i(TAG, "No package for uid " + mUid);
+ }
+ }
+ }
+
public void addServices(ProcessStats.PackageState pkgState) {
for (int isvc=0, NSVC=pkgState.mServices.size(); isvc<NSVC; isvc++) {
ProcessStats.ServiceState svc = pkgState.mServices.valueAt(isvc);
// XXX can't tell what process it is in!
- if (mServices == null) {
- mServices = new ArrayList<Service>();
- }
mServices.add(new Service(svc));
}
}
- public static final class Service {
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mPackage);
+ dest.writeInt(mUid);
+ dest.writeString(mName);
+ dest.writeInt(mUnique ? 1 : 0);
+ dest.writeLong(mDuration);
+ dest.writeLong(mAvgPss);
+ dest.writeLong(mWeight);
+ dest.writeString(mBestTargetPackage);
+ dest.writeTypedList(mServices);
+ }
+
+ public static final Parcelable.Creator<ProcStatsEntry> CREATOR
+ = new Parcelable.Creator<ProcStatsEntry>() {
+ public ProcStatsEntry createFromParcel(Parcel in) {
+ return new ProcStatsEntry(in);
+ }
+
+ public ProcStatsEntry[] newArray(int size) {
+ return new ProcStatsEntry[size];
+ }
+ };
+
+ public static final class Service implements Parcelable {
final String mPackage;
final String mName;
final long mDuration;
@@ -62,15 +218,51 @@ public final class ProcStatsEntry {
public Service(ProcessStats.ServiceState service) {
mPackage = service.mPackage;
mName = service.mName;
- mDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
+ long startDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_STARTED,
- ProcessStats.STATE_NOTHING, 0, 0)
- + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ long bindDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_BOUND,
- ProcessStats.STATE_NOTHING, 0, 0)
- + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ long execDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_EXEC,
ProcessStats.STATE_NOTHING, 0, 0);
+ if (bindDuration > startDuration) {
+ startDuration = bindDuration;
+ }
+ if (execDuration > startDuration) {
+ startDuration = execDuration;
+ }
+ mDuration = startDuration;
}
+
+ public Service(Parcel in) {
+ mPackage = in.readString();
+ mName = in.readString();
+ mDuration = in.readLong();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mPackage);
+ dest.writeString(mName);
+ dest.writeLong(mDuration);
+ }
+
+ public static final Parcelable.Creator<Service> CREATOR
+ = new Parcelable.Creator<Service>() {
+ public Service createFromParcel(Parcel in) {
+ return new Service(in);
+ }
+
+ public Service[] newArray(int size) {
+ return new Service[size];
+ }
+ };
}
}
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
new file mode 100644
index 0000000..5ec3b07
--- /dev/null
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 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.settings.applications;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Fragment;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.preference.PreferenceActivity;
+import android.text.format.Formatter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import static com.android.settings.Utils.prepareCustomPreferencesList;
+
+public class ProcessStatsDetail extends Fragment implements Button.OnClickListener {
+ private static final String TAG = "ProcessStatsDetail";
+
+ public static final int ACTION_FORCE_STOP = 1;
+
+ public static final String EXTRA_ENTRY = "entry";
+ public static final String EXTRA_MAX_WEIGHT = "max_weight";
+ public static final String EXTRA_TOTAL_TIME = "total_time";
+
+ private PackageManager mPm;
+ private DevicePolicyManager mDpm;
+
+ private ProcStatsEntry mEntry;
+ private long mMaxWeight;
+ private long mTotalTime;
+
+ private View mRootView;
+ private TextView mTitleView;
+ private ViewGroup mTwoButtonsPanel;
+ private Button mForceStopButton;
+ private Button mReportButton;
+ private ViewGroup mDetailsParent;
+ private ViewGroup mServicesParent;
+
+ public static String makePercentString(Resources res, long amount, long total) {
+ final double percent = (((double)amount) / total) * 100;
+ return res.getString(R.string.percentage, (int) Math.ceil(percent));
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mPm = getActivity().getPackageManager();
+ mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
+ final Bundle args = getArguments();
+ mEntry = (ProcStatsEntry)args.getParcelable(EXTRA_ENTRY);
+ mEntry.retrieveUiData(mPm);
+ mMaxWeight = args.getLong(EXTRA_MAX_WEIGHT);
+ mTotalTime = args.getLong(EXTRA_TOTAL_TIME);
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.process_stats_details, container, false);
+ prepareCustomPreferencesList(container, view, view, false);
+
+ mRootView = view;
+ createDetails();
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ checkForceStop();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ private void createDetails() {
+ final double percentOfWeight = (((double)mEntry.mWeight) / mMaxWeight) * 100;
+
+ int appLevel = (int) Math.ceil(percentOfWeight);
+ String appLevelText = makePercentString(getResources(), mEntry.mDuration, mTotalTime);
+
+ // Set all values in the header.
+ final TextView summary = (TextView) mRootView.findViewById(android.R.id.summary);
+ summary.setText(mEntry.mName);
+ summary.setVisibility(View.VISIBLE);
+ mTitleView = (TextView) mRootView.findViewById(android.R.id.title);
+ mTitleView.setText(mEntry.mUiBaseLabel);
+ final TextView text1 = (TextView)mRootView.findViewById(android.R.id.text1);
+ text1.setText(appLevelText);
+ final ProgressBar progress = (ProgressBar) mRootView.findViewById(android.R.id.progress);
+ progress.setProgress(appLevel);
+ final ImageView icon = (ImageView) mRootView.findViewById(android.R.id.icon);
+ if (mEntry.mUiTargetApp != null) {
+ icon.setImageDrawable(mEntry.mUiTargetApp.loadIcon(mPm));
+ }
+
+ mTwoButtonsPanel = (ViewGroup)mRootView.findViewById(R.id.two_buttons_panel);
+ mForceStopButton = (Button)mRootView.findViewById(R.id.right_button);
+ mReportButton = (Button)mRootView.findViewById(R.id.left_button);
+ mForceStopButton.setEnabled(false);
+ mReportButton.setVisibility(View.INVISIBLE);
+
+ mDetailsParent = (ViewGroup)mRootView.findViewById(R.id.details);
+ mServicesParent = (ViewGroup)mRootView.findViewById(R.id.services);
+
+ fillDetailsSection();
+ fillServicesSection();
+
+ if (mEntry.mUid >= android.os.Process.FIRST_APPLICATION_UID) {
+ mForceStopButton.setText(R.string.force_stop);
+ mForceStopButton.setTag(ACTION_FORCE_STOP);
+ mForceStopButton.setOnClickListener(this);
+ mTwoButtonsPanel.setVisibility(View.VISIBLE);
+ } else {
+ mTwoButtonsPanel.setVisibility(View.GONE);
+ }
+ }
+
+ public void onClick(View v) {
+ doAction((Integer) v.getTag());
+ }
+
+ private void doAction(int action) {
+ PreferenceActivity pa = (PreferenceActivity)getActivity();
+ switch (action) {
+ case ACTION_FORCE_STOP:
+ killProcesses();
+ break;
+ }
+ }
+
+ private void addDetailsItem(ViewGroup parent, CharSequence label, CharSequence value) {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_detail_item_text,
+ null);
+ parent.addView(item);
+ TextView labelView = (TextView) item.findViewById(R.id.label);
+ TextView valueView = (TextView) item.findViewById(R.id.value);
+ labelView.setText(label);
+ valueView.setText(value);
+ }
+
+ private void fillDetailsSection() {
+ addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_ram_use),
+ Formatter.formatShortFileSize(getActivity(), mEntry.mAvgPss * 1024));
+ addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_run_time),
+ makePercentString(getResources(), mEntry.mDuration, mTotalTime));
+ }
+
+ final static Comparator<ProcStatsEntry.Service> sServiceCompare
+ = new Comparator<ProcStatsEntry.Service>() {
+ @Override
+ public int compare(ProcStatsEntry.Service lhs, ProcStatsEntry.Service rhs) {
+ if (lhs.mDuration < rhs.mDuration) {
+ return 1;
+ } else if (lhs.mDuration > rhs.mDuration) {
+ return -1;
+ }
+ return 0;
+ }
+ };
+
+ private void fillServicesSection() {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ if (mEntry.mServices.size() > 0) {
+ ArrayList<ProcStatsEntry.Service> services =
+ (ArrayList<ProcStatsEntry.Service>)mEntry.mServices.clone();
+ Collections.sort(services, sServiceCompare);
+ for (int i=0; i<services.size(); i++) {
+ ProcStatsEntry.Service service = services.get(i);
+ String label = service.mName;
+ int tail = label.lastIndexOf('.');
+ if (tail >= 0 && tail < (label.length()-1)) {
+ label = label.substring(tail+1);
+ }
+ long duration = service.mDuration;
+ final double percentOfTime = (((double)duration) / mTotalTime) * 100;
+ addDetailsItem(mServicesParent, label, getActivity().getResources().getString(
+ R.string.percentage, (int) Math.ceil(percentOfTime)));
+ }
+ }
+ }
+
+ private void killProcesses() {
+ ActivityManager am = (ActivityManager)getActivity().getSystemService(
+ Context.ACTIVITY_SERVICE);
+ am.forceStopPackage(mEntry.mUiPackage);
+ checkForceStop();
+ }
+
+ private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
+ }
+ };
+
+ private void checkForceStop() {
+ if (mEntry.mUiPackage == null || mEntry.mUid < Process.FIRST_APPLICATION_UID) {
+ mForceStopButton.setEnabled(false);
+ return;
+ }
+ if (mDpm.packageHasActiveAdmins(mEntry.mUiPackage)) {
+ mForceStopButton.setEnabled(false);
+ return;
+ }
+ try {
+ ApplicationInfo info = mPm.getApplicationInfo(mEntry.mUiPackage, 0);
+ if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
+ mForceStopButton.setEnabled(true);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
+ Uri.fromParts("package", mEntry.mUiPackage, null));
+ intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mEntry.mUiPackage });
+ intent.putExtra(Intent.EXTRA_UID, mEntry.mUid);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, mEntry.mUid);
+ getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
+ Activity.RESULT_CANCELED, null, null);
+ }
+}
diff --git a/src/com/android/settings/applications/ProcessStatsPreference.java b/src/com/android/settings/applications/ProcessStatsPreference.java
index 64ab0b6..2dea96a 100644
--- a/src/com/android/settings/applications/ProcessStatsPreference.java
+++ b/src/com/android/settings/applications/ProcessStatsPreference.java
@@ -27,15 +27,21 @@ import android.widget.TextView;
import com.android.settings.R;
public class ProcessStatsPreference extends Preference {
+ private final ProcStatsEntry mEntry;
private int mProgress;
private CharSequence mProgressText;
- public ProcessStatsPreference(Context context, Drawable icon) {
+ public ProcessStatsPreference(Context context, Drawable icon, ProcStatsEntry entry) {
super(context);
+ mEntry = entry;
setLayoutResource(R.layout.app_percentage_item);
setIcon(icon != null ? icon : new ColorDrawable(0));
}
+ public ProcStatsEntry getEntry() {
+ return mEntry;
+ }
+
public void setPercent(double percentOfWeight, double percentOfTime) {
mProgress = (int) Math.ceil(percentOfWeight);
mProgressText = getContext().getResources().getString(
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index 8e98d23..49682ed 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -17,8 +17,6 @@
package com.android.settings.applications;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Parcel;
@@ -28,10 +26,10 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.preference.Preference;
+import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
-import android.text.format.DateFormat;
import android.util.Log;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -83,6 +81,7 @@ public class ProcessStatsUi extends PreferenceFragment {
private PreferenceGroup mAppListGroup;
private Preference mMemStatusPref;
+ long mMaxWeight;
long mTotalTime;
@Override
@@ -127,11 +126,13 @@ public class ProcessStatsUi extends PreferenceFragment {
return false;
}
- /*
- PreferenceActivity pa = (PreferenceActivity)getActivity();
- pa.startPreferencePanel(PowerUsageDetail.class.getName(), args,
- R.string.details_title, null, null, 0);
- */
+ ProcessStatsPreference pgp = (ProcessStatsPreference) preference;
+ Bundle args = new Bundle();
+ args.putParcelable(ProcessStatsDetail.EXTRA_ENTRY, pgp.getEntry());
+ args.putLong(ProcessStatsDetail.EXTRA_MAX_WEIGHT, mMaxWeight);
+ args.putLong(ProcessStatsDetail.EXTRA_TOTAL_TIME, mTotalTime);
+ ((PreferenceActivity) getActivity()).startPreferencePanel(
+ ProcessStatsDetail.class.getName(), args, R.string.details_title, null, null, 0);
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@@ -263,108 +264,19 @@ public class ProcessStatsUi extends PreferenceFragment {
maxWeight = proc.mWeight;
}
}
+ mMaxWeight = maxWeight;
for (int i=0, N=(procs != null ? procs.size() : 0); i<N; i++) {
ProcStatsEntry proc = procs.get(i);
final double percentOfWeight = (((double)proc.mWeight) / maxWeight) * 100;
final double percentOfTime = (((double)proc.mDuration) / mTotalTime) * 100;
if (percentOfWeight < 1) continue;
- ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null);
- ApplicationInfo targetApp = null;
- String label = proc.mName;
- String pkgName = null;
- if (proc.mUnique) {
- pkgName = proc.mPackage;
- proc.addServices(mStats.getPackageStateLocked(proc.mPackage, proc.mUid));
- } else {
- // See if there is one significant package that was running here.
- ArrayList<ProcStatsEntry> subProcs = new ArrayList<ProcStatsEntry>();
- for (int ipkg=0, NPKG=mStats.mPackages.getMap().size(); ipkg<NPKG; ipkg++) {
- SparseArray<ProcessStats.PackageState> uids
- = mStats.mPackages.getMap().valueAt(ipkg);
- for (int iu=0, NU=uids.size(); iu<NU; iu++) {
- if (uids.keyAt(iu) != proc.mUid) {
- continue;
- }
- ProcessStats.PackageState pkgState = uids.valueAt(iu);
- boolean match = false;
- for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
- ProcessStats.ProcessState subProc =
- pkgState.mProcesses.valueAt(iproc);
- if (subProc.mName.equals(proc.mName)) {
- match = true;
- subProcs.add(new ProcStatsEntry(subProc, totals));
- }
- }
- if (match) {
- proc.addServices(mStats.getPackageStateLocked(proc.mPackage,
- proc.mUid));
- }
- }
- }
- if ( subProcs.size() > 1) {
- Collections.sort(subProcs, sEntryCompare);
- if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
- pkgName = subProcs.get(0).mPackage;
- }
- }
- }
- if (pkgName != null) {
- // Only one app associated with this process.
- try {
- targetApp = pm.getApplicationInfo(pkgName,
- PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
- PackageManager.GET_UNINSTALLED_PACKAGES);
- String name = targetApp.loadLabel(pm).toString();
- if (proc.mName.equals(pkgName)) {
- label = name;
- } else {
- if (proc.mName.startsWith(pkgName)) {
- int off = pkgName.length();
- if (proc.mName.length() > off) {
- off++;
- }
- label = name + " (" + proc.mName.substring(off) + ")";
- } else {
- label = name + " (" + proc.mName + ")";
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
- }
- if (targetApp == null) {
- String[] packages = pm.getPackagesForUid(proc.mUid);
- if (packages != null) {
- for (String curPkg : packages) {
- try {
- final PackageInfo pi = pm.getPackageInfo(curPkg,
- PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
- PackageManager.GET_UNINSTALLED_PACKAGES);
- if (pi.sharedUserLabel != 0) {
- targetApp = pi.applicationInfo;
- final CharSequence nm = pm.getText(curPkg,
- pi.sharedUserLabel, pi.applicationInfo);
- if (nm != null) {
- label = nm.toString() + " (" + proc.mName + ")";
- } else {
- label = targetApp.loadLabel(pm).toString() + " ("
- + proc.mName + ")";
- }
- break;
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
- }
- } else {
- // no current packages for this uid, typically because of uninstall
- Log.i(TAG, "No package for uid " + proc.mUid);
- }
- }
- pref.setTitle(label);
- if (targetApp != null) {
- pref.setIcon(targetApp.loadIcon(pm));
+ ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null, proc);
+ proc.evaluateTargetPackage(mStats, totals, sEntryCompare);
+ proc.retrieveUiData(pm);
+ pref.setTitle(proc.mUiLabel);
+ if (proc.mUiTargetApp != null) {
+ pref.setIcon(proc.mUiTargetApp.loadIcon(pm));
}
pref.setOrder(i);
pref.setPercent(percentOfWeight, percentOfTime);