Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddba9667 authored by jackqdyulei's avatar jackqdyulei
Browse files

Revamp the battery usage details page.

This cl adds AdvancedPowerUsageDetail to show the usage details page.
The AdvancedPowerUsageDetail contains all the needed ui components:
1. App Header
2. Two buttons
3. Usage breakdown preference category
4. Power management preference category

This cl also adds preference controller for two buttons but the
detail implementation will be added in the following cl.

Following cl will also remove previous detail page.

Bug: 35810915
Test: RunSettingsRoboTests
Change-Id: I17f95d1288762094671c0f148fa73367e51f175e
parent cb253946
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -4417,8 +4417,12 @@
    <!-- Title for the background activity setting, which allows a user to control whether an app can run in the background [CHAR_LIMIT=40] -->
    <string name="background_activity_title">Background activity</string>
    <!-- Summary for the background activity [CHAR_LIMIT=120] -->
    <string name="background_activity_summary">Allow the app to run in the background</string>
    <!-- Summary for the background activity when it is on [CHAR_LIMIT=120] -->
    <string name="background_activity_summary_on">App can run in the background when not in use</string>
    <!-- Summary for the background activity when it is off [CHAR_LIMIT=120] -->
    <string name="background_activity_summary_off">App\'s background activity is limited when not in use</string>
    <!-- Summary for the background activity when it is disabled [CHAR_LIMIT=120] -->
    <string name="background_activity_summary_disabled">App not allowed to run in background</string>
    <!-- Title for the screen usage in power use UI [CHAR_LIMIT=40] -->
    <string name="device_screen_usage">Screen usage since full charge</string>
@@ -4632,13 +4636,25 @@
    <!-- Description for battery usage info for an app, i.e. 60% used by facebook. [CHAR LIMIT=60] -->
    <string name="battery_used_by"><xliff:g id="percent">%1$s</xliff:g> used by <xliff:g id="app">%2$s</xliff:g></string>
    <!-- Description for percentage of battery usage for an app, i.e. Screen: 30% of overall battery. [CHAR LIMIT=60] -->
    <string name="battery_overall_usage">%1$s of overall battery</string>
    <string name="battery_overall_usage"><xliff:g id="percent">%1$s</xliff:g> of overall battery</string>
    <!-- Description for battery usage detail information since last full charge. [CHAR LIMIT=120] -->
    <string name="battery_detail_since_full_charge">Breakdown since last full charge</string>
    <!-- Title for usage time since last full charge. [CHAR LIMIT=60] -->
    <string name="battery_last_full_charge">Last full charge</string>
    <!-- Description for text in battery footer. [CHAR LIMIT=120] -->
    <string name="battery_footer_summary">Remaining battery time is approximate and can change based on usage</string>
    <!-- Title for battery usage detail in foreground. [CHAR LIMIT=80] -->
    <string name="battery_detail_foreground">While using app</string>
    <!-- Title for battery usage detail in background. [CHAR LIMIT=80] -->
    <string name="battery_detail_background">While in background</string>
    <!-- Title for battery usage amount by this app. [CHAR LIMIT=80] -->
    <string name="battery_detail_power_usage">Battery usage</string>
    <!-- Description for battery usage amount, i.e. 16% of overall app usage(340 mAh). [CHAR LIMIT=120] -->
    <string name="battery_detail_power_percentage"><xliff:g id="percent">%1$s</xliff:g> of total app usage (<xliff:g id="power">%2$d</xliff:g>mAh)</string>
    <!-- Title for the battery usage group, which means all the battery data are calculated 'since full charge' [CHAR LIMIT=40] -->
    <string name ="battery_detail_info_title">Since full charge</string>
    <!-- Title for the battery management group [CHAR LIMIT=40] -->
    <string name ="battery_detail_manage_title">Manage battery usage</string>
    <!-- Description for battery time left, i.e. 50min Estimated time left. [CHAR LIMIT=80]-->
    <string name="estimated_time_left">Estimated time left</string>
