OSDN Git Service

Add new button to report battery usage to the developer.
authorDianne Hackborn <hackbod@google.com>
Mon, 22 Feb 2010 04:07:27 +0000 (20:07 -0800)
committerDianne Hackborn <hackbod@google.com>
Mon, 22 Feb 2010 19:31:37 +0000 (11:31 -0800)
This displays a new button on the application battery usage details
screen for the user to send a bug report to the developer, if that is
possible to do.  Also adds a button to directly force stop the app
from the details screen, and uses the new facilities to determine
whether the button should be enabled.

res/layout/power_usage_action_item.xml
res/layout/power_usage_details.xml
res/layout/running_services.xml
src/com/android/settings/InstalledAppDetails.java
src/com/android/settings/RunningServices.java
src/com/android/settings/fuelgauge/PowerUsageDetail.java
src/com/android/settings/fuelgauge/PowerUsageSummary.java

index a53c551..e4d8b5a 100644 (file)
@@ -28,6 +28,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="2dip"
+            android:paddingBottom="4dip"
             android:ellipsize="marquee"
             android:textAppearance="?android:attr/textAppearanceMedium"/>
 
index 18781a9..23be53f 100644 (file)
             </RelativeLayout>
         </LinearLayout>
 
+        <!-- Force stop and report buttons -->
+        <LinearLayout
+            android:id="@+id/two_buttons_panel"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="6dip"
+            android:orientation="vertical">
+            <include
+                layout="@layout/two_buttons_panel"/>
+        </LinearLayout>
+                    
         <TextView
             style="?android:attr/listSeparatorTextViewStyle"
             android:text="@string/details_subtitle" />
index 2f464a5..5c0da6f 100644 (file)
                    android:text="@string/no_running_services"
                    android:textAppearance="?android:attr/textAppearanceLarge" />
     </FrameLayout>
-    <LinearLayout
+    <view class="com.android.settings.RunningServices$LinearColorBar"
+            android:id="@+id/color_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
-            android:background="?android:attr/colorForeground"
             android:padding="4dp">
-        <TextView android:id="@+id/backgroundText"
+        <TextView android:id="@+id/foregroundText"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:textAppearance="?android:attr/textAppearanceSmallInverse"
             android:color="?android:attr/textColorPrimaryInverse"
             android:singleLine="true" />
-        <TextView android:id="@+id/foregroundText"
+        <TextView android:id="@+id/backgroundText"
             android:layout_gravity="center_vertical|right"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -56,5 +56,5 @@
             android:textAppearance="?android:attr/textAppearanceSmallInverse"
             android:color="?android:attr/textColorPrimaryInverse"
             android:singleLine="true" />
-    </LinearLayout>
+    </view>
 </LinearLayout>
index 2cbc887..67f2f8f 100644 (file)
@@ -23,14 +23,13 @@ import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.ActivityManager.RunningAppProcessInfo;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
 import android.content.pm.PackageInfo;
@@ -43,7 +42,6 @@ import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
 import android.text.format.Formatter;
-import android.util.Config;
 import android.util.Log;
 import java.util.ArrayList;
 import java.util.List;
@@ -234,25 +232,6 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
             // Register listener
             mUninstallButton.setOnClickListener(this);
         }
