From 4d83bd2dbd6cd068ef770ec960c24414e8aa6391 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Sat, 24 Jul 2010 20:04:51 -0700 Subject: Add UI to report a running service to the developer. Change-Id: Ia3f666344ee02bc96784b198533392252230bd80 --- .../applications/RunningServiceDetails.java | 91 ++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/com/android/settings/applications/RunningServiceDetails.java b/src/com/android/settings/applications/RunningServiceDetails.java index f469608..a55e54f 100644 --- a/src/com/android/settings/applications/RunningServiceDetails.java +++ b/src/com/android/settings/applications/RunningServiceDetails.java @@ -4,29 +4,41 @@ import com.android.settings.R; import android.app.Activity; import android.app.ActivityManager; +import android.app.ApplicationErrorReport; import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentSender; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.os.Bundle; +import android.os.Debug; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; 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.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; +import android.widget.Button; 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.List; @@ -63,11 +75,66 @@ public class RunningServiceDetails extends Activity { class ActiveDetail implements View.OnClickListener { View mRootView; + Button mStopButton; + Button mReportButton; + RunningState.ServiceItem mServiceItem; RunningProcessesView.ActiveItem mActiveItem; RunningProcessesView.ViewHolder mViewHolder; PendingIntent mManageIntent; + ComponentName mInstaller; 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) { try { startIntentSender(mManageIntent.getIntentSender(), null, @@ -185,6 +252,7 @@ public class RunningServiceDetails extends Activity { mAllDetails, false); mAllDetails.addView(root); detail.mRootView = root; + detail.mServiceItem = si; detail.mViewHolder = new RunningProcessesView.ViewHolder(root); 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); - button.setOnClickListener(detail); - ((TextView)button).setText(getText(detail.mManageIntent != null + detail.mStopButton = (Button)root.findViewById(R.id.left_button); + detail.mStopButton.setOnClickListener(detail); + detail.mStopButton.setText(getText(detail.mManageIntent != null ? 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); } -- cgit v1.1