+65 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright (C) 2017 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.
  -->

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <com.android.settings.applications.LayoutPreference
        android:key="header_view"
        android:layout="@layout/app_details"
        android:selectable="false"
        android:order="-10000"/>

    <com.android.settings.applications.LayoutPreference
        android:key="action_buttons"
        android:layout="@layout/app_action_buttons"
        android:selectable="false"
        android:order="-9999"/>

    <PreferenceCategory
        android:title="@string/battery_detail_info_title">

        <Preference
            android:key="app_usage_foreground"
            android:title="@string/battery_detail_foreground"/>

        <Preference
            android:key="app_usage_background"
            android:title="@string/battery_detail_background"/>

        <Preference
            android:key="app_power_usage"
            android:title="@string/battery_detail_power_usage"/>

    </PreferenceCategory>

    <PreferenceCategory
        android:title="@string/battery_detail_manage_title">

        <SwitchPreference
            android:key="background_activity"
            android:title="@string/background_activity_title"
            android:selectable="true"/>

        <Preference
            android:key="battery_optimization"
            android:title="@string/battery_detail_background"
            android:summary="@string/high_power_off"
            android:selectable="true"/>

    </PreferenceCategory>

</PreferenceScreen>
 No newline at end of file
+12 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.provider.Settings;
import android.service.persistentdata.PersistentDataBlockManager;
import android.support.annotation.StringRes;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceManager;
@@ -1241,6 +1242,17 @@ public final class Utils extends com.android.settingslib.Utils {
        return isVolumeValid(volume) ? volume : null;
    }

    /**
     * Return the resource id to represent the install status for an app
     */
    @StringRes
    public static int getInstallationStatus(ApplicationInfo info) {
        if ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
            return R.string.not_installed;
        }
        return info.enabled ? R.string.installed : R.string.disabled;
    }

    private static boolean isVolumeValid(VolumeInfo volume) {
        return (volume != null) && (volume.getType() == VolumeInfo.TYPE_PRIVATE)
                && volume.isMountedReadable();
+1 −9
Original line number Diff line number Diff line
@@ -546,7 +546,7 @@ public class InstalledAppDetails extends AppInfoBase
            .newAppHeaderController(this, appSnippet)
            .setLabel(mAppEntry)
            .setIcon(mAppEntry)
            .setSummary(getString(getInstallationStatus(mAppEntry.info)))
            .setSummary(getString(Utils.getInstallationStatus(mAppEntry.info)))
            .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
            .done(false /* rebindActions */);
        mVersionPreference.setSummary(getString(R.string.version_text, pkgInfo.versionName));
@@ -574,14 +574,6 @@ public class InstalledAppDetails extends AppInfoBase
        return showIt;
    }

    @VisibleForTesting
    int getInstallationStatus(ApplicationInfo info) {
        if ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
            return R.string.not_installed;
        }
        return info.enabled ? R.string.installed : R.string.disabled;
    }

    private boolean signaturesMatch(String pkg1, String pkg2) {
        if (pkg1 != null && pkg2 != null) {
            try {
+204 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.content.Context;
import android.os.BatteryStats;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference;
import android.view.View;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.applications.AppHeaderController;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;

import java.util.ArrayList;
import java.util.List;

/**
 * Power usage detail fragment for each app, this fragment contains
 *
 * 1. Detail battery usage information for app(i.e. usage time, usage amount)
 * 2. Battery related controls for app(i.e uninstall, force stop)
 *
 * This fragment will replace {@link PowerUsageDetail}
 */
public class AdvancedPowerUsageDetail extends PowerUsageBase {

    public static final String TAG = "AdvancedPowerUsageDetail";
    public static final String EXTRA_UID = "extra_uid";
    public static final String EXTRA_PACKAGE_NAME = "extra_package_name";
    public static final String EXTRA_FOREGROUND_TIME = "extra_foreground_time";
    public static final String EXTRA_BACKGROUND_TIME = "extra_background_time";
    public static final String EXTRA_LABEL = "extra_label";
    public static final String EXTRA_ICON_ID = "extra_icon_id";
    public static final String EXTRA_POWER_USAGE_PERCENT = "extra_power_usage_percent";
    public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount";

    private static final String KEY_PREF_FOREGROUND = "app_usage_foreground";
    private static final String KEY_PREF_BACKGROUND = "app_usage_background";
    private static final String KEY_PREF_POWER_USAGE = "app_power_usage";
    private static final String KEY_PREF_HEADER = "header_view";

    @VisibleForTesting
    LayoutPreference mHeaderPreference;
    @VisibleForTesting
    ApplicationsState mState;
    @VisibleForTesting
    ApplicationsState.AppEntry mAppEntry;

    private Preference mForegroundPreference;
    private Preference mBackgroundPreference;
    private Preference mPowerUsagePreference;

    public static void startBatteryDetailPage(SettingsActivity caller, PreferenceFragment fragment,
            BatteryStatsHelper helper, int which, BatteryEntry entry, String usagePercent) {
        // Initialize mStats if necessary.
        helper.getStats();

        final Bundle args = new Bundle();
        final BatterySipper sipper = entry.sipper;
        final BatteryStats.Uid uid = sipper.uidObj;

        final long backgroundTimeMs = BatteryUtils.getProcessTimeMs(
                BatteryUtils.StatusType.BACKGROUND, uid, which);
        final long foregroundTimeMs = BatteryUtils.getProcessTimeMs(
                BatteryUtils.StatusType.FOREGROUND, uid, which);

        if (ArrayUtils.isEmpty(sipper.mPackages)) {
            // populate data for system app
            args.putString(EXTRA_LABEL, entry.getLabel());
            args.putInt(EXTRA_ICON_ID, entry.iconId);
            args.putString(EXTRA_PACKAGE_NAME, null);
        } else {
            // populate data for normal app
            args.putString(EXTRA_PACKAGE_NAME, sipper.mPackages[0]);
        }

        args.putInt(EXTRA_UID, sipper.getUid());
        args.putLong(EXTRA_BACKGROUND_TIME, backgroundTimeMs);
        args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs);
        args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent);
        args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) sipper.totalPowerMah);

        caller.startPreferencePanelAsUser(fragment, AdvancedPowerUsageDetail.class.getName(), args,
                R.string.details_title, null, new UserHandle(UserHandle.myUserId()));
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
        mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
        mPowerUsagePreference = findPreference(KEY_PREF_POWER_USAGE);
        mHeaderPreference = (LayoutPreference) findPreference(KEY_PREF_HEADER);
        mState = ApplicationsState.getInstance(getActivity().getApplication());

        final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
        if (packageName != null) {
            mAppEntry = mState.getEntry(packageName, UserHandle.myUserId());
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        initHeader();

        final Bundle bundle = getArguments();
        final Context context = getContext();

        final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
        final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
        final String usagePercent = bundle.getString(EXTRA_POWER_USAGE_PERCENT);
        final int powerMah = bundle.getInt(EXTRA_POWER_USAGE_AMOUNT);
        mForegroundPreference.setSummary(Utils.formatElapsedTime(context, foregroundTimeMs, false));
        mBackgroundPreference.setSummary(Utils.formatElapsedTime(context, backgroundTimeMs, false));
        mPowerUsagePreference.setSummary(
                getString(R.string.battery_detail_power_percentage, usagePercent, powerMah));
    }

    @VisibleForTesting
    void initHeader() {
        final View appSnippet = mHeaderPreference.findViewById(R.id.app_snippet);
        final Context context = getContext();
        final Bundle bundle = getArguments();
        AppHeaderController controller = FeatureFactory.getFactory(context)
                .getApplicationFeatureProvider(context)
                .newAppHeaderController(this, appSnippet)
                .setButtonActions(AppHeaderController.ActionType.ACTION_NONE,
                        AppHeaderController.ActionType.ACTION_NONE);

        if (mAppEntry == null) {
            controller.setLabel(bundle.getString(EXTRA_LABEL));
            controller.setIcon(getContext().getDrawable(bundle.getInt(EXTRA_ICON_ID)));
        } else {
            mState.ensureIcon(mAppEntry);
            controller.setLabel(mAppEntry);
            controller.setIcon(mAppEntry);
            controller.setSummary(getString(Utils.getInstallationStatus(mAppEntry.info)));
        }

        controller.done(true /* rebindActions */);
    }

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

    @Override
    protected String getLogTag() {
        return TAG;
    }

    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.power_usage_detail_ia;
    }

    @Override
    protected List<PreferenceController> getPreferenceControllers(Context context) {
        final List<PreferenceController> controllers = new ArrayList<>();
        final Bundle bundle = getArguments();
        final int uid = bundle.getInt(EXTRA_UID, 0);
        final String packageName = bundle.getString(EXTRA_PACKAGE_NAME);

        controllers.add(new BackgroundActivityPreferenceController(context, uid));
        controllers.add(new BatteryOptimizationPreferenceController(
                (SettingsActivity) getActivity(), this));
        controllers.add(
                new AppButtonsPreferenceController(getActivity(), getLifecycle(), packageName));

        return controllers;
    }
}
Loading