Add UI to report a running service to the developer.
Change-Id: Ia3f666344ee02bc96784b198533392252230bd80
This commit is contained in:
@@ -4,29 +4,41 @@ import com.android.settings.R;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
import android.app.ApplicationErrorReport;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ProviderInfo;
|
import android.content.pm.ProviderInfo;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.text.format.DateUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -63,11 +75,66 @@ public class RunningServiceDetails extends Activity {
|
|||||||
|
|
||||||
class ActiveDetail implements View.OnClickListener {
|
class ActiveDetail implements View.OnClickListener {
|
||||||
View mRootView;
|
View mRootView;
|
||||||
|
Button mStopButton;
|
||||||
|
Button mReportButton;
|
||||||
|
RunningState.ServiceItem mServiceItem;
|
||||||
RunningProcessesView.ActiveItem mActiveItem;
|
RunningProcessesView.ActiveItem mActiveItem;
|
||||||
RunningProcessesView.ViewHolder mViewHolder;
|
RunningProcessesView.ViewHolder mViewHolder;
|
||||||
PendingIntent mManageIntent;
|
PendingIntent mManageIntent;
|
||||||
|
ComponentName mInstaller;
|
||||||
|
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
if (v == mReportButton) {
|
||||||
|
ApplicationErrorReport report = new ApplicationErrorReport();
|
||||||
|
report.type = ApplicationErrorReport.TYPE_RUNNING_SERVICE;
|
||||||
|
report.packageName = mServiceItem.mServiceInfo.packageName;
|
||||||
|
report.installerPackageName = mInstaller.getPackageName();
|
||||||
|
report.processName = mServiceItem.mRunningService.process;
|
||||||
|
report.time = System.currentTimeMillis();
|
||||||
|
report.systemApp = (mServiceItem.mServiceInfo.applicationInfo.flags
|
||||||
|
& ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||||
|
ApplicationErrorReport.RunningServiceInfo info
|
||||||
|
= new ApplicationErrorReport.RunningServiceInfo();
|
||||||
|
if (mActiveItem.mItem.mActiveSince >= 0) {
|
||||||
|
info.durationMillis = SystemClock.uptimeMillis()-mActiveItem.mFirstRunTime;
|
||||||
|
} else {
|
||||||
|
info.durationMillis = -1;
|
||||||
|
}
|
||||||
|
ComponentName comp = new ComponentName(mServiceItem.mServiceInfo.packageName,
|
||||||
|
mServiceItem.mServiceInfo.name);
|
||||||
|
File filename = getFileStreamPath("service_dump.txt");
|
||||||
|
FileOutputStream output = null;
|
||||||
|
try {
|
||||||
|
output = new FileOutputStream(filename);
|
||||||
|
Debug.dumpService("activity", output.getFD(),
|
||||||
|
new String[] { "-a", "service", comp.flattenToString() });
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, "Can't dump service: " + comp, e);
|
||||||
|
} finally {
|
||||||
|
if (output != null) try { output.close(); } catch (IOException e) {}
|
||||||
|
}
|
||||||
|
FileInputStream input = null;
|
||||||
|
try {
|
||||||
|
input = new FileInputStream(filename);
|
||||||
|
byte[] buffer = new byte[(int) filename.length()];
|
||||||
|
input.read(buffer);
|
||||||
|
info.serviceDetails = new String(buffer);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, "Can't read service dump: " + comp, e);
|
||||||
|
} finally {
|
||||||
|
if (input != null) try { input.close(); } catch (IOException e) {}
|
||||||
|
}
|
||||||
|
filename.delete();
|
||||||
|
Log.i(TAG, "Details: " + info.serviceDetails);
|
||||||
|
report.runningServiceInfo = info;
|
||||||
|
Intent result = new Intent(Intent.ACTION_APP_ERROR);
|
||||||
|
result.setComponent(mInstaller);
|
||||||
|
result.putExtra(Intent.EXTRA_BUG_REPORT, report);
|
||||||
|
result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
startActivity(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mManageIntent != null) {
|
if (mManageIntent != null) {
|
||||||
try {
|
try {
|
||||||
startIntentSender(mManageIntent.getIntentSender(), null,
|
startIntentSender(mManageIntent.getIntentSender(), null,
|
||||||
@@ -185,6 +252,7 @@ public class RunningServiceDetails extends Activity {
|
|||||||
mAllDetails, false);
|
mAllDetails, false);
|
||||||
mAllDetails.addView(root);
|
mAllDetails.addView(root);
|
||||||
detail.mRootView = root;
|
detail.mRootView = root;
|
||||||
|
detail.mServiceItem = si;
|
||||||
detail.mViewHolder = new RunningProcessesView.ViewHolder(root);
|
detail.mViewHolder = new RunningProcessesView.ViewHolder(root);
|
||||||
detail.mActiveItem = detail.mViewHolder.bind(mState, bi, mBuilder);
|
detail.mActiveItem = detail.mViewHolder.bind(mState, bi, mBuilder);
|
||||||
|
|
||||||
@@ -215,11 +283,24 @@ public class RunningServiceDetails extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
View button = root.findViewById(R.id.right_button);
|
detail.mStopButton = (Button)root.findViewById(R.id.left_button);
|
||||||
button.setOnClickListener(detail);
|
detail.mStopButton.setOnClickListener(detail);
|
||||||
((TextView)button).setText(getText(detail.mManageIntent != null
|
detail.mStopButton.setText(getText(detail.mManageIntent != null
|
||||||
? R.string.service_manage : R.string.service_stop));
|
? R.string.service_manage : R.string.service_stop));
|
||||||
root.findViewById(R.id.left_button).setVisibility(View.INVISIBLE);
|
|
||||||
|
detail.mReportButton = (Button)root.findViewById(R.id.right_button);
|
||||||
|
detail.mReportButton.setOnClickListener(detail);
|
||||||
|
detail.mReportButton.setText(com.android.internal.R.string.report);
|
||||||
|
// check if error reporting is enabled in secure settings
|
||||||
|
int enabled = Settings.Secure.getInt(getContentResolver(),
|
||||||
|
Settings.Secure.SEND_ACTION_APP_ERROR, 0);
|
||||||
|
if (enabled != 0) {
|
||||||
|
detail.mInstaller = ApplicationErrorReport.getErrorReportReceiver(
|
||||||
|
this, si.mServiceInfo.packageName, si.mServiceInfo.applicationInfo.flags);
|
||||||
|
detail.mReportButton.setEnabled(detail.mInstaller != null);
|
||||||
|
} else {
|
||||||
|
detail.mReportButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
mActiveDetails.add(detail);
|
mActiveDetails.add(detail);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user