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

Commit ea0f5b3d authored by Zaiyue Xue's avatar Zaiyue Xue
Browse files

Refactor battery usage page contollers interaction logic

(1) Move controllers interaction logic from BatteryChartPreferenceController to main page PowerUsageAdvanced.
(2) Move query power anomaly logic to DataProcessManager async job.

Bug: 284893240
Test: manual
Change-Id: Ib23b338fe3946e68ff73a372342ec5d86494c566
Merged-In: Ib23b338fe3946e68ff73a372342ec5d86494c566
parent 19046965
Loading
Loading
Loading
Loading
+33 −219
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -44,7 +43,6 @@ 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.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;

@@ -52,17 +50,12 @@ import com.google.common.base.Objects;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

/** Controls the update for chart graph and the list items. */
public class BatteryChartPreferenceController extends AbstractPreferenceController
        implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy, OnPause,
        implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy,
        OnSaveInstanceState, OnResume {
    private static final String TAG = "BatteryChartPreferenceController";
    private static final String PREFERENCE_KEY = "battery_chart";
@@ -74,53 +67,17 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    private static final String KEY_DAILY_CHART_INDEX = "daily_chart_index";
    private static final String KEY_HOURLY_CHART_INDEX = "hourly_chart_index";

    /**
     * A callback listener for battery usage is updated.
     * This happens when battery usage data is ready or the selected index is changed.
     */
    public interface OnBatteryUsageUpdatedListener {
        /**
         * The callback function for battery usage is updated.
         * @param slotUsageData The battery usage diff data for the selected slot. This is used in
         *                      the app list.
         * @param slotTimestamp The selected slot timestamp information. This is used in the battery
         *                      usage breakdown category.
         * @param isAllUsageDataEmpty Whether all the battery usage data is null or empty. This is
         *                            used when showing the footer.
         */
        void onBatteryUsageUpdated(
                BatteryDiffData slotUsageData, String slotTimestamp, boolean isAllUsageDataEmpty);
    }

    /**
     * A callback listener for the device screen on time is updated.
     * This happens when screen on time data is ready or the selected index is changed.
     */
    public interface OnScreenOnTimeUpdatedListener {
        /**
         * The callback function for the device screen on time is updated.
         * @param screenOnTime The selected slot device screen on time.
         * @param slotTimestamp The selected slot timestamp information.
         */
        void onScreenOnTimeUpdated(Long screenOnTime, String slotTimestamp);
    }

    /**
     * A callback listener for the battery tips card is updated.
     * This happens when battery tips card is ready.
     */
    public interface OnBatteryTipsUpdatedListener {
        /**
         * The callback function for the battery tips card is updated.
         * @param powerAnomalyEvent the power anomaly event with highest score
         */
        void onBatteryTipsUpdated(PowerAnomalyEvent powerAnomalyEvent);
    /** A callback listener for the selected index is updated. */
    interface OnSelectedIndexUpdatedListener {
        /** The callback function for the selected index is updated. */
        void onSelectedIndexUpdated();
    }


    @VisibleForTesting
    Context mPrefContext;
    @VisibleForTesting
    TextView mChartSummaryTextView;
    @VisibleForTesting
    BatteryChartView mDailyChartView;
    @VisibleForTesting
    BatteryChartView mHourlyChartView;
@@ -128,28 +85,20 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    int mDailyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
    @VisibleForTesting
    int mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
    @VisibleForTesting
    Map<Integer, Map<Integer, BatteryDiffData>> mBatteryUsageMap;

    private boolean mIs24HourFormat;
    private View mBatteryChartViewGroup;
    private TextView mChartSummaryTextView;
    private BatteryChartViewModel mDailyViewModel;
    private List<BatteryChartViewModel> mHourlyViewModels;
    private OnBatteryUsageUpdatedListener mOnBatteryUsageUpdatedListener;
    private OnScreenOnTimeUpdatedListener mOnScreenOnTimeUpdatedListener;
    private OnBatteryTipsUpdatedListener mOnBatteryTipsUpdatedListener;
    private AtomicBoolean mIsAppResume = new AtomicBoolean(false);
    private OnSelectedIndexUpdatedListener mOnSelectedIndexUpdatedListener;

    private final SettingsActivity mActivity;
    private final MetricsFeatureProvider mMetricsFeatureProvider;
    private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final AnimatorListenerAdapter mHourlyChartFadeInAdapter =
            createHourlyChartAnimatorListenerAdapter(/*visible=*/ true);
    private final AnimatorListenerAdapter mHourlyChartFadeOutAdapter =
            createHourlyChartAnimatorListenerAdapter(/*visible=*/ false);
    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    @VisibleForTesting
    final DailyChartLabelTextGenerator mDailyChartLabelTextGenerator =
@@ -165,8 +114,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        mIs24HourFormat = DateFormat.is24HourFormat(context);
        mMetricsFeatureProvider =
                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
        mPowerUsageFeatureProvider =
                FeatureFactory.getFactory(mContext).getPowerUsageFeatureProvider(context);
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
@@ -184,15 +131,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        Log.d(TAG, String.format("onCreate() dailyIndex=%d hourlyIndex=%d",
                mDailyChartIndex, mHourlyChartIndex));
    }
    @Override
    public void onPause() {
        mIsAppResume.compareAndSet(/* expect= */ true, /* update= */ false);
    }


    @Override
    public void onResume() {
        mIsAppResume.compareAndSet(/* expect= */ false, /* update= */ true);
        mIs24HourFormat = DateFormat.is24HourFormat(mContext);
        mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE);
    }
