2 * Copyright (C) 2009 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.settings.fuelgauge;
19 import android.app.Activity;
20 import android.app.ActivityManager;
21 import android.app.ApplicationErrorReport;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.BroadcastReceiver;
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.ApplicationInfo;
28 import android.content.pm.PackageInfo;
29 import android.content.pm.PackageManager;
30 import android.content.pm.PackageManager.NameNotFoundException;
31 import android.graphics.drawable.Drawable;
32 import android.net.Uri;
33 import android.os.BatteryStats;
34 import android.os.Bundle;
35 import android.os.Process;
36 import android.os.UserHandle;
37 import android.preference.Preference;
38 import android.preference.Preference.OnPreferenceClickListener;
39 import android.preference.PreferenceCategory;
40 import android.text.TextUtils;
41 import android.util.Log;
42 import android.view.View;
43 import android.widget.Button;
45 import com.android.internal.logging.MetricsLogger;
46 import com.android.internal.os.BatterySipper;
47 import com.android.internal.os.BatterySipper.DrainType;
48 import com.android.internal.os.BatteryStatsHelper;
49 import com.android.internal.util.FastPrintWriter;
50 import com.android.settings.AppHeader;
51 import com.android.settings.DisplaySettings;
52 import com.android.settings.R;
53 import com.android.settings.SettingsActivity;
54 import com.android.settings.Utils;
55 import com.android.settings.WirelessSettings;
56 import com.android.settings.applications.AppInfoWithHeader;
57 import com.android.settings.applications.InstalledAppDetails;
58 import com.android.settings.applications.LayoutPreference;
59 import com.android.settings.bluetooth.BluetoothSettings;
60 import com.android.settings.location.LocationSettings;
61 import com.android.settings.wifi.WifiSettings;
63 import java.io.PrintWriter;
64 import java.io.StringWriter;
65 import java.io.Writer;
67 public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickListener {
69 // Note: Must match the sequence of the DrainType
70 private static int[] sDrainTypeDesciptions = new int[] {
71 R.string.battery_desc_standby,
72 R.string.battery_desc_radio,
73 R.string.battery_desc_voice,
74 R.string.battery_desc_wifi,
75 R.string.battery_desc_bluetooth,
76 R.string.battery_desc_flashlight,
77 R.string.battery_desc_display,
78 R.string.battery_desc_apps,
79 R.string.battery_desc_users,
80 R.string.battery_desc_unaccounted,
81 R.string.battery_desc_overcounted,
82 R.string.battery_desc_camera,
85 public static void startBatteryDetailPage(
86 SettingsActivity caller, BatteryStatsHelper helper, int statsType, BatteryEntry entry,
87 boolean showLocationButton) {
88 // Initialize mStats if necessary.
91 final int dischargeAmount = helper.getStats().getDischargeAmount(statsType);
92 Bundle args = new Bundle();
93 args.putString(PowerUsageDetail.EXTRA_TITLE, entry.name);
94 args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int)
95 ((entry.sipper.totalPowerMah * dischargeAmount / helper.getTotalPower()) + .5));
96 args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int)
97 Math.ceil(entry.sipper.totalPowerMah * 100 / helper.getMaxPower()));
98 args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, helper.getStatsPeriod());
99 args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, entry.defaultPackageName);
100 args.putInt(PowerUsageDetail.EXTRA_ICON_ID, entry.iconId);
101 args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, entry.sipper.noCoveragePercent);
102 if (entry.sipper.uidObj != null) {
103 args.putInt(PowerUsageDetail.EXTRA_UID, entry.sipper.uidObj.getUid());
105 args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, entry.sipper.drainType);
106 args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton);
108 int userId = UserHandle.myUserId();
111 switch (entry.sipper.drainType) {
115 BatteryStats.Uid uid = entry.sipper.uidObj;
117 R.string.usage_type_cpu,
118 R.string.usage_type_cpu_foreground,
119 R.string.usage_type_wake_lock,
120 R.string.usage_type_gps,
121 R.string.usage_type_wifi_running,
122 R.string.usage_type_data_recv,
123 R.string.usage_type_data_send,
124 R.string.usage_type_radio_active,
125 R.string.usage_type_data_wifi_recv,
126 R.string.usage_type_data_wifi_send,
127 R.string.usage_type_audio,
128 R.string.usage_type_video,
129 R.string.usage_type_camera,
130 R.string.usage_type_flashlight,
131 R.string.usage_type_computed_power,
133 values = new double[] {
134 entry.sipper.cpuTimeMs,
135 entry.sipper.cpuFgTimeMs,
136 entry.sipper.wakeLockTimeMs,
137 entry.sipper.gpsTimeMs,
138 entry.sipper.wifiRunningTimeMs,
139 entry.sipper.mobileRxPackets,
140 entry.sipper.mobileTxPackets,
141 entry.sipper.mobileActive,
142 entry.sipper.wifiRxPackets,
143 entry.sipper.wifiTxPackets,
146 entry.sipper.cameraTimeMs,
147 entry.sipper.flashlightTimeMs,
148 entry.sipper.totalPowerMah,
151 if (entry.sipper.drainType == BatterySipper.DrainType.APP) {
152 Writer result = new StringWriter();
153 PrintWriter printWriter = new FastPrintWriter(result, false, 1024);
154 helper.getStats().dumpLocked(caller, printWriter, "", helper.getStatsType(),
157 args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString());
159 result = new StringWriter();
160 printWriter = new FastPrintWriter(result, false, 1024);
161 helper.getStats().dumpCheckinLocked(caller, printWriter, helper.getStatsType(),
164 args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS,
166 userId = UserHandle.getUserId(uid.getUid());
173 R.string.usage_type_on_time,
174 R.string.usage_type_no_coverage,
175 R.string.usage_type_radio_active,
176 R.string.usage_type_computed_power,
178 values = new double[] {
179 entry.sipper.usageTimeMs,
180 entry.sipper.noCoveragePercent,
181 entry.sipper.mobileActive,
182 entry.sipper.totalPowerMah,
189 R.string.usage_type_wifi_running,
190 R.string.usage_type_cpu,
191 R.string.usage_type_cpu_foreground,
192 R.string.usage_type_wake_lock,
193 R.string.usage_type_data_recv,
194 R.string.usage_type_data_send,
195 R.string.usage_type_data_wifi_recv,
196 R.string.usage_type_data_wifi_send,
197 R.string.usage_type_computed_power,
199 values = new double[] {
200 entry.sipper.wifiRunningTimeMs,
201 entry.sipper.cpuTimeMs,
202 entry.sipper.cpuFgTimeMs,
203 entry.sipper.wakeLockTimeMs,
204 entry.sipper.mobileRxPackets,
205 entry.sipper.mobileTxPackets,
206 entry.sipper.wifiRxPackets,
207 entry.sipper.wifiTxPackets,
208 entry.sipper.totalPowerMah,
214 R.string.usage_type_on_time,
215 R.string.usage_type_cpu,
216 R.string.usage_type_cpu_foreground,
217 R.string.usage_type_wake_lock,
218 R.string.usage_type_data_recv,
219 R.string.usage_type_data_send,
220 R.string.usage_type_data_wifi_recv,
221 R.string.usage_type_data_wifi_send,
222 R.string.usage_type_computed_power,
224 values = new double[] {
225 entry.sipper.usageTimeMs,
226 entry.sipper.cpuTimeMs,
227 entry.sipper.cpuFgTimeMs,
228 entry.sipper.wakeLockTimeMs,
229 entry.sipper.mobileRxPackets,
230 entry.sipper.mobileTxPackets,
231 entry.sipper.wifiRxPackets,
232 entry.sipper.wifiTxPackets,
233 entry.sipper.totalPowerMah,
239 R.string.usage_type_total_battery_capacity,
240 R.string.usage_type_computed_power,
241 R.string.usage_type_actual_power,
243 values = new double[] {
244 helper.getPowerProfile().getBatteryCapacity(),
245 helper.getComputedPower(),
246 helper.getMinDrainedPower(),
252 R.string.usage_type_total_battery_capacity,
253 R.string.usage_type_computed_power,
254 R.string.usage_type_actual_power,
256 values = new double[] {
257 helper.getPowerProfile().getBatteryCapacity(),
258 helper.getComputedPower(),
259 helper.getMaxDrainedPower(),
265 R.string.usage_type_on_time,
266 R.string.usage_type_computed_power,
268 values = new double[] {
269 entry.sipper.usageTimeMs,
270 entry.sipper.totalPowerMah,
274 args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types);
275 args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values);
277 caller.startPreferencePanelAsUser(PowerUsageDetail.class.getName(), args,
278 R.string.details_title, null, new UserHandle(userId));
281 public static final int ACTION_DISPLAY_SETTINGS = 1;
282 public static final int ACTION_WIFI_SETTINGS = 2;
283 public static final int ACTION_BLUETOOTH_SETTINGS = 3;
284 public static final int ACTION_WIRELESS_SETTINGS = 4;
285 public static final int ACTION_APP_DETAILS = 5;
286 public static final int ACTION_LOCATION_SETTINGS = 6;
287 public static final int ACTION_FORCE_STOP = 7;
288 public static final int ACTION_REPORT = 8;
290 public static final int USAGE_SINCE_UNPLUGGED = 1;
291 public static final int USAGE_SINCE_RESET = 2;
293 public static final String EXTRA_TITLE = "title";
294 public static final String EXTRA_PERCENT = "percent";
295 public static final String EXTRA_GAUGE = "gauge";
296 public static final String EXTRA_UID = "uid";
297 public static final String EXTRA_USAGE_SINCE = "since";
298 public static final String EXTRA_USAGE_DURATION = "duration";
299 public static final String EXTRA_REPORT_DETAILS = "report_details";
300 public static final String EXTRA_REPORT_CHECKIN_DETAILS = "report_checkin_details";
301 public static final String EXTRA_DETAIL_TYPES = "types"; // Array of usage types (cpu, gps, etc)
302 public static final String EXTRA_DETAIL_VALUES = "values"; // Array of doubles
303 public static final String EXTRA_DRAIN_TYPE = "drainType"; // DrainType
304 public static final String EXTRA_ICON_PACKAGE = "iconPackage"; // String
305 public static final String EXTRA_NO_COVERAGE = "noCoverage";
306 public static final String EXTRA_ICON_ID = "iconId"; // Int
307 public static final String EXTRA_SHOW_LOCATION_BUTTON = "showLocationButton"; // Boolean
309 private static final String TAG = "PowerUsageDetail";
311 private static final String KEY_DETAILS_PARENT = "details_parent";
312 private static final String KEY_CONTROLS_PARENT = "controls_parent";
313 private static final String KEY_MESSAGES_PARENT = "messages_parent";
314 private static final String KEY_PACKAGES_PARENT = "packages_parent";
315 private static final String KEY_TWO_BUTTONS = "two_buttons";
316 private static final String KEY_HIGH_POWER = "high_power";
318 private PackageManager mPm;
319 private DevicePolicyManager mDpm;
320 private int mUsageSince;
321 private int[] mTypes;
323 private double[] mValues;
324 private Button mForceStopButton;
325 private Button mReportButton;
326 private long mStartTime;
327 private BatterySipper.DrainType mDrainType;
328 private double mNoCoverage; // Percentage of time that there was no coverage
330 private PreferenceCategory mDetailsParent;
331 private PreferenceCategory mControlsParent;
332 private PreferenceCategory mMessagesParent;
333 private PreferenceCategory mPackagesParent;
335 private boolean mUsesGps;
336 private boolean mShowLocationButton;
338 private String[] mPackages;
340 ApplicationInfo mApp;
341 ComponentName mInstaller;
342 private Preference mHighPower;
345 public void onCreate(Bundle icicle) {
346 super.onCreate(icicle);
347 mPm = getActivity().getPackageManager();
348 mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
350 addPreferencesFromResource(R.xml.power_usage_details);
351 mDetailsParent = (PreferenceCategory) findPreference(KEY_DETAILS_PARENT);
352 mControlsParent = (PreferenceCategory) findPreference(KEY_CONTROLS_PARENT);
353 mMessagesParent = (PreferenceCategory) findPreference(KEY_MESSAGES_PARENT);
354 mPackagesParent = (PreferenceCategory) findPreference(KEY_PACKAGES_PARENT);
360 protected int getMetricsCategory() {
361 return MetricsLogger.FUELGAUGE_POWER_USAGE_DETAIL;
365 public void onResume() {
367 mStartTime = android.os.Process.getElapsedCpuTime();
369 if (mHighPower != null) {
370 mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
377 public void onActivityResult(int requestCode, int resultCode, Intent data) {
378 super.onActivityResult(requestCode, resultCode, data);
379 if (mHighPower != null) {
380 mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
384 private void createDetails() {
385 final Bundle args = getArguments();
386 Context context = getActivity();
387 mUsageSince = args.getInt(EXTRA_USAGE_SINCE, USAGE_SINCE_UNPLUGGED);
388 mUid = args.getInt(EXTRA_UID, 0);
389 mPackages = context.getPackageManager().getPackagesForUid(mUid);
390 mDrainType = (BatterySipper.DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
391 mNoCoverage = args.getDouble(EXTRA_NO_COVERAGE, 0);
392 mShowLocationButton = args.getBoolean(EXTRA_SHOW_LOCATION_BUTTON);
394 mTypes = args.getIntArray(EXTRA_DETAIL_TYPES);
395 mValues = args.getDoubleArray(EXTRA_DETAIL_VALUES);
397 LayoutPreference twoButtons = (LayoutPreference) findPreference(KEY_TWO_BUTTONS);
398 mForceStopButton = (Button) twoButtons.findViewById(R.id.left_button);
399 mReportButton = (Button) twoButtons.findViewById(R.id.right_button);
400 mForceStopButton.setEnabled(false);
402 if (mUid >= Process.FIRST_APPLICATION_UID) {
403 mForceStopButton.setText(R.string.force_stop);
404 mForceStopButton.setTag(ACTION_FORCE_STOP);
405 mForceStopButton.setOnClickListener(this);
406 mReportButton.setText(com.android.internal.R.string.report);
407 mReportButton.setTag(ACTION_REPORT);
408 mReportButton.setOnClickListener(this);
410 if (mPackages != null && mPackages.length > 0) {
412 mApp = context.getPackageManager().getApplicationInfo(
414 } catch (NameNotFoundException e) {
417 Log.d(TAG, "No packages!!");
419 // check if error reporting is enabled in secure settings
420 int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
421 android.provider.Settings.Global.SEND_ACTION_APP_ERROR, 0);
424 mInstaller = ApplicationErrorReport.getErrorReportReceiver(
425 context, mPackages[0], mApp.flags);
427 mReportButton.setEnabled(mInstaller != null);
429 removePreference(KEY_TWO_BUTTONS);
432 mHighPower = findPreference(KEY_HIGH_POWER);
433 mHighPower.setOnPreferenceClickListener(new OnPreferenceClickListener() {
435 public boolean onPreferenceClick(Preference preference) {
436 HighPowerDetail.show(PowerUsageDetail.this, mApp.packageName, 0, false);
441 removePreference(KEY_HIGH_POWER);
444 removePreference(KEY_TWO_BUTTONS);
445 removePreference(KEY_HIGH_POWER);
450 fillDetailsSection();
451 fillPackagesSection(mUid);
452 fillControlsSection(mUid);
453 fillMessagesSection(mUid);
456 private void setupHeader() {
457 final Bundle args = getArguments();
458 String title = args.getString(EXTRA_TITLE);
459 String pkg = args.getString(EXTRA_ICON_PACKAGE);
460 int iconId = args.getInt(EXTRA_ICON_ID, 0);
461 Drawable appIcon = null;
463 if (!TextUtils.isEmpty(pkg)) {
465 final PackageManager pm = getActivity().getPackageManager();
466 ApplicationInfo ai = pm.getPackageInfo(pkg, 0).applicationInfo;
468 appIcon = ai.loadIcon(pm);
470 } catch (NameNotFoundException nnfe) {
473 } else if (iconId != 0) {
474 appIcon = getActivity().getDrawable(iconId);
476 if (appIcon == null) {
477 appIcon = getActivity().getPackageManager().getDefaultActivityIcon();
480 if (pkg == null && mPackages != null) {
483 AppHeader.createAppHeader(this, appIcon, title,
484 pkg != null ? AppInfoWithHeader.getInfoIntent(this, pkg) : null,
485 mDrainType != DrainType.APP ? android.R.color.white : 0);
488 public void onClick(View v) {
489 doAction((Integer) v.getTag());
492 // utility method used to start sub activity
493 private void startApplicationDetailsActivity() {
494 // start new fragment to display extended information
495 Bundle args = new Bundle();
496 args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackages[0]);
498 SettingsActivity sa = (SettingsActivity) getActivity();
499 sa.startPreferencePanel(InstalledAppDetails.class.getName(), args,
500 R.string.application_info_label, null, null, 0);
503 private void doAction(int action) {
504 SettingsActivity sa = (SettingsActivity)getActivity();
506 case ACTION_DISPLAY_SETTINGS:
507 sa.startPreferencePanel(DisplaySettings.class.getName(), null,
508 R.string.display_settings_title, null, null, 0);
510 case ACTION_WIFI_SETTINGS:
511 sa.startPreferencePanel(WifiSettings.class.getName(), null,
512 R.string.wifi_settings, null, null, 0);
514 case ACTION_BLUETOOTH_SETTINGS:
515 sa.startPreferencePanel(BluetoothSettings.class.getName(), null,
516 R.string.bluetooth_settings, null, null, 0);
518 case ACTION_WIRELESS_SETTINGS:
519 sa.startPreferencePanel(WirelessSettings.class.getName(), null,
520 R.string.radio_controls_title, null, null, 0);
522 case ACTION_APP_DETAILS:
523 startApplicationDetailsActivity();
525 case ACTION_LOCATION_SETTINGS:
526 sa.startPreferencePanel(LocationSettings.class.getName(), null,
527 R.string.location_settings_title, null, null, 0);
529 case ACTION_FORCE_STOP:
538 private void fillDetailsSection() {
539 if (mTypes != null && mValues != null) {
540 for (int i = 0; i < mTypes.length; i++) {
541 // Only add an item if the time is greater than zero
542 if (mValues[i] <= 0) continue;
543 final String label = getString(mTypes[i]);
546 case R.string.usage_type_data_recv:
547 case R.string.usage_type_data_send:
548 case R.string.usage_type_data_wifi_recv:
549 case R.string.usage_type_data_wifi_send:
550 final long packets = (long) (mValues[i]);
551 value = Long.toString(packets);
553 case R.string.usage_type_no_coverage:
554 final int percentage = (int) Math.floor(mValues[i]);
555 value = Utils.formatPercentage(percentage);
557 case R.string.usage_type_total_battery_capacity:
558 case R.string.usage_type_computed_power:
559 case R.string.usage_type_actual_power:
560 value = getActivity().getString(R.string.mah, (long)(mValues[i]));
562 case R.string.usage_type_gps:
566 value = Utils.formatElapsedTime(getActivity(), mValues[i], true);
568 addHorizontalPreference(mDetailsParent, label, value);
573 private void addHorizontalPreference(PreferenceCategory parent, CharSequence title,
574 CharSequence summary) {
575 Preference pref = new Preference(getActivity());
576 pref.setLayoutResource(R.layout.horizontal_preference);
577 pref.setTitle(title);
578 pref.setSummary(summary);
579 pref.setSelectable(false);
580 parent.addPreference(pref);
583 private void fillControlsSection(int uid) {
584 PackageManager pm = getActivity().getPackageManager();
585 String[] packages = pm.getPackagesForUid(uid);
586 PackageInfo pi = null;
588 pi = packages != null ? pm.getPackageInfo(packages[0], 0) : null;
589 } catch (NameNotFoundException nnfe) { /* Nothing */ }
590 ApplicationInfo ai = pi != null? pi.applicationInfo : null;
592 boolean removeHeader = true;
593 switch (mDrainType) {
595 // If it is a Java application and only one package is associated with the Uid
596 if (packages != null && packages.length == 1) {
597 addControl(R.string.battery_action_app_details,
598 R.string.battery_sugg_apps_info, ACTION_APP_DETAILS);
599 removeHeader = false;
600 // If the application has a settings screen, jump to that
603 // If power usage detail page is launched from location page, suppress "Location"
604 // button to prevent circular loops.
605 if (mUsesGps && mShowLocationButton) {
606 addControl(R.string.location_settings_title,
607 R.string.battery_sugg_apps_gps, ACTION_LOCATION_SETTINGS);
608 removeHeader = false;
612 addControl(R.string.display_settings,
613 R.string.battery_sugg_display,
614 ACTION_DISPLAY_SETTINGS);
615 removeHeader = false;
618 addControl(R.string.wifi_settings,
619 R.string.battery_sugg_wifi,
620 ACTION_WIFI_SETTINGS);
621 removeHeader = false;
624 addControl(R.string.bluetooth_settings,
625 R.string.battery_sugg_bluetooth_basic,
626 ACTION_BLUETOOTH_SETTINGS);
627 removeHeader = false;
630 if (mNoCoverage > 10) {
631 addControl(R.string.radio_controls_title,
632 R.string.battery_sugg_radio,
633 ACTION_WIRELESS_SETTINGS);
634 removeHeader = false;
639 mControlsParent.setTitle(null);
643 private void addControl(int pageSummary, int actionTitle, final int action) {
644 Preference pref = new Preference(getActivity());
645 pref.setTitle(actionTitle);
646 pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
648 public boolean onPreferenceClick(Preference preference) {
653 mControlsParent.addPreference(pref);
656 private void fillMessagesSection(int uid) {
657 boolean removeHeader = true;
658 switch (mDrainType) {
660 addMessage(R.string.battery_msg_unaccounted);
661 removeHeader = false;
665 mMessagesParent.setTitle(null);
669 private void addMessage(int message) {
670 addHorizontalPreference(mMessagesParent, getString(message), null);
673 private void removePackagesSection() {
674 getPreferenceScreen().removePreference(mPackagesParent);
677 private void killProcesses() {
678 if (mPackages == null) return;
679 ActivityManager am = (ActivityManager)getActivity().getSystemService(
680 Context.ACTIVITY_SERVICE);
681 final int userId = UserHandle.getUserId(mUid);
682 for (int i = 0; i < mPackages.length; i++) {
683 am.forceStopPackageAsUser(mPackages[i], userId);
688 private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
690 public void onReceive(Context context, Intent intent) {
691 mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
695 private void checkForceStop() {
696 if (mPackages == null || mUid < Process.FIRST_APPLICATION_UID) {
697 mForceStopButton.setEnabled(false);
700 for (int i = 0; i < mPackages.length; i++) {
701 if (mDpm.packageHasActiveAdmins(mPackages[i])) {
702 mForceStopButton.setEnabled(false);
706 for (int i = 0; i < mPackages.length; i++) {
708 ApplicationInfo info = mPm.getApplicationInfo(mPackages[i], 0);
709 if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
710 mForceStopButton.setEnabled(true);
713 } catch (PackageManager.NameNotFoundException e) {
716 Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
717 Uri.fromParts("package", mPackages[0], null));
718 intent.putExtra(Intent.EXTRA_PACKAGES, mPackages);
719 intent.putExtra(Intent.EXTRA_UID, mUid);
720 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mUid));
721 getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
722 Activity.RESULT_CANCELED, null, null);
725 private void reportBatteryUse() {
726 if (mPackages == null) return;
728 ApplicationErrorReport report = new ApplicationErrorReport();
729 report.type = ApplicationErrorReport.TYPE_BATTERY;
730 report.packageName = mPackages[0];
731 report.installerPackageName = mInstaller.getPackageName();
732 report.processName = mPackages[0];
733 report.time = System.currentTimeMillis();
734 report.systemApp = (mApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
736 final Bundle args = getArguments();
737 ApplicationErrorReport.BatteryInfo batteryInfo = new ApplicationErrorReport.BatteryInfo();
738 batteryInfo.usagePercent = args.getInt(EXTRA_PERCENT, 1);
739 batteryInfo.durationMicros = args.getLong(EXTRA_USAGE_DURATION, 0);
740 batteryInfo.usageDetails = args.getString(EXTRA_REPORT_DETAILS);
741 batteryInfo.checkinDetails = args.getString(EXTRA_REPORT_CHECKIN_DETAILS);
742 report.batteryInfo = batteryInfo;
744 Intent result = new Intent(Intent.ACTION_APP_ERROR);
745 result.setComponent(mInstaller);
746 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
747 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
748 startActivity(result);
751 private void fillPackagesSection(int uid) {
753 removePackagesSection();
756 if (mPackages == null || mPackages.length < 2) {
757 removePackagesSection();
761 PackageManager pm = getPackageManager();
762 // Convert package names to user-facing labels where possible
763 for (int i = 0; i < mPackages.length; i++) {
765 ApplicationInfo ai = pm.getApplicationInfo(mPackages[i], 0);
766 CharSequence label = ai.loadLabel(pm);
768 mPackages[i] = label.toString();
770 addHorizontalPreference(mPackagesParent, mPackages[i], null);
771 } catch (NameNotFoundException e) {