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

Commit eb1fc841 authored by Xinyi Mao's avatar Xinyi Mao Committed by Android (Google) Code Review
Browse files

Merge "Migrate Spinner on Battery Usage to settingsLib Spinner widget." into main

parents c9cae8f7 05e857de
Loading
Loading
Loading
Loading

res/layout/preference_spinner.xml

deleted100644 → 0
+0 −24
Original line number Diff line number Diff line
<!--
  ~ 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.
  ~ 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.
  -->

<Spinner
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="24dp"
    android:layout_marginTop="8dp"
    android:theme="@style/Widget.PopupWindow.Settings" />
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@
            "com.android.settings.fuelgauge.batteryusage.BatteryUsageBreakdownController"
        settings:isPreferenceVisible="false">

        <com.android.settings.fuelgauge.batteryusage.SpinnerPreference
        <com.android.settingslib.widget.SettingsSpinnerPreference
            android:key="battery_usage_spinner"
            settings:isPreferenceVisible="false" />

+34 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
@@ -46,9 +47,13 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.SettingsSpinnerAdapter;
import com.android.settingslib.widget.SettingsSpinnerPreference;

import java.util.ArrayList;
import java.util.List;
@@ -58,7 +63,7 @@ import java.util.Set;

/** Controller for battery usage breakdown preference group. */
public class BatteryUsageBreakdownController extends BasePreferenceController
        implements LifecycleObserver, OnResume, OnDestroy {
        implements LifecycleObserver, OnResume, OnDestroy, OnCreate, OnSaveInstanceState {
    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";
@@ -67,6 +72,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
    private static final String PACKAGE_NAME_NONE = "none";
    private static final String SLOT_TIMESTAMP = "slot_timestamp";
    private static final String ANOMALY_KEY = "anomaly_key";
    private static final String KEY_SPINNER_POSITION = "spinner_position";
    private static final List<BatteryDiffEntry> EMPTY_ENTRY_LIST = new ArrayList<>();

    private static int sUiMode = Configuration.UI_MODE_NIGHT_UNDEFINED;
@@ -78,12 +84,12 @@ public class BatteryUsageBreakdownController extends BasePreferenceController

    @VisibleForTesting final Map<String, Preference> mPreferenceCache = new ArrayMap<>();

    private int mSpinnerPosition;
    private String mSlotInformation;
    private SettingsSpinnerPreference mSpinnerPreference;
    private SettingsSpinnerAdapter<CharSequence> mSpinnerAdapter;

    @VisibleForTesting Context mPrefContext;
    @VisibleForTesting PreferenceCategory mRootPreference;
    @VisibleForTesting SpinnerPreference mSpinnerPreference;
    @VisibleForTesting PreferenceGroup mAppListPreferenceGroup;
    @VisibleForTesting FooterPreference mFooterPreference;
    @VisibleForTesting BatteryDiffData mBatteryDiffData;
@@ -92,6 +98,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
    @VisibleForTesting String mPercentLessThanThresholdContentDescription;
    @VisibleForTesting boolean mIsHighlightSlot;
    @VisibleForTesting int mAnomalyKeyNumber;
    @VisibleForTesting int mSpinnerPosition;
    @VisibleForTesting String mAnomalyEntryKey;
    @VisibleForTesting String mAnomalyHintString;
    @VisibleForTesting String mAnomalyHintPrefKey;
@@ -110,6 +117,15 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            return;
        }
        mSpinnerPosition = savedInstanceState.getInt(KEY_SPINNER_POSITION, mSpinnerPosition);
        Log.d(TAG, "onCreate() spinnerPosition=" + mSpinnerPosition);
    }

    @Override
    public void onResume() {
        final int currentUiMode =
@@ -140,6 +156,15 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
        return false;
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            return;
        }
        savedInstanceState.putInt(KEY_SPINNER_POSITION, mSpinnerPosition);
        Log.d(TAG, "onSaveInstanceState() spinnerPosition=" + mSpinnerPosition);
    }

    private boolean isAnomalyBatteryDiffEntry(BatteryDiffEntry entry) {
        return mIsHighlightSlot
                && mAnomalyEntryKey != null
@@ -218,11 +243,14 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
                        formatPercentage);

        mAppListPreferenceGroup.setOrderingAsAdded(false);
        mSpinnerPreference.initializeSpinner(
        mSpinnerAdapter = new SettingsSpinnerAdapter<>(mPrefContext);
        mSpinnerAdapter.addAll(
                new String[] {
                    mPrefContext.getString(R.string.battery_usage_spinner_view_by_apps),
                    mPrefContext.getString(R.string.battery_usage_spinner_view_by_systems)
                },
                });
        mSpinnerPreference.setAdapter(mSpinnerAdapter);
        mSpinnerPreference.setOnItemSelectedListener(
                new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(
@@ -244,6 +272,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {}
                });
        mSpinnerPreference.setSelection(mSpinnerPosition);
    }

    /**
+0 −134
Original line number Diff line number Diff line
/*
 * 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.
 * 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.batteryusage;

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.preference.Preference;
import androidx.preference.PreferenceViewHolder;

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

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

    private AdapterView.OnItemSelectedListener mOnItemSelectedListener;

    @VisibleForTesting Spinner mSpinner;
    @VisibleForTesting String[] mItems;
    @VisibleForTesting int mSavedSpinnerPosition;

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

    void initializeSpinner(
            String[] items, AdapterView.OnItemSelectedListener onItemSelectedListener) {
        mItems = items;
        mOnItemSelectedListener = onItemSelectedListener;
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder view) {
        if (mSpinner != null) {
            return;
        }

        mSpinner = (Spinner) view.findViewById(R.id.spinner);
        mSpinner.setAdapter(new SpinnerAdapter(getContext(), mItems));
        mSpinner.setSelection(mSavedSpinnerPosition);
        mSpinner.setLongClickable(false);
        if (mOnItemSelectedListener != null) {
            mSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
        }
    }

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

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state == null || state == BaseSavedState.EMPTY_STATE) {
            super.onRestoreInstanceState(state);
            return;
        }
        if (!(state instanceof SavedState)) {
            // To avoid the IllegalArgumentException, return the BaseSavedState.EMPTY_STATE.
            super.onRestoreInstanceState(BaseSavedState.EMPTY_STATE);
            return;
        }
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        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 mSpinnerPosition;

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

        int getSpinnerPosition() {
            return mSpinnerPosition;
        }
    }

    private static class SpinnerAdapter extends SettingsSpinnerAdapter<CharSequence> {
        private final String[] mItems;

        SpinnerAdapter(Context context, String[] items) {
            super(context);
            mItems = items;
        }

        @Override
        public int getCount() {
            return mItems.length;
        }

        @Override
        public CharSequence getItem(int position) {
            return mItems[position];
        }
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.LocaleList;
import android.text.format.DateUtils;

@@ -57,6 +58,7 @@ public final class BatteryUsageBreakdownControllerTest {
    private static final String PREF_KEY = "pref_key";
    private static final String PREF_KEY2 = "pref_key2";
    private static final String PREF_SUMMARY = "fake preference summary";
    private static final String KEY_SPINNER_POSITION = "spinner_position";
    private static final long TIME_LESS_THAN_HALF_MINUTE  = DateUtils.MINUTE_IN_MILLIS / 2  - 1;

    @Mock private InstrumentedPreferenceFragment mFragment;
@@ -148,6 +150,15 @@ public final class BatteryUsageBreakdownControllerTest {
        verify(mAppListPreferenceGroup).removeAll();
    }

    @Test
    public void onSaveInstanceState_returnExpectedResult() {
        mBatteryUsageBreakdownController.mSpinnerPosition = 1;
        final Bundle savedInstanceState = new Bundle();
        mBatteryUsageBreakdownController.onSaveInstanceState(savedInstanceState);

        assertThat(savedInstanceState.getInt(KEY_SPINNER_POSITION)).isEqualTo(1);
    }

    @Test
    public void addAllPreferences_addAllPreferences() {
        final String appLabel = "fake app label";
Loading