@@ -232,16 +173,16 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        return PREFERENCE_KEY;
    }

    void setOnBatteryUsageUpdatedListener(OnBatteryUsageUpdatedListener listener) {
        mOnBatteryUsageUpdatedListener = listener;
    int getDailyChartIndex() {
        return mDailyChartIndex;
    }

    void setOnScreenOnTimeUpdatedListener(OnScreenOnTimeUpdatedListener listener) {
        mOnScreenOnTimeUpdatedListener = listener;
    int getHourlyChartIndex() {
        return mHourlyChartIndex;
    }

    void setOnBatteryTipsUpdatedListener(OnBatteryTipsUpdatedListener listener) {
        mOnBatteryTipsUpdatedListener = listener;
    void setOnSelectedIndexUpdatedListener(OnSelectedIndexUpdatedListener listener) {
        mOnSelectedIndexUpdatedListener = listener;
    }

    void onBatteryLevelDataUpdate(final BatteryLevelData batteryLevelData) {
@@ -276,13 +217,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        refreshUi();
    }

    void onBatteryUsageMapUpdate(Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageMap) {
        Log.d(TAG, "onBatteryUsageMapUpdate: " + batteryUsageMap);
        mBatteryUsageMap = batteryUsageMap;
        logScreenUsageTime();
        refreshUi();
    }

    void setBatteryChartView(@NonNull final BatteryChartView dailyChartView,
            @NonNull final BatteryChartView hourlyChartView) {
        final View parentView = (View) dailyChartView.getParent();
@@ -319,6 +253,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
                            ? SettingsEnums.ACTION_BATTERY_USAGE_DAILY_SHOW_ALL
                            : SettingsEnums.ACTION_BATTERY_USAGE_DAILY_TIME_SLOT,
                    mDailyChartIndex);
            if (mOnSelectedIndexUpdatedListener != null) {
                mOnSelectedIndexUpdatedListener.onSelectedIndexUpdated();
            }
        });
        mHourlyChartView = hourlyChartView;
        mHourlyChartView.setOnSelectListener(trapezoidIndex -> {
@@ -340,102 +277,37 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
                            ? SettingsEnums.ACTION_BATTERY_USAGE_SHOW_ALL
                            : SettingsEnums.ACTION_BATTERY_USAGE_TIME_SLOT,
                    mHourlyChartIndex);
            if (mOnSelectedIndexUpdatedListener != null) {
                mOnSelectedIndexUpdatedListener.onSelectedIndexUpdated();
            }
        });
        refreshUi();
    }

    @VisibleForTesting
    boolean refreshUi() {
        if (mDailyChartView == null || mHourlyChartView == null) {
            // Chart views are not initialized.
            return false;
        }

        // When mDailyViewModel or mHourlyViewModels is null, there is no battery level data.
        // This is mainly in 2 cases:
        // 1) battery data is within 2 hours
        // 2) no battery data in the latest 7 days (power off >= 7 days)
        final boolean refreshUiResult = mDailyViewModel == null || mHourlyViewModels == null
                ? refreshUiWithNoLevelDataCase()
                : refreshUiWithLevelDataCase();

        if (!refreshUiResult) {
            return false;
        }

        if (mOnBatteryUsageUpdatedListener != null && mBatteryUsageMap != null
                && mBatteryUsageMap.get(mDailyChartIndex) != null) {
            final BatteryDiffData slotUsageData =
                    mBatteryUsageMap.get(mDailyChartIndex).get(mHourlyChartIndex);
            if (slotUsageData != null) {
                mOnScreenOnTimeUpdatedListener.onScreenOnTimeUpdated(
                        slotUsageData.getScreenOnTime(),
                        getSlotInformation());
            }
            mOnBatteryUsageUpdatedListener.onBatteryUsageUpdated(
                    slotUsageData, getSlotInformation(), isBatteryUsageMapNullOrEmpty());
            if (mOnBatteryTipsUpdatedListener != null) {
                mExecutor.execute(() -> {
                    final PowerAnomalyEventList anomalyEventList = mPowerUsageFeatureProvider
                            .detectSettingsAnomaly(mContext, /* displayDrain= */ 0);
                    Log.d(TAG, "anomalyEventList = " + anomalyEventList);
                    final PowerAnomalyEvent displayEvent =
                            getHighestScoreAnomalyEvent(anomalyEventList);
                    mHandler.post(() -> {
                                if (mIsAppResume.get()) {
                                    mOnBatteryTipsUpdatedListener
                                            .onBatteryTipsUpdated(displayEvent);
                                }
                            }
                    );
                });
            }
        }
        return true;
    // Show empty hourly chart view only if there is no valid battery usage data.
    void showEmptyChart() {
        setChartSummaryVisible(true);
        mDailyChartView.setVisibility(View.GONE);
        mHourlyChartView.setVisibility(View.VISIBLE);
        mHourlyChartView.setViewModel(null);
    }

    @VisibleForTesting
    PowerAnomalyEvent getHighestScoreAnomalyEvent(PowerAnomalyEventList anomalyEventList) {
        if (anomalyEventList == null || anomalyEventList.getPowerAnomalyEventsCount() == 0) {
            return null;
        }
        final Set<String> dismissedPowerAnomalyKeys =
                DatabaseUtils.getDismissedPowerAnomalyKeys(mContext);
        Log.d(TAG, "dismissedPowerAnomalyKeys = " + dismissedPowerAnomalyKeys);

        final PowerAnomalyEvent highestScoreEvent = anomalyEventList.getPowerAnomalyEventsList()
                .stream()
                .filter(event -> event.hasKey()
                        && !dismissedPowerAnomalyKeys.contains(event.getKey().name()))
                .max(Comparator.comparing(PowerAnomalyEvent::getScore))
                .orElse(null);
        Log.d(TAG, "highestScoreAnomalyEvent = " + highestScoreEvent);
        return highestScoreEvent;
    void refreshUi() {
        if (mDailyChartView == null || mHourlyChartView == null) {
            // Chart views are not initialized.
            return;
        }

    private boolean refreshUiWithNoLevelDataCase() {
        if (mDailyViewModel == null || mHourlyViewModels == null) {
            setChartSummaryVisible(false);
        if (mBatteryUsageMap == null) {
            // There is no battery level data and battery usage data is not ready, wait for data
            // ready to refresh UI. Show nothing temporarily.
            mDailyChartView.setVisibility(View.GONE);
            mHourlyChartView.setVisibility(View.GONE);
            mDailyChartView.setViewModel(null);
            mHourlyChartView.setViewModel(null);
            return false;
        } else if (mBatteryUsageMap
                .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
                .get(BatteryChartViewModel.SELECTED_INDEX_ALL) == null) {
            // There is no battery level data and battery usage data, show an empty hourly chart
            // view.
            mDailyChartView.setVisibility(View.GONE);
            mHourlyChartView.setVisibility(View.VISIBLE);
            mHourlyChartView.setViewModel(null);
        }
        return true;
            return;
        }

    private boolean refreshUiWithLevelDataCase() {
        setChartSummaryVisible(true);
        // Gets valid battery level data.
        if (isBatteryLevelDataInOneDay()) {
@@ -464,15 +336,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
            hourlyViewModel.setSelectedIndex(mHourlyChartIndex);
            mHourlyChartView.setViewModel(hourlyViewModel);
        }

        if (mBatteryUsageMap == null) {
            // Battery usage data is not ready, wait for data ready to refresh UI.
            return false;
        }
        return true;
    }

    @VisibleForTesting
    String getSlotInformation() {
        if (mDailyViewModel == null || mHourlyViewModels == null) {
            // No data
@@ -563,44 +428,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        };
    }

    private void logScreenUsageTime() {
        if (mBatteryUsageMap == null) {
            return;
        }
        final BatteryDiffData allBatteryDiffData = mBatteryUsageMap.get(
                BatteryChartViewModel.SELECTED_INDEX_ALL).get(
                BatteryChartViewModel.SELECTED_INDEX_ALL);
        if (allBatteryDiffData == null) {
            return;
        }
        mMetricsFeatureProvider.action(
                mPrefContext,
                SettingsEnums.ACTION_BATTERY_USAGE_SCREEN_ON_TIME,
                (int) allBatteryDiffData.getScreenOnTime());
        mMetricsFeatureProvider.action(
                mPrefContext,
                SettingsEnums.ACTION_BATTERY_USAGE_FOREGROUND_USAGE_TIME,
                (int) getTotalForegroundUsageTime());
    }

    private long getTotalForegroundUsageTime() {
        if (mBatteryUsageMap == null) {
            return 0;
        }
        final BatteryDiffData totalBatteryUsageDiffData =
                mBatteryUsageMap
                        .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
                        .get(BatteryChartViewModel.SELECTED_INDEX_ALL);
        if (totalBatteryUsageDiffData == null) {
            return 0;
        }
        long totalValue = 0;
        for (final BatteryDiffEntry entry : totalBatteryUsageDiffData.getAppDiffEntryList()) {
            totalValue += entry.mForegroundUsageTimeInMs;
        }
        return totalValue;
    }

    private boolean isBatteryLevelDataInOneDay() {
        return mHourlyViewModels != null && mHourlyViewModels.size() == 1;
    }
@@ -611,19 +438,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
                && mHourlyChartIndex == BatteryChartViewModel.SELECTED_INDEX_ALL;
    }

    private boolean isBatteryUsageMapNullOrEmpty() {
        if (mBatteryUsageMap == null) {
            return true;
        }
        BatteryDiffData allBatteryDiffData = mBatteryUsageMap
                .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
                .get(BatteryChartViewModel.SELECTED_INDEX_ALL);
        // If all data is null or empty, each slot must be null or empty.
        return allBatteryDiffData == null
                || (allBatteryDiffData.getAppDiffEntryList().isEmpty()
                && allBatteryDiffData.getSystemDiffEntryList().isEmpty());
    }

    @VisibleForTesting
    static int getTotalHours(final BatteryLevelData batteryLevelData) {
        if (batteryLevelData == null) {
+142 −21

File changed.

Preview size limit exceeded, changes collapsed.

+62 −66
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -44,9 +45,9 @@ import android.util.ArrayMap;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.settings.SettingsActivity;
import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;

import org.junit.Before;
@@ -72,6 +73,8 @@ public final class BatteryChartPreferenceControllerTest {
    @Mock
    private SettingsActivity mSettingsActivity;
    @Mock
    private TextView mChartSummaryTextView;
    @Mock
    private BatteryChartView mDailyChartView;
    @Mock
    private BatteryChartView mHourlyChartView;
@@ -112,6 +115,7 @@ public final class BatteryChartPreferenceControllerTest {
        setupHourlyChartViewAnimationMock();
        mBatteryChartPreferenceController = createController();
        mBatteryChartPreferenceController.mPrefContext = mContext;
        mBatteryChartPreferenceController.mChartSummaryTextView = mChartSummaryTextView;
        mBatteryChartPreferenceController.mDailyChartView = mDailyChartView;
        mBatteryChartPreferenceController.mHourlyChartView = mHourlyChartView;
        BatteryDiffEntry.clearCache();
@@ -180,7 +184,6 @@ public final class BatteryChartPreferenceControllerTest {
                mBatteryChartPreferenceController.mDailyChartLabelTextGenerator);

        mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(60));
        mBatteryChartPreferenceController.onBatteryUsageMapUpdate(getEmptyBatteryUsageMap());

        verify(mDailyChartView, atLeastOnce()).setVisibility(View.VISIBLE);
        verify(mViewPropertyAnimator, atLeastOnce()).alpha(0f);
@@ -275,29 +278,78 @@ public final class BatteryChartPreferenceControllerTest {
    }

    @Test
    public void refreshUi_normalCase_returnTrue() {
    public void onBatteryLevelDataUpdate_oneDay_showHourlyChartOnly() {
        doReturn(View.GONE).when(mHourlyChartView).getVisibility();

        mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(6));
        mBatteryChartPreferenceController.onBatteryUsageMapUpdate(getEmptyBatteryUsageMap());
        assertThat(mBatteryChartPreferenceController.refreshUi()).isTrue();

        verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
        verify(mDailyChartView).setVisibility(View.GONE);
        verify(mHourlyChartView).setVisibility(View.VISIBLE);
    }

    @Test
    public void onBatteryLevelDataUpdate_selectAllForMultipleDays_showDailyChartOnly() {
        doReturn(View.GONE).when(mHourlyChartView).getVisibility();

        mBatteryChartPreferenceController.mDailyChartIndex = SELECTED_INDEX_ALL;
        mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(60));

        verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
        verify(mDailyChartView).setVisibility(View.VISIBLE);
        verify(mHourlyChartView, never()).setVisibility(View.VISIBLE);
    }

    @Test
    public void refreshUi_batteryIndexedMapIsNull_returnTrue() {
    public void onBatteryLevelDataUpdate_selectOneDayForMultipleDays_showBothCharts() {
        doReturn(View.GONE).when(mHourlyChartView).getVisibility();

        mBatteryChartPreferenceController.mDailyChartIndex = 0;
        mBatteryChartPreferenceController.onBatteryLevelDataUpdate(createBatteryLevelData(60));

        verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
        verify(mDailyChartView).setVisibility(View.VISIBLE);
        verify(mHourlyChartView).setVisibility(View.VISIBLE);
    }

    @Test
    public void onBatteryLevelDataUpdate_batteryLevelDataIsNull_showNoChart() {
        doReturn(View.GONE).when(mHourlyChartView).getVisibility();

        mBatteryChartPreferenceController.onBatteryLevelDataUpdate(null);
        mBatteryChartPreferenceController.onBatteryUsageMapUpdate(getEmptyBatteryUsageMap());
        assertThat(mBatteryChartPreferenceController.refreshUi()).isTrue();

        verify(mChartSummaryTextView).setVisibility(View.GONE);
        verify(mDailyChartView).setVisibility(View.GONE);
        verify(mHourlyChartView).setVisibility(View.GONE);
    }

    @Test
    public void showEmptyChart_normalCase_showEmptyChart() {
        doReturn(View.GONE).when(mHourlyChartView).getVisibility();

        mBatteryChartPreferenceController.showEmptyChart();

        verify(mChartSummaryTextView).setVisibility(View.VISIBLE);
        verify(mDailyChartView).setVisibility(View.GONE);
        verify(mHourlyChartView).setVisibility(View.VISIBLE);
    }

    @Test
    public void refreshUi_dailyChartViewIsNull_ignoreRefresh() {
        mBatteryChartPreferenceController.mDailyChartView = null;
        assertThat(mBatteryChartPreferenceController.refreshUi()).isFalse();

        mBatteryChartPreferenceController.refreshUi();

        verify(mChartSummaryTextView, never()).setVisibility(anyInt());
    }

    @Test
    public void refreshUi_hourlyChartViewIsNull_ignoreRefresh() {
        mBatteryChartPreferenceController.mHourlyChartView = null;
        assertThat(mBatteryChartPreferenceController.refreshUi()).isFalse();

        mBatteryChartPreferenceController.refreshUi();

        verify(mChartSummaryTextView, never()).setVisibility(anyInt());
    }

    @Test
@@ -408,57 +460,6 @@ public final class BatteryChartPreferenceControllerTest {
        assertThat(totalHour).isEqualTo(59);
    }

    @Test
    public void getHighestScoreAnomalyEvent_withEmptyOrNullList_getNull() {
        assertThat(mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(null))
                .isEqualTo(null);
        assertThat(mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(
                BatteryTestUtils.createEmptyPowerAnomalyEventList()))
                .isEqualTo(null);
    }

    @Test
    public void getHighestScoreAnomalyEvent_withoutDismissed_getHighestScoreEvent() {
        final PowerAnomalyEventList eventList =
                BatteryTestUtils.createNonEmptyPowerAnomalyEventList();

        final PowerAnomalyEvent highestScoreEvent =
                mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(eventList);

        assertThat(highestScoreEvent)
                .isEqualTo(BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent());
    }

    @Test
    public void getHighestScoreAnomalyEvent_withBrightnessDismissed_getScreenTimeout() {
        final PowerAnomalyEventList eventList =
                BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
        DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
        DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, PowerAnomalyKey.KEY_BRIGHTNESS.name());

        final PowerAnomalyEvent highestScoreEvent =
                mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(eventList);

        assertThat(highestScoreEvent)
                .isEqualTo(BatteryTestUtils.createScreenTimeoutAnomalyEvent());
    }

    @Test
    public void getHighestScoreAnomalyEvent_withAllDismissed_getNull() {
        final PowerAnomalyEventList eventList =
                BatteryTestUtils.createNonEmptyPowerAnomalyEventList();
        DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
        for (PowerAnomalyKey key : PowerAnomalyKey.values()) {
            DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, key.name());
        }

        final PowerAnomalyEvent highestScoreEvent =
                mBatteryChartPreferenceController.getHighestScoreAnomalyEvent(eventList);

        assertThat(highestScoreEvent).isEqualTo(null);
    }


    private static Long generateTimestamp(int index) {
        // "2021-04-23 07:00:00 UTC" + index hours
        return 1619247600000L + index * DateUtils.HOUR_IN_MILLIS;
@@ -481,11 +482,6 @@ public final class BatteryChartPreferenceControllerTest {
        return new BatteryLevelData(batteryLevelMap);
    }

    private static Map<Integer, Map<Integer, BatteryDiffData>> getEmptyBatteryUsageMap() {
        return Map.of(SELECTED_INDEX_ALL, Map.of(SELECTED_INDEX_ALL, new BatteryDiffData(
                null, 0, 0, 0, 0, 0, List.of(), List.of(), Set.of(), Set.of(), false)));
    }

    private BatteryChartPreferenceController createController() {
        final BatteryChartPreferenceController controller =
                new BatteryChartPreferenceController(
+92 −0

File added.

Preview size limit exceeded, changes collapsed.