/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.fuelgauge;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ApplicationErrorReport;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceCategory;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatterySipper.DrainType;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.util.FastPrintWriter;
import com.android.settings.AppHeader;
import com.android.settings.DisplaySettings;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.WirelessSettings;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.location.LocationSettings;
import com.android.settings.wifi.WifiSettings;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickListener {

    // Note: Must match the sequence of the DrainType
    private static int[] sDrainTypeDesciptions = new int[] {
        R.string.battery_desc_standby,
        R.string.battery_desc_radio,
        R.string.battery_desc_voice,
        R.string.battery_desc_wifi,
        R.string.battery_desc_bluetooth,
        R.string.battery_desc_flashlight,
        R.string.battery_desc_display,
        R.string.battery_desc_apps,
        R.string.battery_desc_users,
        R.string.battery_desc_unaccounted,
        R.string.battery_desc_overcounted,
        R.string.battery_desc_camera,
    };

    public static void startBatteryDetailPage(
            SettingsActivity caller, BatteryStatsHelper helper, int statsType, BatteryEntry entry,
            boolean showLocationButton, boolean includeAppInfo) {
        // Initialize mStats if necessary.
        helper.getStats();

        final int dischargeAmount = helper.getStats().getDischargeAmount(statsType);
        Bundle args = new Bundle();
        args.putString(PowerUsageDetail.EXTRA_TITLE, entry.name);
        args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int)
                ((entry.sipper.totalPowerMah * dischargeAmount / helper.getTotalPower()) + .5));
        args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int)
                Math.ceil(entry.sipper.totalPowerMah * 100 / helper.getMaxPower()));
        args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, helper.getStatsPeriod());
        args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, entry.defaultPackageName);
        args.putInt(PowerUsageDetail.EXTRA_ICON_ID, entry.iconId);
        args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, entry.sipper.noCoveragePercent);
        if (entry.sipper.uidObj != null) {
            args.putInt(PowerUsageDetail.EXTRA_UID, entry.sipper.uidObj.getUid());
        }
        args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, entry.sipper.drainType);
        args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton);
        args.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, !includeAppInfo);

        int userId = UserHandle.myUserId();
        int[] types;
        double[] values;
        switch (entry.sipper.drainType) {
            case APP:
            case USER:
            {
                BatteryStats.Uid uid = entry.sipper.uidObj;
                types = new int[] {
                    R.string.usage_type_cpu,
                    R.string.usage_type_cpu_foreground,
                    R.string.usage_type_wake_lock,
                    R.string.usage_type_gps,
                    R.string.usage_type_wifi_running,
                    R.string.usage_type_data_recv,
                    R.string.usage_type_data_send,
                    R.string.usage_type_radio_active,
                    R.string.usage_type_data_wifi_recv,
                    R.string.usage_type_data_wifi_send,
                    R.string.usage_type_audio,
                    R.string.usage_type_video,
                    R.string.usage_type_camera,
                    R.string.usage_type_flashlight,
                    R.string.usage_type_computed_power,
                };
                values = new double[] {
                    entry.sipper.cpuTimeMs,
                    entry.sipper.cpuFgTimeMs,
                    entry.sipper.wakeLockTimeMs,
                    entry.sipper.gpsTimeMs,
                    entry.sipper.wifiRunningTimeMs,
                    entry.sipper.mobileRxPackets,
                    entry.sipper.mobileTxPackets,
                    entry.sipper.mobileActive,
                    entry.sipper.wifiRxPackets,
                    entry.sipper.wifiTxPackets,
                    0,
                    0,
                    entry.sipper.cameraTimeMs,
                    entry.sipper.flashlightTimeMs,
                    entry.sipper.totalPowerMah,
                };

                if (entry.sipper.drainType == BatterySipper.DrainType.APP) {
                    Writer result = new StringWriter();
                    PrintWriter printWriter = new FastPrintWriter(result, false, 1024);
                    helper.getStats().dumpLocked(caller, printWriter, "", helper.getStatsType(),
                            uid.getUid());
                    printWriter.flush();
                    args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString());

                    result = new StringWriter();
                    printWriter = new FastPrintWriter(result, false, 1024);
                    helper.getStats().dumpCheckinLocked(caller, printWriter, helper.getStatsType(),
                            uid.getUid());
                    printWriter.flush();
                    args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS,
                            result.toString());
                    if (uid.getUid() != 0) {
                        userId = UserHandle.getUserId(uid.getUid());
                    }
                }
            }
            break;
            case CELL:
            {
                types = new int[] {
                    R.string.usage_type_on_time,
                    R.string.usage_type_no_coverage,
                    R.string.usage_type_radio_active,
                    R.string.usage_type_computed_power,
                };
                values = new double[] {
                    entry.sipper.usageTimeMs,
                    entry.sipper.noCoveragePercent,
                    entry.sipper.mobileActive,
                    entry.sipper.totalPowerMah,
                };
            }
            break;
            case WIFI:
            {
                types = new int[] {
                    R.string.usage_type_wifi_running,
                    R.string.usage_type_cpu,
                    R.string.usage_type_cpu_foreground,
                    R.string.usage_type_wake_lock,
                    R.string.usage_type_data_recv,
                    R.string.usage_type_data_send,
                    R.string.usage_type_data_wifi_recv,
                    R.string.usage_type_data_wifi_send,
                    R.string.usage_type_computed_power,
                };
                values = new double[] {
                    entry.sipper.wifiRunningTimeMs,
                    entry.sipper.cpuTimeMs,
                    entry.sipper.cpuFgTimeMs,
                    entry.sipper.wakeLockTimeMs,
                    entry.sipper.mobileRxPackets,
                    entry.sipper.mobileTxPackets,
                    entry.sipper.wifiRxPackets,
                    entry.sipper.wifiTxPackets,
                    entry.sipper.totalPowerMah,
                };
            } break;
            case BLUETOOTH:
            {
                types = new int[] {
                    R.string.usage_type_on_time,
                    R.string.usage_type_cpu,
                    R.string.usage_type_cpu_foreground,
                    R.string.usage_type_wake_lock,
                    R.string.usage_type_data_recv,
                    R.string.usage_type_data_send,
                    R.string.usage_type_data_wifi_recv,
                    R.string.usage_type_data_wifi_send,
                    R.string.usage_type_computed_power,
                };
                values = new double[] {
                    entry.sipper.usageTimeMs,
                    entry.sipper.cpuTimeMs,
                    entry.sipper.cpuFgTimeMs,
                    entry.sipper.wakeLockTimeMs,
                    entry.sipper.mobileRxPackets,
                    entry.sipper.mobileTxPackets,
                    entry.sipper.wifiRxPackets,
                    entry.sipper.wifiTxPackets,
                    entry.sipper.totalPowerMah,
                };
            } break;
            case UNACCOUNTED:
            {
                types = new int[] {
                    R.string.usage_type_total_battery_capacity,
                    R.string.usage_type_computed_power,
                    R.string.usage_type_actual_power,
                };
                values = new double[] {
                    helper.getPowerProfile().getBatteryCapacity(),
                    helper.getComputedPower(),
                    helper.getMinDrainedPower(),
                };
            } break;
            case OVERCOUNTED:
            {
                types = new int[] {
                    R.string.usage_type_total_battery_capacity,
                    R.string.usage_type_computed_power,
                    R.string.usage_type_actual_power,
                };
                values = new double[] {
                    helper.getPowerProfile().getBatteryCapacity(),
                    helper.getComputedPower(),
                    helper.getMaxDrainedPower(),
                };
            } break;
            default:
            {
                types = new int[] {
                    R.string.usage_type_on_time,
                    R.string.usage_type_computed_power,
                };
                values = new double[] {
                    entry.sipper.usageTimeMs,
                    entry.sipper.totalPowerMah,
                };
            }
        }
        args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types);
        args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values);

        caller.startPreferencePanelAsUser(PowerUsageDetail.class.getName(), args,
                R.string.details_title, null, new UserHandle(userId));
    }

    public static final int ACTION_DISPLAY_SETTINGS = 1;
    public static final int ACTION_WIFI_SETTINGS = 2;
    public static final int ACTION_BLUETOOTH_SETTINGS = 3;
    public static final int ACTION_WIRELESS_SETTINGS = 4;
    public static final int ACTION_APP_DETAILS = 5;
    public static final int ACTION_LOCATION_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;

    public static final String EXTRA_TITLE = "title";
    public static final String EXTRA_PERCENT = "percent";
    public static final String EXTRA_GAUGE = "gauge";
    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
    public static final String EXTRA_ICON_PACKAGE = "iconPackage"; // String
    public static final String EXTRA_NO_COVERAGE = "noCoverage";
    public static final String EXTRA_ICON_ID = "iconId"; // Int
    public static final String EXTRA_SHOW_LOCATION_BUTTON = "showLocationButton";  // Boolean

    private static final String TAG = "PowerUsageDetail";

    private static final String KEY_DETAILS_PARENT = "details_parent";
    private static final String KEY_CONTROLS_PARENT = "controls_parent";
    private static final String KEY_MESSAGES_PARENT = "messages_parent";
    private static final String KEY_PACKAGES_PARENT = "packages_parent";
    private static final String KEY_TWO_BUTTONS = "two_buttons";
    private static final String KEY_HIGH_POWER = "high_power";

    private PackageManager mPm;
    private DevicePolicyManager mDpm;
    private int mUsageSince;
    private int[] mTypes;
    private int mUid;
    private double[] mValues;
    private Button mForceStopButton;
    private Button mReportButton;
    private long mStartTime;
    private BatterySipper.DrainType mDrainType;
    private double mNoCoverage; // Percentage of time that there was no coverage

    private PreferenceCategory mDetailsParent;
    private PreferenceCategory mControlsParent;
    private PreferenceCategory mMessagesParent;
    private PreferenceCategory mPackagesParent;

    private boolean mUsesGps;
    private boolean mShowLocationButton;

    private String[] mPackages;

    ApplicationInfo mApp;
    ComponentName mInstaller;
    private Preference mHighPower;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        mPm = getActivity().getPackageManager();
        mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);

        addPreferencesFromResource(R.xml.power_usage_details);
        mDetailsParent = (PreferenceCategory) findPreference(KEY_DETAILS_PARENT);
        mControlsParent = (PreferenceCategory) findPreference(KEY_CONTROLS_PARENT);
        mMessagesParent = (PreferenceCategory) findPreference(KEY_MESSAGES_PARENT);
        mPackagesParent = (PreferenceCategory) findPreference(KEY_PACKAGES_PARENT);

        createDetails();
    }

    @Override
    protected int getMetricsCategory() {
        return MetricsEvent.FUELGAUGE_POWER_USAGE_DETAIL;
    }

    @Override
    public void onResume() {
        super.onResume();
        mStartTime = android.os.Process.getElapsedCpuTime();
        checkForceStop();
        if (mHighPower != null) {
            mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
        }

        setupHeader();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (mHighPower != null) {
            mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
        }
    }

    private void createDetails() {
        final Bundle args = getArguments();
        Context context = getActivity();
        mUsageSince = args.getInt(EXTRA_USAGE_SINCE, USAGE_SINCE_UNPLUGGED);
        mUid = args.getInt(EXTRA_UID, 0);
        mPackages = context.getPackageManager().getPackagesForUid(mUid);
        mDrainType = (BatterySipper.DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
        mNoCoverage = args.getDouble(EXTRA_NO_COVERAGE, 0);
        mShowLocationButton = args.getBoolean(EXTRA_SHOW_LOCATION_BUTTON);

        mTypes = args.getIntArray(EXTRA_DETAIL_TYPES);
        mValues = args.getDoubleArray(EXTRA_DETAIL_VALUES);

        LayoutPreference twoButtons = (LayoutPreference) findPreference(KEY_TWO_BUTTONS);
        mForceStopButton = (Button) twoButtons.findViewById(R.id.left_button);
        mReportButton = (Button) twoButtons.findViewById(R.id.right_button);
        mForceStopButton.setEnabled(false);

        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);

            if (mPackages != null && mPackages.length > 0) {
                try {
                    mApp = context.getPackageManager().getApplicationInfo(
                            mPackages[0], 0);
                } catch (NameNotFoundException e) {
                }
            } else {
                Log.d(TAG, "No packages!!");
            }
            // check if error reporting is enabled in secure settings
            int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
                    android.provider.Settings.Global.SEND_ACTION_APP_ERROR, 0);
            if (enabled != 0) {
                if (mApp != null) {
                    mInstaller = ApplicationErrorReport.getErrorReportReceiver(
                            context, mPackages[0], mApp.flags);
                }
                mReportButton.setEnabled(mInstaller != null);
            } else {
                removePreference(KEY_TWO_BUTTONS);
            }
            if (mApp != null
                    && PowerWhitelistBackend.getInstance().isWhitelisted(mApp.packageName)) {
                mHighPower = findPreference(KEY_HIGH_POWER);
                mHighPower.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                    @Override
                    public boolean onPreferenceClick(Preference preference) {
                        HighPowerDetail.show(PowerUsageDetail.this, mApp.packageName, 0, false);
                        return true;
                    }
                });
            } else {
                mControlsParent.removePreference(findPreference(KEY_HIGH_POWER));
            }
        } else {
            removePreference(KEY_TWO_BUTTONS);
            mControlsParent.removePreference(findPreference(KEY_HIGH_POWER));
        }

        refreshStats();

        fillDetailsSection();
        fillPackagesSection(mUid);
        fillControlsSection(mUid);
        fillMessagesSection(mUid);
    }

    private void setupHeader() {
        final Bundle args = getArguments();
        String title = args.getString(EXTRA_TITLE);
        String pkg = args.getString(EXTRA_ICON_PACKAGE);
        int iconId = args.getInt(EXTRA_ICON_ID, 0);
        Drawable appIcon = null;
        int uid = -1;
        final PackageManager pm = getActivity().getPackageManager();

        if (!TextUtils.isEmpty(pkg)) {
            try {
                ApplicationInfo ai = pm.getPackageInfo(pkg, 0).applicationInfo;
                if (ai != null) {
                    appIcon = ai.loadIcon(pm);
                    uid = ai.uid;
                }
            } catch (NameNotFoundException nnfe) {
                // Use default icon
            }
        } else if (iconId != 0) {
            appIcon = getActivity().getDrawable(iconId);
        }
        if (appIcon == null) {
            appIcon = getActivity().getPackageManager().getDefaultActivityIcon();
        }

        if (pkg == null && mPackages != null) {
            pkg = mPackages[0];
        }
        AppHeader.createAppHeader(this, appIcon, title, pkg, uid,
                mDrainType != DrainType.APP ? android.R.color.white : 0);
    }

    public void onClick(View v) {
        doAction((Integer) v.getTag());
    }

    // utility method used to start sub activity
    private void startApplicationDetailsActivity() {
        // start new fragment to display extended information
        Bundle args = new Bundle();
        args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackages[0]);

        SettingsActivity sa = (SettingsActivity) getActivity();
        sa.startPreferencePanel(InstalledAppDetails.class.getName(), args,
                R.string.application_info_label, null, null, 0);
    }

    private void doAction(int action) {
        SettingsActivity sa = (SettingsActivity)getActivity();
        switch (action) {
            case ACTION_DISPLAY_SETTINGS:
                sa.startPreferencePanel(DisplaySettings.class.getName(), null,
                        R.string.display_settings_title, null, null, 0);
                break;
            case ACTION_WIFI_SETTINGS:
                sa.startPreferencePanel(WifiSettings.class.getName(), null,
                        R.string.wifi_settings, null, null, 0);
                break;
            case ACTION_BLUETOOTH_SETTINGS:
                sa.startPreferencePanel(BluetoothSettings.class.getName(), null,
                        R.string.bluetooth_settings, null, null, 0);
                break;
            case ACTION_WIRELESS_SETTINGS:
                sa.startPreferencePanel(WirelessSettings.class.getName(), null,
                        R.string.radio_controls_title, null, null, 0);
                break;
            case ACTION_APP_DETAILS:
                startApplicationDetailsActivity();
                break;
            case ACTION_LOCATION_SETTINGS:
                sa.startPreferencePanel(LocationSettings.class.getName(), null,
                        R.string.location_settings_title, null, null, 0);
                break;
            case ACTION_FORCE_STOP:
                killProcesses();
                break;
            case ACTION_REPORT:
                reportBatteryUse();
                break;
        }
    }

    private void fillDetailsSection() {
        if (mTypes != null && mValues != null) {
            for (int i = 0; i < mTypes.length; i++) {
                // Only add an item if the time is greater than zero
                if (mValues[i] <= 0) continue;
                final String label = getString(mTypes[i]);
                String value = null;
                switch (mTypes[i]) {
                    case R.string.usage_type_data_recv:
                    case R.string.usage_type_data_send:
                    case R.string.usage_type_data_wifi_recv:
                    case R.string.usage_type_data_wifi_send:
                        final long packets = (long) (mValues[i]);
                        value = Long.toString(packets);
                        break;
                    case R.string.usage_type_no_coverage:
                        final int percentage = (int) Math.floor(mValues[i]);
                        value = Utils.formatPercentage(percentage);
                        break;
                    case R.string.usage_type_total_battery_capacity:
                    case R.string.usage_type_computed_power:
                    case R.string.usage_type_actual_power:
                        value = getActivity().getString(R.string.mah, (long)(mValues[i]));
                        break;
                    case R.string.usage_type_gps:
                        mUsesGps = true;
                        // Fall through
                    default:
                        value = Utils.formatElapsedTime(getActivity(), mValues[i], true);
                }
                addHorizontalPreference(mDetailsParent, label, value);
            }
        }
    }

    private void addHorizontalPreference(PreferenceCategory parent, CharSequence title,
            CharSequence summary) {
        Preference pref = new Preference(getPrefContext());
        pref.setLayoutResource(R.layout.horizontal_preference);
        pref.setTitle(title);
        pref.setSummary(summary);
        pref.setSelectable(false);
        parent.addPreference(pref);
    }

    private void fillControlsSection(int uid) {
        PackageManager pm = getActivity().getPackageManager();
        String[] packages = pm.getPackagesForUid(uid);
        PackageInfo pi = null;
        try {
            pi = packages != null ? pm.getPackageInfo(packages[0], 0) : null;
        } catch (NameNotFoundException nnfe) { /* Nothing */ }
        ApplicationInfo ai = pi != null? pi.applicationInfo : null;

        boolean removeHeader = true;
        switch (mDrainType) {
            case APP:
                // If it is a Java application and only one package is associated with the Uid
                if (packages != null && packages.length == 1) {
                    addControl(R.string.battery_action_app_details,
                            R.string.battery_sugg_apps_info, ACTION_APP_DETAILS);
                    removeHeader = false;
                    // If the application has a settings screen, jump to  that
                    // TODO:
                }
                // If power usage detail page is launched from location page, suppress "Location"
                // button to prevent circular loops.
                if (mUsesGps && mShowLocationButton) {
                    addControl(R.string.location_settings_title,
                            R.string.battery_sugg_apps_gps, ACTION_LOCATION_SETTINGS);
                    removeHeader = false;
                }
                break;
            case SCREEN:
                addControl(R.string.display_settings,
                        R.string.battery_sugg_display,
                        ACTION_DISPLAY_SETTINGS);
                removeHeader = false;
                break;
            case WIFI:
                addControl(R.string.wifi_settings,
                        R.string.battery_sugg_wifi,
                        ACTION_WIFI_SETTINGS);
                removeHeader = false;
                break;
            case BLUETOOTH:
                addControl(R.string.bluetooth_settings,
                        R.string.battery_sugg_bluetooth_basic,
                        ACTION_BLUETOOTH_SETTINGS);
                removeHeader = false;
                break;
            case CELL:
                if (mNoCoverage > 10) {
                    addControl(R.string.radio_controls_title,
                            R.string.battery_sugg_radio,
                            ACTION_WIRELESS_SETTINGS);
                    removeHeader = false;
                }
                break;
        }
        if (removeHeader) {
            mControlsParent.setTitle(null);
        }
    }

    private void addControl(int pageSummary, int actionTitle, final int action) {
        Preference pref = new Preference(getPrefContext());
        pref.setTitle(actionTitle);
        pref.setLayoutResource(R.layout.horizontal_preference);
        pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                doAction(action);
                return true;
            }
        });
        mControlsParent.addPreference(pref);
    }

    private void fillMessagesSection(int uid) {
        boolean removeHeader = true;
        switch (mDrainType) {
            case UNACCOUNTED:
                addMessage(R.string.battery_msg_unaccounted);
                removeHeader = false;
                break;
        }
        if (removeHeader) {
            mMessagesParent.setTitle(null);
        }
    }

    private void addMessage(int message) {
        addHorizontalPreference(mMessagesParent, getString(message), null);
    }

    private void removePackagesSection() {
        getPreferenceScreen().removePreference(mPackagesParent);
    }

    private void killProcesses() {
        if (mPackages == null) return;
        ActivityManager am = (ActivityManager)getActivity().getSystemService(
                Context.ACTIVITY_SERVICE);
        final int userId = UserHandle.getUserId(mUid);
        for (int i = 0; i < mPackages.length; i++) {
            am.forceStopPackageAsUser(mPackages[i], userId);
        }
        checkForceStop();
    }

    private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
        }
    };

    private void checkForceStop() {
        if (mPackages == null || mUid < Process.FIRST_APPLICATION_UID) {
            mForceStopButton.setEnabled(false);
            return;
        }
        for (int i = 0; i < mPackages.length; i++) {
            if (mDpm.packageHasActiveAdmins(mPackages[i])) {
                mForceStopButton.setEnabled(false);
                return;
            }
        }
        for (int i = 0; i < mPackages.length; i++) {
            try {
                ApplicationInfo info = mPm.getApplicationInfo(mPackages[i], 0);
                if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
                    mForceStopButton.setEnabled(true);
                    break;
                }
            } catch (PackageManager.NameNotFoundException e) {
            }
        }
        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);
        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mUid));
        getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
                Activity.RESULT_CANCELED, null, null);
    }

    private void reportBatteryUse() {
        if (mPackages == null) return;

        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;

        final Bundle args = getArguments();
        ApplicationErrorReport.BatteryInfo batteryInfo = new ApplicationErrorReport.BatteryInfo();
        batteryInfo.usagePercent = args.getInt(EXTRA_PERCENT, 1);
        batteryInfo.durationMicros = args.getLong(EXTRA_USAGE_DURATION, 0);
        batteryInfo.usageDetails = args.getString(EXTRA_REPORT_DETAILS);
        batteryInfo.checkinDetails = args.getString(EXTRA_REPORT_CHECKIN_DETAILS);
        report.batteryInfo = batteryInfo;

        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();
            return;
        }
        if (mPackages == null || mPackages.length < 2) {
            removePackagesSection();
            return;
        }

        PackageManager pm = getPackageManager();
        // Convert package names to user-facing labels where possible
        for (int i = 0; i < mPackages.length; i++) {
            try {
                ApplicationInfo ai = pm.getApplicationInfo(mPackages[i], 0);
                CharSequence label = ai.loadLabel(pm);
                if (label != null) {
                    mPackages[i] = label.toString();
                }
                addHorizontalPreference(mPackagesParent, mPackages[i], null);
            } catch (NameNotFoundException e) {
            }
        }
    }
}
