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

Commit 949dd581 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Replace battery usage breakdown list from tabs to dropdown list."

parents 3d5dfd5f 778a4b42
Loading
Loading
Loading
Loading
+7 −20
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2022 The Android Open Source Project
  ~ Copyright (C) 2023 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.
@@ -15,23 +14,11 @@
  ~ limitations under the License.
  -->

<LinearLayout
<Spinner
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:theme="@style/Theme.TabTheme"
    android:id="@+id/tab_container"
    android:clipToPadding="true"
    android:clipChildren="true"
    android:layout_width="match_parent"
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        style="@style/SettingsLibTabsStyle" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
    android:layout_marginStart="24dp"
    android:layout_marginTop="8dp"
    android:theme="@style/Widget.PopupWindow.Settings" />
+6 −6
Original line number Diff line number Diff line
@@ -5175,13 +5175,13 @@
    <!-- [CHAR_LIMIT=NONE] Accessibility content description for hourly battery chart view. -->
    <string name="hourly_battery_usage_chart">Hourly battery usage chart</string>
    <!-- [CHAR_LIMIT=NONE] Battery usage breakdown title since last full charge -->
    <string name="battery_usage_breakdown_title_since_last_full_charge">Usage proportional breakdown since last full charge</string>
    <string name="battery_usage_breakdown_title_since_last_full_charge">Battery usage since last full charge</string>
    <!-- [CHAR_LIMIT=NONE] Battery usage breakdown title for a selected slot -->
    <string name="battery_usage_breakdown_title_for_slot">Usage proportional breakdown for <xliff:g id="slot">%s</xliff:g></string>
    <!-- [CHAR_LIMIT=NONE] The tab title in the battery usage breakdown. -->
    <string name="battery_usage_app_tab">App</string>
    <!-- [CHAR_LIMIT=NONE] The tab title in the battery usage breakdown. -->
    <string name="battery_usage_system_tab">System</string>
    <string name="battery_usage_breakdown_title_for_slot">Battery usage for <xliff:g id="slot">%s</xliff:g></string>
    <!-- [CHAR_LIMIT=NONE] The spinner item text in the battery usage breakdown. -->
    <string name="battery_usage_spinner_breakdown_by_apps">Breakdown by apps</string>
    <!-- [CHAR_LIMIT=NONE] The spinner item text in the battery usage breakdown. -->
    <string name="battery_usage_spinner_breakdown_by_system">Breakdown by system</string>
    <!-- Process Stats strings -->
    <skip />
+2 −2
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@
            "com.android.settings.fuelgauge.batteryusage.BatteryUsageBreakdownController"
        settings:isPreferenceVisible="false">

        <com.android.settings.fuelgauge.batteryusage.TabPreference
            android:key="battery_usage_tab"
        <com.android.settings.fuelgauge.batteryusage.SpinnerPreference
            android:key="battery_usage_spinner"
            settings:isPreferenceVisible="false" />

        <PreferenceCategory
+31 −23
Original line number Diff line number Diff line
@@ -24,12 +24,13 @@ import android.os.Looper;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;

import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import androidx.viewpager2.widget.ViewPager2;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
@@ -55,7 +56,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
    private static final String TAG = "BatteryUsageBreakdownController";
    private static final String ROOT_PREFERENCE_KEY = "battery_usage_breakdown";
    private static final String FOOTER_PREFERENCE_KEY = "battery_usage_footer";
    private static final String TAB_PREFERENCE_KEY = "battery_usage_tab";
    private static final String SPINNER_PREFERENCE_KEY = "battery_usage_spinner";
    private static final String APP_LIST_PREFERENCE_KEY = "app_list";
    private static final String PACKAGE_NAME_NONE = "none";
    private static final int ENABLED_ICON_ALPHA = 255;
@@ -69,7 +70,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
    @VisibleForTesting
    final Map<String, Preference> mPreferenceCache = new HashMap<>();

    private int mTabPosition;
    private int mSpinnerPosition;
    private String mSlotTimestamp;

    @VisibleForTesting
@@ -77,7 +78,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
    @VisibleForTesting
    PreferenceCategory mRootPreference;
    @VisibleForTesting
    TabPreference mTabPreference;
    SpinnerPreference mSpinnerPreference;
    @VisibleForTesting
    PreferenceGroup mAppListPreferenceGroup;
    @VisibleForTesting
