diff options
author | Dianne Hackborn <hackbod@google.com> | 2013-09-04 18:31:29 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-09-04 18:31:29 -0700 |
commit | ec4f5ed1a95bd26e68766252f19c407b1479bb83 (patch) | |
tree | fe7ebd9914dc30432f3b95b1d5aa89dc19f3ed70 /src/com/android | |
parent | 8ed62da68b1682245e2c8d093c96a6a3f169679a (diff) | |
parent | dd600b603d98e28219a9a38a62f2527db05736bb (diff) | |
download | packages_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')
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); |