Allow user to see and stop heavy-weight processes.

Change-Id: If5caed3972ab03a54fbf8c459cdfc136e4bdc020
This commit is contained in:
Dianne Hackborn
2010-06-24 11:29:50 -07:00
parent 12fd447d6f
commit c01b0c83fc
5 changed files with 242 additions and 148 deletions

View File

@@ -55,6 +55,8 @@ public class RunningServiceDetails extends Activity {
RunningProcessesView.ActiveItem mSnippetActiveItem;
RunningProcessesView.ViewHolder mSnippetViewHolder;
int mNumServices, mNumProcesses;
TextView mServicesHeader;
TextView mProcessesHeader;
final ArrayList<ActiveDetail> mActiveDetails = new ArrayList<ActiveDetail>();
@@ -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<ProviderInfo> providers = null;
if (comp != null) {
providers = getPackageManager()
.queryContentProviders(comp.getPackageName(),
rpi.uid, 0);
}
if (providers != null) {
for (int j=0; j<providers.size(); j++) {
ProviderInfo prov = providers.get(j);
if (comp.getClassName().equals(prov.name)) {
label = RunningState.makeLabel(getPackageManager(),
prov.name, prov);
break;
}
}
}
break;
case ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE:
textid = R.string.process_service_in_use_description;
if (rpi.importanceReasonComponent != null) {
try {
ServiceInfo serv = getPackageManager().getServiceInfo(
rpi.importanceReasonComponent, 0);
label = RunningState.makeLabel(getPackageManager(),
serv.name, serv);
} catch (NameNotFoundException e) {
}
}
break;
}
if (textid != 0 && label != null) {
description.setText(getString(textid, label));
}
}
mActiveDetails.add(detail);
}
void addDetailViews() {
for (int i=mActiveDetails.size()-1; i>=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<mMergedItem.mServices.size(); i++) {
if (i == 0) {
mServicesHeader = (TextView)mInflater.inflate(R.layout.separator_label,
mAllDetails, false);
mServicesHeader.setText(R.string.runningservicedetails_services_title);
mAllDetails.addView(mServicesHeader);
}
RunningState.ServiceItem si = mMergedItem.mServices.get(i);
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, si, mBuilder);
if (si.mRunningService.clientLabel != 0) {
detail.mManageIntent = mAm.getRunningServiceControlPanel(
si.mRunningService.service);
}
TextView description = (TextView)root.findViewById(R.id.comp_description);
if (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(R.string.service_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);
addServiceDetailsView(mMergedItem.mServices.get(i), mMergedItem);
}
if (mMergedItem.mServices.size() <= 0) {
// This item does not have any services, so it must be
// a heavy-weight process... we will put a fake service
// entry for it, to allow the user to "stop" it.
addServiceDetailsView(null, mMergedItem);
}
boolean didProcess = false;
for (int i=-1; i<mMergedItem.mOtherProcesses.size(); i++) {
RunningState.ProcessItem pi = i < 0 ? mMergedItem.mProcess
: mMergedItem.mOtherProcesses.get(i);
@@ -238,70 +329,7 @@ public class RunningServiceDetails extends Activity {
continue;
}
if (!didProcess) {
mProcessesHeader = (TextView)mInflater.inflate(R.layout.separator_label,
mAllDetails, false);
mProcessesHeader.setText(R.string.runningservicedetails_processes_title);
mAllDetails.addView(mProcessesHeader);
didProcess = true;
}
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 (i < 0) {
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<ProviderInfo> providers = null;
if (comp != null) {
providers = getPackageManager()
.queryContentProviders(comp.getPackageName(),
rpi.uid, 0);
}
if (providers != null) {
for (int j=0; j<providers.size(); j++) {
ProviderInfo prov = providers.get(i);
if (comp.getClassName().equals(prov.name)) {
label = RunningState.makeLabel(getPackageManager(),
prov.name, prov);
break;
}
}
}
break;
case ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE:
textid = R.string.process_service_in_use_description;
if (rpi.importanceReasonComponent != null) {
try {
ServiceInfo serv = getPackageManager().getServiceInfo(
rpi.importanceReasonComponent, 0);
label = RunningState.makeLabel(getPackageManager(),
serv.name, serv);
} catch (NameNotFoundException e) {
}
}
break;
}
if (textid != 0 && label != null) {
description.setText(getString(textid, label));
}
}
mActiveDetails.add(detail);
addProcessDetailsView(pi, i < 0);
}
}
}