@@ -145,25 +146,32 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
        super.displayPreference(screen);
        mPrefContext = screen.getContext();
        mRootPreference = screen.findPreference(ROOT_PREFERENCE_KEY);
        mTabPreference = screen.findPreference(TAB_PREFERENCE_KEY);
        mSpinnerPreference = screen.findPreference(SPINNER_PREFERENCE_KEY);
        mAppListPreferenceGroup = screen.findPreference(APP_LIST_PREFERENCE_KEY);
        mFooterPreference = screen.findPreference(FOOTER_PREFERENCE_KEY);

        mAppListPreferenceGroup.setOrderingAsAdded(false);
        mTabPreference.initializeTabs(mFragment, new String[]{
                mPrefContext.getString(R.string.battery_usage_app_tab),
                mPrefContext.getString(R.string.battery_usage_system_tab)
        });
        mTabPreference.setOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        mSpinnerPreference.initializeSpinner(
                new String[]{
                        mPrefContext.getString(R.string.battery_usage_spinner_breakdown_by_apps),
                        mPrefContext.getString(R.string.battery_usage_spinner_breakdown_by_system)
                },
                new AdapterView.OnItemSelectedListener() {
                    @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                mTabPosition = position;
                    public void onItemSelected(
                            AdapterView<?> parent, View view, int position, long id) {
                        if (mSpinnerPosition != position) {
                            mSpinnerPosition = position;
                            mHandler.post(() -> {
                                removeAndCacheAllPreferences();
                                addAllPreferences();
                            });
                        }
                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {
                    }
                });
    }

@@ -182,7 +190,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
        mSlotTimestamp = slotTimestamp;

        showCategoryTitle(slotTimestamp);
        showTabAndAppList();
        showSpinnerAndAppList();
        showFooterPreference(isAllUsageDataEmpty);
    }

