From c01b0c83fca571229621d16b757a46dc0fae7dfe Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 24 Jun 2010 11:29:50 -0700 Subject: Allow user to see and stop heavy-weight processes. Change-Id: If5caed3972ab03a54fbf8c459cdfc136e4bdc020 --- res/values/strings.xml | 3 + .../applications/RunningProcessesView.java | 12 +- .../applications/RunningServiceDetails.java | 254 ++++++++++++--------- .../settings/applications/RunningState.java | 97 ++++++-- .../settings/fuelgauge/BatteryHistoryChart.java | 24 +- 5 files changed, 242 insertions(+), 148 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 03d2136..4a5907d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1788,6 +1788,9 @@ found in the list of installed applications. This service was started by its application. Stopping it may cause the application to fail. + + This application can not safely + be stopped. Doing so may lose some of your current work. %1$s: currently in use. Touch Settings to control it. diff --git a/src/com/android/settings/applications/RunningProcessesView.java b/src/com/android/settings/applications/RunningProcessesView.java index 9fbae6d..d63cc88 100644 --- a/src/com/android/settings/applications/RunningProcessesView.java +++ b/src/com/android/settings/applications/RunningProcessesView.java @@ -130,8 +130,16 @@ public class RunningProcessesView extends FrameLayout uptimeView.setText(DateUtils.formatElapsedTime(builder, (SystemClock.uptimeMillis()-mFirstRunTime)/1000)); } else { - uptimeView.setText(context.getResources().getText( - R.string.service_restarting)); + boolean isService = false; + if (mItem instanceof RunningState.MergedItem) { + isService = ((RunningState.MergedItem)mItem).mServices.size() > 0; + } + if (isService) { + uptimeView.setText(context.getResources().getText( + R.string.service_restarting)); + } else { + uptimeView.setText(""); + } } } } diff --git a/src/com/android/settings/applications/RunningServiceDetails.java b/src/com/android/settings/applications/RunningServiceDetails.java index f33625e..f469608 100644 --- a/src/com/android/settings/applications/RunningServiceDetails.java +++ b/src/com/android/settings/applications/RunningServiceDetails.java @@ -55,6 +55,8 @@ public class RunningServiceDetails extends Activity { RunningProcessesView.ActiveItem mSnippetActiveItem; RunningProcessesView.ViewHolder mSnippetViewHolder; + int mNumServices, mNumProcesses; + TextView mServicesHeader; TextView mProcessesHeader; final ArrayList mActiveDetails = new ArrayList(); @@ -79,7 +81,7 @@ public class RunningServiceDetails extends Activity { } catch (ActivityNotFoundException e) { Log.w(TAG, e); } - } else { + } else if (mActiveItem.mItem instanceof RunningState.ServiceItem) { RunningState.ServiceItem si = (RunningState.ServiceItem)mActiveItem.mItem; stopService(new Intent().setComponent(si.mRunningService.service)); if (mMergedItem == null || mMergedItem.mServices.size() <= 1) { @@ -91,6 +93,10 @@ public class RunningServiceDetails extends Activity { mBackgroundHandler.sendEmptyMessage(MSG_UPDATE_CONTENTS); } } + } else { + // Heavy-weight process. We'll do a force-stop on it. + mAm.forceStopPackage(mActiveItem.mItem.mPackageInfo.packageName); + finish(); } } } @@ -163,6 +169,129 @@ public class RunningServiceDetails extends Activity { return false; } + void addServiceDetailsView(RunningState.ServiceItem si, RunningState.MergedItem mi) { + if (mNumServices == 0) { + mServicesHeader = (TextView)mInflater.inflate(R.layout.separator_label, + mAllDetails, false); + mServicesHeader.setText(R.string.runningservicedetails_services_title); + mAllDetails.addView(mServicesHeader); + } + mNumServices++; + + RunningState.BaseItem bi = si != null ? si : mi; + + ActiveDetail detail = new ActiveDetail(); + View root = mInflater.inflate(R.layout.running_service_details_service, + mAllDetails, false); + mAllDetails.addView(root); + detail.mRootView = root; + detail.mViewHolder = new RunningProcessesView.ViewHolder(root); + detail.mActiveItem = detail.mViewHolder.bind(mState, bi, mBuilder); + + if (si != null && si.mRunningService.clientLabel != 0) { + detail.mManageIntent = mAm.getRunningServiceControlPanel( + si.mRunningService.service); + } + + TextView description = (TextView)root.findViewById(R.id.comp_description); + if (si != null && si.mServiceInfo.descriptionRes != 0) { + description.setText(getPackageManager().getText( + si.mServiceInfo.packageName, si.mServiceInfo.descriptionRes, + si.mServiceInfo.applicationInfo)); + } else { + if (detail.mManageIntent != null) { + try { + Resources clientr = getPackageManager().getResourcesForApplication( + si.mRunningService.clientPackage); + String label = clientr.getString(si.mRunningService.clientLabel); + description.setText(getString(R.string.service_manage_description, + label)); + } catch (PackageManager.NameNotFoundException e) { + } + } else { + description.setText(getText(si != null + ? R.string.service_stop_description + : R.string.heavy_weight_stop_description)); + } + } + + View button = root.findViewById(R.id.right_button); + button.setOnClickListener(detail); + ((TextView)button).setText(getText(detail.mManageIntent != null + ? R.string.service_manage : R.string.service_stop)); + root.findViewById(R.id.left_button).setVisibility(View.INVISIBLE); + + mActiveDetails.add(detail); + } + + void addProcessDetailsView(RunningState.ProcessItem pi, boolean isMain) { + if (mNumProcesses == 0) { + mProcessesHeader = (TextView)mInflater.inflate(R.layout.separator_label, + mAllDetails, false); + mProcessesHeader.setText(R.string.runningservicedetails_processes_title); + mAllDetails.addView(mProcessesHeader); + } + mNumProcesses++; + + ActiveDetail detail = new ActiveDetail(); + View root = mInflater.inflate(R.layout.running_service_details_process, + mAllDetails, false); + mAllDetails.addView(root); + detail.mRootView = root; + detail.mViewHolder = new RunningProcessesView.ViewHolder(root); + detail.mActiveItem = detail.mViewHolder.bind(mState, pi, mBuilder); + + TextView description = (TextView)root.findViewById(R.id.comp_description); + if (isMain) { + description.setText(R.string.main_running_process_description); + } else { + int textid = 0; + CharSequence label = null; + ActivityManager.RunningAppProcessInfo rpi = pi.mRunningProcessInfo; + final ComponentName comp = rpi.importanceReasonComponent; + //Log.i(TAG, "Secondary proc: code=" + rpi.importanceReasonCode + // + " pid=" + rpi.importanceReasonPid + " comp=" + comp); + switch (rpi.importanceReasonCode) { + case ActivityManager.RunningAppProcessInfo.REASON_PROVIDER_IN_USE: + textid = R.string.process_provider_in_use_description; + List providers = null; + if (comp != null) { + providers = getPackageManager() + .queryContentProviders(comp.getPackageName(), + rpi.uid, 0); + } + if (providers != null) { + for (int j=0; j=0; i--) { mAllDetails.removeView(mActiveDetails.get(i).mRootView); @@ -179,58 +308,20 @@ public class RunningServiceDetails extends Activity { mProcessesHeader = null; } + mNumServices = mNumProcesses = 0; + if (mMergedItem != null) { for (int i=0; i