-        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-        List<RunningAppProcessInfo> rList = am.getRunningAppProcesses();
-        boolean running = false;
-        if (rList != null) {
-            for (RunningAppProcessInfo info : rList) {
-                if (info.pkgList != null) {
-                    for (String rpkg : info.pkgList) {
-                        if (rpkg.equals(mAppInfo.packageName)) {
-                            running = true;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-        mForceStopButton.setEnabled(running);
-        if (running) {
-            mForceStopButton.setOnClickListener(this);
-        }
     }
 
     /** Called when the activity is first created. */
@@ -292,6 +271,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
         mForceStopButton = (Button) btnPanel.findViewById(R.id.left_button);
         mForceStopButton.setText(R.string.force_stop);
         mUninstallButton = (Button)btnPanel.findViewById(R.id.right_button);
+        mForceStopButton.setEnabled(false);
         initControlButtons();
         // Initialize clear data and move install location buttons
         View data_buttons_panel = findViewById(R.id.data_buttons_panel);
@@ -384,6 +364,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
             showDialogInner(DLG_APP_NOT_FOUND);
             return;
         }
+        checkForceStop();
         refreshAppAttributes(pkgInfo);
     }
 
@@ -604,8 +585,25 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
         ActivityManager am = (ActivityManager)getSystemService(
                 Context.ACTIVITY_SERVICE);
         am.forceStopPackage(pkgName);
+        checkForceStop();
     }
 
+    private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mForceStopButton.setEnabled(getResultCode() != RESULT_CANCELED);
+        }
+    };
+    
+    private void checkForceStop() {
+        Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
+                Uri.fromParts("package", mAppInfo.packageName, null));
+        intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppInfo.packageName });
+        intent.putExtra(Intent.EXTRA_UID, mAppInfo.uid);
+        sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
+                Activity.RESULT_CANCELED, null, null);
+    }
+    
     /*
      * Method implementing functionality of buttons clicked
      * @see android.view.View.OnClickListener#onClick(android.view.View)
index 6c11ea0..4808aec 100644 (file)
@@ -35,6 +35,9 @@ import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
@@ -53,6 +56,7 @@ import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.TextView;
 
@@ -93,13 +97,16 @@ public class RunningServices extends ListActivity
     
     int mProcessBgColor;
     
+    LinearColorBar mColorBar;
     TextView mBackgroundProcessText;
     TextView mForegroundProcessText;
     
     int mLastNumBackgroundProcesses = -1;
     int mLastNumForegroundProcesses = -1;
+    int mLastNumServiceProcesses = -1;
     long mLastBackgroundProcessMemory = -1;
     long mLastForegroundProcessMemory = -1;
+    long mLastServiceProcessMemory = -1;
     long mLastAvailMemory = -1;
     
     Dialog mCurDialog;
@@ -392,6 +399,8 @@ public class RunningServices extends ListActivity
         long mBackgroundProcessMemory;
         int mNumForegroundProcesses;
         long mForegroundProcessMemory;
+        int mNumServiceProcesses;
+        long mServiceProcessMemory;
         
         boolean update(Context context, ActivityManager am) {
             final PackageManager pm = context.getPackageManager();
@@ -576,6 +585,7 @@ public class RunningServices extends ListActivity
             mAllProcessItems.addAll(mProcessItems);
             mNumBackgroundProcesses = 0;
             mNumForegroundProcesses = 0;
+            mNumServiceProcesses = 0;
             NRP = mRunningProcesses.size();
             for (int i=0; i<NRP; i++) {
                 ProcessItem proc = mRunningProcesses.valueAt(i);
@@ -590,13 +600,19 @@ public class RunningServices extends ListActivity
                             ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
                         mNumForegroundProcesses++;
                         mAllProcessItems.add(proc);
+                    } else {
+                        Log.i(TAG, "Unknown non-service process: "
+                                + proc.mProcessName + " #" + proc.mPid);
                     }
+                } else {
+                    mNumServiceProcesses++;
                 }
             }
             
             try {
                 mBackgroundProcessMemory = 0;
                 mForegroundProcessMemory = 0;
+                mServiceProcessMemory = 0;
                 final int numProc = mAllProcessItems.size();
                 int[] pids = new int[numProc];
                 for (int i=0; i<numProc; i++) {
@@ -608,9 +624,8 @@ public class RunningServices extends ListActivity
                     ProcessItem proc = mAllProcessItems.get(i);
                     changed |= proc.updateSize(context, mem[i], mSequence);
                     if (proc.mCurSeq == mSequence) {
-                        continue;
-                    }
-                    if (proc.mRunningProcessInfo.importance >=
+                        mServiceProcessMemory += proc.mSize;
+                    } else if (proc.mRunningProcessInfo.importance >=
                             ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                         mBackgroundProcessMemory += proc.mSize;
                     } else if (proc.mRunningProcessInfo.importance <=
@@ -725,6 +740,67 @@ public class RunningServices extends ListActivity
         }
     }
     
+    public static class LinearColorBar extends LinearLayout {
+        private float mRedRatio;
+        private float mYellowRatio;
+        private float mGreenRatio;
+        
+        final Rect mRect = new Rect();
+        final Paint mPaint = new Paint();
+        
+        public LinearColorBar(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            setWillNotDraw(false);
+            mPaint.setStyle(Paint.Style.FILL);
+        }
+
+        public void setRatios(float red, float yellow, float green) {
+            mRedRatio = red;
+            mYellowRatio = yellow;
+            mGreenRatio = green;
+            invalidate();
+        }
+        
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            
+            int width = getWidth();
+            mRect.top = 0;
+            mRect.bottom = getHeight();
+            
+            int left = 0;
+            
+            int right = left + (int)(width*mRedRatio);
+            if (left < right) {
+                mRect.left = left;
+                mRect.right = right;
+                mPaint.setColor(0xffff8080);
+                canvas.drawRect(mRect, mPaint);
+                width -= (right-left);
+                left = right;
+            }
+            
+            right = left + (int)(width*mYellowRatio);
+            if (left < right) {
+                mRect.left = left;
+                mRect.right = right;
+                mPaint.setColor(0xffffff00);
+                canvas.drawRect(mRect, mPaint);
+                width -= (right-left);
+                left = right;
+            }
+            
+            right = left + width;
+            if (left < right) {
+                mRect.left = left;
+                mRect.right = right;
+                mPaint.setColor(0xff80ff80);
+                canvas.drawRect(mRect, mPaint);
+            }
+        }
+    }
+    
     final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -823,6 +899,7 @@ public class RunningServices extends ListActivity
         setContentView(R.layout.running_services);
         getListView().setDivider(null);
         getListView().setAdapter(new ServiceListAdapter(mState));
+        mColorBar = (LinearColorBar)findViewById(R.id.color_bar);
         mBackgroundProcessText = (TextView)findViewById(R.id.backgroundText);
         mForegroundProcessText = (TextView)findViewById(R.id.foregroundText);
         
@@ -864,6 +941,14 @@ public class RunningServices extends ListActivity
             mForegroundProcessText.setText(getResources().getString(
                     R.string.service_foreground_processes, mLastNumForegroundProcesses, sizeStr));
         }
+        mLastNumServiceProcesses = mState.mNumServiceProcesses;
+        mLastServiceProcessMemory = mState.mServiceProcessMemory;
+        
+        float totalMem = mLastBackgroundProcessMemory
+                + mLastForegroundProcessMemory + mLastServiceProcessMemory;
+        mColorBar.setRatios(mLastForegroundProcessMemory/totalMem,
+                mLastServiceProcessMemory/totalMem,
+                mLastForegroundProcessMemory/totalMem);
     }
     
     @Override
index a98bfed..da5721a 100644 (file)
@@ -18,6 +18,9 @@ package com.android.settings.fuelgauge;
 
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.ApplicationErrorReport;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -26,9 +29,12 @@ import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.Process;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -37,6 +43,7 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.settings.InstalledAppDetails;
+import com.android.settings.ManageApplications;
 import com.android.settings.R;
 
 public class PowerUsageDetail extends Activity implements Button.OnClickListener {
@@ -68,6 +75,8 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
     public static final int ACTION_WIRELESS_SETTINGS = 4;
     public static final int ACTION_APP_DETAILS = 5;
     public static final int ACTION_SECURITY_SETTINGS = 6;
+    public static final int ACTION_FORCE_STOP = 7;
+    public static final int ACTION_REPORT = 8;
 
     public static final int USAGE_SINCE_UNPLUGGED = 1;
     public static final int USAGE_SINCE_RESET = 2;
@@ -78,6 +87,8 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
     public static final String EXTRA_UID = "uid";
     public static final String EXTRA_USAGE_SINCE = "since";
     public static final String EXTRA_USAGE_DURATION = "duration";
+    public static final String EXTRA_REPORT_DETAILS = "report_details";
+    public static final String EXTRA_REPORT_CHECKIN_DETAILS = "report_checkin_details";
     public static final String EXTRA_DETAIL_TYPES = "types"; // Array of usage types (cpu, gps, etc)
     public static final String EXTRA_DETAIL_VALUES = "values"; // Array of doubles
     public static final String EXTRA_DRAIN_TYPE = "drainType"; // DrainType
@@ -92,6 +103,9 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
     private int mUid;
     private double[] mValues;
     private TextView mTitleView;
+    private ViewGroup mTwoButtonsPanel;
+    private Button mForceStopButton;
+    private Button mReportButton;
     private ViewGroup mDetailsParent;
     private ViewGroup mControlsParent;
     private long mStartTime;
@@ -105,6 +119,9 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
     private static final String TAG = "PowerUsageDetail";
     private String[] mPackages;
 
+    ApplicationInfo mApp;
+    ComponentName mInstaller;
+    
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -116,6 +133,7 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
     protected void onResume() {
         super.onResume();
         mStartTime = android.os.Process.getElapsedCpuTime();
+        checkForceStop();
     }
 
     @Override
@@ -163,6 +181,11 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
         ((TextView)findViewById(R.id.battery_percentage))
             .setText(String.format("%d%%", percentage));
 
+        mTwoButtonsPanel = (ViewGroup) findViewById(R.id.two_buttons_panel);
+        mForceStopButton = (Button) findViewById(R.id.left_button);
+        mReportButton = (Button) findViewById(R.id.right_button);
+        mForceStopButton.setEnabled(false);
+        
         ImageView gaugeImage = (ImageView) findViewById(R.id.gauge);
         mGauge = new PercentageBar();
         mGauge.percent = gaugeValue;
@@ -178,6 +201,34 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
         fillDetailsSection();
         fillPackagesSection(mUid);
         fillControlsSection(mUid);
+        
+        if (mUid >= Process.FIRST_APPLICATION_UID) {
+            mForceStopButton.setText(R.string.force_stop);
+            mForceStopButton.setTag(ACTION_FORCE_STOP);
+            mForceStopButton.setOnClickListener(this);
+            mReportButton.setText(com.android.internal.R.string.report);
+            mReportButton.setTag(ACTION_REPORT);
+            mReportButton.setOnClickListener(this);
+            
+            // 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) {
+                if (mPackages != null && mPackages.length > 0) {
+                    try {
+                        mApp = getPackageManager().getApplicationInfo(mPackages[0], 0);
+                        mInstaller = ApplicationErrorReport.getErrorReportReceiver(
+                                this, mPackages[0], mApp.flags);
+                    } catch (NameNotFoundException e) {
+                    }
+                }
+                mReportButton.setEnabled(mInstaller != null);
+            } else {
+                mTwoButtonsPanel.setVisibility(View.GONE);
+            }
+        } else {
+            mTwoButtonsPanel.setVisibility(View.GONE);
+        }
     }
 
     public void onClick(View v) {
@@ -201,12 +252,18 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
             case ACTION_APP_DETAILS:
                 Intent intent = new Intent(Intent.ACTION_VIEW);
                 intent.setClass(this, InstalledAppDetails.class);
-                intent.putExtra("com.android.settings.ApplicationPkgName", mPackages[0]);
+                intent.putExtra(ManageApplications.APP_PKG_NAME, mPackages[0]);
                 startActivity(intent);
                 break;
             case ACTION_SECURITY_SETTINGS:
                 startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
                 break;
+            case ACTION_FORCE_STOP:
+                killProcesses();
+                break;
+            case ACTION_REPORT:
+                reportBatteryUse();
+                break;
         }
     }
 
@@ -332,8 +389,62 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
         for (int i = 0; i < mPackages.length; i++) {
             am.forceStopPackage(mPackages[i]);
         }
+        checkForceStop();
     }
 
+    private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mForceStopButton.setEnabled(getResultCode() != RESULT_CANCELED);
+        }
+    };
+    
+    private void checkForceStop() {
+        if (mPackages == null || mUid < Process.FIRST_APPLICATION_UID) {
+            mForceStopButton.setEnabled(false);
+            return;
+        }
+        Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
+                Uri.fromParts("package", mPackages[0], null));
+        intent.putExtra(Intent.EXTRA_PACKAGES, mPackages);
+        intent.putExtra(Intent.EXTRA_UID, mUid);
+        sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
+                Activity.RESULT_CANCELED, null, null);
+    }
+    
+    private void reportBatteryUse() {
+        if (mPackages == null) return;
+        
+        final Intent intent = getIntent();
+        final int percentage = intent.getIntExtra(EXTRA_PERCENT, 1);
+        final long duration = intent.getLongExtra(EXTRA_USAGE_DURATION, 0);
+        
+        ApplicationErrorReport report = new ApplicationErrorReport();
+        report.type = ApplicationErrorReport.TYPE_BATTERY;
+        report.packageName = mPackages[0];
+        report.installerPackageName = mInstaller.getPackageName();
+        report.processName = mPackages[0];
+        report.time = System.currentTimeMillis();
+        report.systemApp = (mApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+        
+        StringBuilder builder = new StringBuilder();
+        builder.append("Application used " + percentage + "% of battery over "
+                + Utils.formatElapsedTime(this, duration / 1000));
+        builder.append('\n');
+        builder.append(intent.getStringExtra(EXTRA_REPORT_DETAILS));
+        builder.append('\n');
+        builder.append("----------------------------------------------");
+        builder.append('\n');
+        builder.append(intent.getStringExtra(EXTRA_REPORT_CHECKIN_DETAILS));
+        builder.append('\n');
+        report.batteryText = builder.toString();
+        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);
+    }
+    
     private void fillPackagesSection(int uid) {
         if (uid < 1) {
             removePackagesSection();
@@ -344,7 +455,7 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
         LayoutInflater inflater = getLayoutInflater();
         
         PackageManager pm = getPackageManager();
-        final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
+        //final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
         mPackages = pm.getPackagesForUid(uid);
         if (mPackages == null || mPackages.length < 2) {
             removePackagesSection();
@@ -356,13 +467,13 @@ public class PowerUsageDetail extends Activity implements Button.OnClickListener
             try {
                 ApplicationInfo ai = pm.getApplicationInfo(mPackages[i], 0);
                 CharSequence label = ai.loadLabel(pm);
-                Drawable icon = defaultActivityIcon;
+                //Drawable icon = defaultActivityIcon;
                 if (label != null) {
                     mPackages[i] = label.toString();
                 }
-                if (ai.icon != 0) {
-                    icon = ai.loadIcon(pm);
-                }
+                //if (ai.icon != 0) {
+                //    icon = ai.loadIcon(pm);
+                //}
                 ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_package_item,
                         null);
                 packagesParent.addView(item);
index 10ab2d0..5678160 100644 (file)
@@ -48,6 +48,9 @@ import com.android.internal.os.PowerProfile;
 import com.android.settings.R;
 import com.android.settings.fuelgauge.PowerUsageDetail.DrainType;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -78,6 +81,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
     private static final int MIN_POWER_THRESHOLD = 5;
     private static final int MAX_ITEMS_TO_LIST = 10;
 
+    private long mStatsPeriod = 0;
     private double mMaxPower = 1;
     private double mTotalPower;
     private PowerProfile mPowerProfile;
@@ -132,6 +136,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
                 Math.ceil(sipper.getSortValue() * 100 / mTotalPower));
         intent.putExtra(PowerUsageDetail.EXTRA_GAUGE, (int)
                 Math.ceil(sipper.getSortValue() * 100 / mMaxPower));
+        intent.putExtra(PowerUsageDetail.EXTRA_USAGE_DURATION, mStatsPeriod);
         intent.putExtra(PowerUsageDetail.EXTRA_ICON_PACKAGE, sipper.defaultPackageName);
         intent.putExtra(PowerUsageDetail.EXTRA_ICON_ID, sipper.iconId);
         intent.putExtra(PowerUsageDetail.EXTRA_NO_COVERAGE, sipper.noCoveragePercent);
@@ -165,6 +170,15 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
                     0
                 };
 
+                Writer result = new StringWriter();
+                PrintWriter printWriter = new PrintWriter(result);
+                mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid());
+                intent.putExtra(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString());
+                
+                result = new StringWriter();
+                printWriter = new PrintWriter(result);
+                mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid());
+                intent.putExtra(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, result.toString());
             }
             break;
             case CELL:
@@ -303,6 +317,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
         }
         final double averageCostPerByte = getAverageDataCost();
         long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
+        mStatsPeriod = uSecTime;
         updateStatsPeriod(uSecTime);
         SparseArray<? extends Uid> uidStats = mStats.getUidStats();
         final int NU = uidStats.size();