@@ -204,12 +212,12 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
        mFooterPreference.setVisible(true);
    }

    private void showTabAndAppList() {
    private void showSpinnerAndAppList() {
        removeAndCacheAllPreferences();
        if (mBatteryDiffData == null) {
            return;
        }
        mTabPreference.setVisible(true);
        mSpinnerPreference.setVisible(true);
        mAppListPreferenceGroup.setVisible(true);
        mHandler.post(() -> {
            addAllPreferences();
@@ -222,7 +230,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
            return;
        }
        final long start = System.currentTimeMillis();
        final List<BatteryDiffEntry> entries = mTabPosition == 0
        final List<BatteryDiffEntry> entries = mSpinnerPosition == 0
                ? mBatteryDiffData.getAppDiffEntryList()
                : mBatteryDiffData.getSystemDiffEntryList();
        int prefIndex = mAppListPreferenceGroup.getPreferenceCount();
+121 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 * Copyright (C) 2023 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.
@@ -20,82 +20,54 @@ import android.content.Context;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.AdapterView;
import android.widget.Spinner;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settingslib.widget.SettingsSpinnerAdapter;

import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
/** A preference which contains a spinner. */
public class SpinnerPreference extends Preference {
    private static final String TAG = "SpinnerPreference";

/** A preference which contains a tab selection. */
public class TabPreference extends Preference {
    private static final String TAG = "TabPreference";

    private Fragment mRootFragment;
    private ViewPager2 mViewPager;
    private ViewPager2.OnPageChangeCallback mOnPageChangeCallback;
    private AdapterView.OnItemSelectedListener mOnItemSelectedListener;

    @VisibleForTesting
    String[] mTabTitles;
    Spinner mSpinner;
    @VisibleForTesting
    int mSavedTabPosition;
    String[] mItems;
    @VisibleForTesting
    TabLayout mTabLayout;
    int mSavedSpinnerPosition;

    public TabPreference(Context context, AttributeSet attrs) {
    public SpinnerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setLayoutResource(R.layout.preference_tab);
    }

    void initializeTabs(Fragment rootFragment, String[] tabTitles) {
        mRootFragment = rootFragment;
        mTabTitles = tabTitles;
        setLayoutResource(R.layout.preference_spinner);
    }

    void setOnPageChangeCallback(ViewPager2.OnPageChangeCallback callback) {
        mOnPageChangeCallback = callback;
    void initializeSpinner(
            String[] items, AdapterView.OnItemSelectedListener onItemSelectedListener) {
        mItems = items;
        mOnItemSelectedListener = onItemSelectedListener;
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder view) {
        super.onBindViewHolder(view);
        if (mViewPager != null && mTabLayout != null) {
            return;
        }

        mViewPager = (ViewPager2) view.findViewById(R.id.view_pager);
        mViewPager.setAdapter(new FragmentAdapter(mRootFragment, mTabTitles.length));
        mViewPager.setUserInputEnabled(false);
        if (mOnPageChangeCallback != null) {
            mViewPager.registerOnPageChangeCallback(mOnPageChangeCallback);
        }

        mTabLayout = (TabLayout) view.findViewById(R.id.tabs);
        new TabLayoutMediator(
                mTabLayout, mViewPager, /* autoRefresh= */ true, /* smoothScroll= */ false,
                (tab, position) -> tab.setText(mTabTitles[position])).attach();
        mTabLayout.getTabAt(mSavedTabPosition).select();
    }

    @Override
    public void onDetached() {
        super.onDetached();
        if (mViewPager != null && mOnPageChangeCallback != null) {
            mViewPager.unregisterOnPageChangeCallback(mOnPageChangeCallback);
        mSpinner = (Spinner) view.findViewById(R.id.spinner);
        mSpinner.setAdapter(new SpinnerAdapter(getContext(), mItems));
        mSpinner.setSelection(mSavedSpinnerPosition);
        if (mOnItemSelectedListener != null) {
            mSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
        }
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Log.d(TAG, "onSaveInstanceState() tabPosition=" + mTabLayout.getSelectedTabPosition());
        return new SavedState(super.onSaveInstanceState(), mTabLayout.getSelectedTabPosition());
        Log.d(TAG, "onSaveInstanceState() spinnerPosition=" + mSpinner.getSelectedItemPosition());
        return new SavedState(super.onSaveInstanceState(), mSpinner.getSelectedItemPosition());
    }

    @Override
@@ -106,47 +78,44 @@ public class TabPreference extends Preference {
        }
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        mSavedTabPosition = savedState.getTabPosition();
        Log.d(TAG, "onRestoreInstanceState() tabPosition=" + savedState.getTabPosition());
        mSavedSpinnerPosition = savedState.getSpinnerPosition();
        if (mOnItemSelectedListener != null) {
            mOnItemSelectedListener.onItemSelected(/* parent= */null, /* view= */null,
                    savedState.getSpinnerPosition(), /* id= */ 0);
        }
        Log.d(TAG, "onRestoreInstanceState() spinnerPosition=" + savedState.getSpinnerPosition());
    }

    @VisibleForTesting
    static class SavedState extends BaseSavedState {
        private int mTabPosition;
        private int mSpinnerPosition;

        SavedState(Parcelable superState, int tabPosition) {
        SavedState(Parcelable superState, int spinnerPosition) {
            super(superState);
            mTabPosition = tabPosition;
            mSpinnerPosition = spinnerPosition;
        }

        int getTabPosition() {
            return mTabPosition;
        int getSpinnerPosition() {
            return mSpinnerPosition;
        }
    }

    private static class FragmentAdapter extends FragmentStateAdapter {
        private final int mItemCount;
        private final Fragment[] mItemFragments;
    private static class SpinnerAdapter extends SettingsSpinnerAdapter<CharSequence> {
        private final String[] mItems;

        FragmentAdapter(@NonNull Fragment rootFragment, int itemCount) {
            super(rootFragment);
            mItemCount = itemCount;
            mItemFragments = new Fragment[mItemCount];
            for (int i = 0; i < mItemCount; i++) {
                // Empty tab pages.
                mItemFragments[i] = new Fragment();
            }
        SpinnerAdapter(Context context, String[] items) {
            super(context);
            mItems = items;
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            return mItemFragments[position];
        public int getCount() {
            return mItems.length;
        }

        @Override
        public int getItemCount() {
            return mItemCount;
        public CharSequence getItem(int position) {
            return mItems[position];
        }
    }
}
Loading