Merge "Add list preference for BT audio device type selection" into udc-qpr-dev
diff --git a/res/drawable/battery_tips_all_rounded_bg_ripple.xml b/res/drawable/battery_tips_all_rounded_bg_ripple.xml
new file mode 100644
index 0000000..3180570
--- /dev/null
+++ b/res/drawable/battery_tips_all_rounded_bg_ripple.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?android:attr/colorControlHighlight">
+    <item android:drawable="@drawable/battery_tips_all_rounded_bg"/>
+</ripple>
\ No newline at end of file
diff --git a/res/layout/battery_tips_card.xml b/res/layout/battery_tips_card.xml
index d2edb51..2fa5bf2 100644
--- a/res/layout/battery_tips_card.xml
+++ b/res/layout/battery_tips_card.xml
@@ -12,36 +12,16 @@
         android:id="@+id/tips_card"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@drawable/battery_tips_all_rounded_bg"
+        android:background="@drawable/battery_tips_all_rounded_bg_ripple"
         android:orientation="vertical"
         android:padding="24dp">
 
-        <LinearLayout
-            android:layout_width="match_parent"
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="horizontal">
-
-            <ImageView
-                android:id="@+id/icon"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|start"
-                android:src="@drawable/ic_battery_tips_lightbulb" />
-
-            <Space
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                android:layout_weight="1" />
-
-            <ImageButton
-                android:id="@+id/dismiss_button"
-                style="@style/Banner.Dismiss.SettingsLib"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|end"
-                android:layout_marginEnd="0dp"
-                android:src="@drawable/ic_battery_tips_close_icon" />
-        </LinearLayout>
+            android:layout_gravity="center_vertical|start"
+            android:src="@drawable/ic_battery_tips_lightbulb" />
 
         <TextView
             android:id="@+id/title"
@@ -53,30 +33,40 @@
             android:textAppearance="?android:attr/textAppearanceLarge"
             android:textColor="?android:attr/textColorPrimary" />
 
-        <TextView
-            android:id="@+id/summary"
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:orientation="horizontal"
             android:layout_marginTop="8dp"
-            android:gravity="start"
-            android:maxLines="10"
-            android:textAlignment="viewStart"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="?android:attr/textColorSecondary" />
+            android:gravity="end">
 
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/action_button"
-            style="@style/Widget.Material3.Button.OutlinedButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="end"
-            android:layout_marginTop="8dp"
-            android:text="@string/battery_tips_card_action_button"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="?android:attr/textColorPrimary"
-            android:textStyle="bold"
-            app:strokeColor="?android:attr/colorAccent"
-            app:strokeWidth="1dp" />
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/dismiss_button"
+                style="@style/Widget.Material3.Button.TextButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="end"
+                android:paddingHorizontal="16dp"
+                android:layout_marginEnd="8dp"
+                android:text="@string/battery_tips_card_dismiss_button"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/colorAccent"
+                android:textStyle="bold" />
+
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/main_button"
+                style="@style/Widget.Material3.Button.OutlinedButton"
+                android:paddingHorizontal="16dp"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="end"
+                android:text="@string/battery_tips_card_action_button"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorPrimary"
+                android:textStyle="bold"
+                app:strokeColor="?android:attr/colorAccent"
+                app:strokeWidth="1dp" />
+        </LinearLayout>
     </LinearLayout>
 
     <Space
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 787163e..906d4ee 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1409,4 +1409,25 @@
     <integer-array name="network_mode_3g_deprecated_carrier_id" translatable="false">
     </integer-array>
 
+    <!-- The following 4 arrays are for power anomaly tips card. Please keep them the same size. -->
+    <string-array name="power_anomaly_keys" translatable="false">
+        <item>adaptive_brightness</item>
+        <item>screen_timeout</item>
+    </string-array>
+
+    <string-array name="power_anomaly_titles">
+        <item>Turn on adaptive brightness to extend battery life</item>
+        <item>Reduce screen timeout to extend battery life</item>
+    </string-array>
+
+    <string-array name="power_anomaly_main_btn_strings">
+        <item>@string/battery_tips_card_action_button</item>
+        <item>@string/battery_tips_card_action_button</item>
+    </string-array>
+
+    <string-array name="power_anomaly_dismiss_btn_strings">
+        <item>@string/battery_tips_card_dismiss_button</item>
+        <item>@string/battery_tips_card_dismiss_button</item>
+    </string-array>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 12ba29d..9a4812f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9651,23 +9651,14 @@
     <string name="app_battery_usage_summary">Set battery usage for apps</string>
 
     <!-- Label of action button in battery tips card [CHAR LIMIT=NONE] -->
-    <string name="battery_tips_card_action_button" translatable="false">Optimize</string>
+    <string name="battery_tips_card_action_button" translatable="false">View Settings</string>
+
+    <!-- Label of dismiss button in battery tips card [CHAR LIMIT=NONE] -->
+    <string name="battery_tips_card_dismiss_button" translatable="false">Got it</string>
 
     <!-- Feedback card message in battery tips card [CHAR LIMIT=NONE] -->
     <string name="battery_tips_card_feedback_info" translatable="false">Is this message helpful?</string>
 
-    <!-- Title of battery tips: adaptive brightness [CHAR LIMIT=NONE] -->
-    <string name="battery_tips_adaptive_brightness_title" translatable="false">Turn on adaptive brightness to extend battery life</string>
-
-    <!-- Summary of battery tips: adaptive brightness [CHAR LIMIT=NONE] -->
-    <string name="battery_tips_adaptive_brightness_summary" translatable="false">It will help reduce your daily battery drain by 10%</string>
-
-    <!-- Title of battery tips: reduce screen timeout [CHAR LIMIT=NONE] -->
-    <string name="battery_tips_screen_timeout_title" translatable="false">Reduce screen timeout to extend battery life</string>
-
-    <!-- Summary of battery tips: reduce screen timeout [CHAR LIMIT=NONE] -->
-    <string name="battery_tips_screen_timeout_summary" translatable="false">It will help reduce your daily battery drain by 10%</string>
-
     <!-- Filter title for battery unrestricted[CHAR_LIMIT=50]-->
     <string name="filter_battery_unrestricted_title">Unrestricted</string>
 
diff --git a/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java
index 43337c8..7ca35d8 100644
--- a/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java
+++ b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProvider.java
@@ -41,7 +41,8 @@
      * the list will contain only the preference showing the current firmware version.
      *
      * @param context The context
+     * @param usbDevice The USB device for which to generate preferences.
      */
     @Nullable
-    List<Preference> getUsbFirmwareUpdatePreferences(Context context);
+    List<Preference> getUsbFirmwareUpdatePreferences(Context context, UsbDevice usbDevice);
 }
diff --git a/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java
index dba569b..be5ae40 100644
--- a/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java
+++ b/src/com/android/settings/connecteddevice/stylus/StylusFeatureProviderImpl.java
@@ -31,7 +31,7 @@
     }
 
     @Override
-    public List<Preference> getUsbFirmwareUpdatePreferences(Context context) {
+    public List<Preference> getUsbFirmwareUpdatePreferences(Context context, UsbDevice usbDevice) {
         return null;
     }
 }
diff --git a/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java b/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java
index 4a4dfa2..9c567a4 100644
--- a/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java
+++ b/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareController.java
@@ -88,7 +88,7 @@
             StylusFeatureProvider featureProvider = FeatureFactory.getFactory(
                     mContext).getStylusFeatureProvider();
             List<Preference> preferences =
-                    featureProvider.getUsbFirmwareUpdatePreferences(mContext);
+                    featureProvider.getUsbFirmwareUpdatePreferences(mContext, mStylusUsbDevice);
 
             if (preferences != null) {
                 mPreference = new PreferenceCategory(mContext);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 258ded1..30eabfa 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -22,6 +22,7 @@
 import android.util.ArrayMap;
 import android.util.SparseIntArray;
 
+import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
 import com.android.settingslib.fuelgauge.Estimate;
 
 import java.util.List;
@@ -147,7 +148,7 @@
     /**
      * Returns {@link Bundle} for settings anomaly detection result
      */
-    Bundle detectSettingsAnomaly(Context context, double displayDrain);
+    PowerAnomalyEventList detectSettingsAnomaly(Context context, double displayDrain);
 
     /**
      * Gets an intent for one time bypass charge limited to resume charging.
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 9b5bb5e..127178a 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -21,13 +21,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.os.Bundle;
 import android.os.Process;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.SparseIntArray;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
 import com.android.settingslib.fuelgauge.Estimate;
 
 import java.util.ArrayList;
@@ -82,7 +82,7 @@
 
     @Override
     public boolean isBatteryTipsFeedbackEnabled() {
-        return true;
+        return false;
     }
 
     @Override
@@ -175,7 +175,7 @@
     public void insertSettingsData(Context context, double displayDrain) {}
 
     @Override
-    public Bundle detectSettingsAnomaly(Context context, double displayDrain) {
+    public PowerAnomalyEventList detectSettingsAnomaly(Context context, double displayDrain) {
         return null;
     }
 
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
index b7e1885..3231e55 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
@@ -105,10 +105,9 @@
     public interface OnBatteryTipsUpdatedListener {
         /**
          * The callback function for the battery tips card is updated.
-         * @param title the title of the battery tip card
-         * @param summary the summary of the battery tip card
+         * @param powerAnomalyEvent the power anomaly event with highest score
          */
-        void onBatteryTipsUpdated(String title, String summary);
+        void onBatteryTipsUpdated(PowerAnomalyEvent powerAnomalyEvent);
     }
 
 
@@ -365,7 +364,8 @@
                     slotUsageData, getSlotInformation(), isBatteryUsageMapNullOrEmpty());
 
             if (mOnBatteryTipsUpdatedListener != null) {
-                mOnBatteryTipsUpdatedListener.onBatteryTipsUpdated(null, null);
+                // TODO: replace with a selected powerAnomalyEvent with highest score
+                mOnBatteryTipsUpdatedListener.onBatteryTipsUpdated(null);
             }
         }
         return true;
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
index 661d7c8..f59f2e2 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
@@ -17,15 +17,19 @@
 package com.android.settings.fuelgauge.batteryusage;
 
 import android.content.Context;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.ImageButton;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 
@@ -40,12 +44,14 @@
 
     private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
 
-    private MaterialButton mActionButton;
-    private ImageButton mDismissButton;
-    private ImageButton mThumbUpButton;
-    private ImageButton mThumbDownButton;
-    private CharSequence mTitle;
-    private CharSequence mSummary;
+    @VisibleForTesting
+    CharSequence mMainButtonLabel;
+    @VisibleForTesting
+    CharSequence mDismissButtonLabel;
+    @VisibleForTesting
+    String mDestinationComponentName;
+    @VisibleForTesting
+    int mSourceMetricsCategory;
 
     public BatteryTipsCardPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -55,34 +61,65 @@
                 .getPowerUsageFeatureProvider(context);
     }
 
-    @Override
-    public void setTitle(CharSequence title) {
-        mTitle = title;
-        notifyChanged();
+    /**
+     * Update the label of main button in tips card.
+     */
+    public void setMainButtonLabel(CharSequence label) {
+        if (!TextUtils.equals(mMainButtonLabel, label)) {
+            mMainButtonLabel = label;
+            notifyChanged();
+        }
     }
 
-    @Override
-    public void setSummary(CharSequence summary) {
-        mSummary = summary;
-        notifyChanged();
+    /**
+     * Update the label of dismiss button in tips card.
+     */
+    public void setDismissButtonLabel(CharSequence label) {
+        if (!TextUtils.equals(mDismissButtonLabel, label)) {
+            mDismissButtonLabel = label;
+            notifyChanged();
+        }
+    }
+
+    /**
+     * Update the info of target fragment launched by main button.
+     */
+    public void setMainButtonLauncherInfo(final String destinationClassName,
+            final Integer sourceMetricsCategory) {
+        mDestinationComponentName = destinationClassName;
+        mSourceMetricsCategory = sourceMetricsCategory;
     }
 
     @Override
     public void onClick(View view) {
-        // TODO: replace with the settings anomaly obtained from detectSettingsAnomaly();
+        final int viewId = view.getId();
+        if (viewId == R.id.main_button || viewId == R.id.tips_card) {
+            if (TextUtils.isEmpty(mDestinationComponentName)) {
+                return;
+            }
+            new SubSettingLauncher(getContext())
+                    .setDestination(mDestinationComponentName)
+                    .setSourceMetricsCategory(mSourceMetricsCategory)
+                    .launch();
+        } else if (viewId == R.id.dismiss_button) {
+            setVisible(false);
+        }
     }
 
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
         super.onBindViewHolder(view);
 
-        ((TextView) view.findViewById(R.id.title)).setText(mTitle);
-        ((TextView) view.findViewById(R.id.summary)).setText(mSummary);
+        ((TextView) view.findViewById(R.id.title)).setText(getTitle());
 
-        mActionButton = (MaterialButton) view.findViewById(R.id.action_button);
-        mActionButton.setOnClickListener(this);
-        mDismissButton = (ImageButton) view.findViewById(R.id.dismiss_button);
-        mDismissButton.setOnClickListener(this);
+        LinearLayout tipsCard = (LinearLayout) view.findViewById(R.id.tips_card);
+        tipsCard.setOnClickListener(this);
+        MaterialButton mainButton = (MaterialButton) view.findViewById(R.id.main_button);
+        mainButton.setOnClickListener(this);
+        mainButton.setText(mMainButtonLabel);
+        MaterialButton dismissButton = (MaterialButton) view.findViewById(R.id.dismiss_button);
+        dismissButton.setOnClickListener(this);
+        dismissButton.setText(mDismissButtonLabel);
 
         if (!mPowerUsageFeatureProvider.isBatteryTipsFeedbackEnabled()) {
             return;
@@ -91,9 +128,9 @@
                 .setBackgroundResource(R.drawable.battery_tips_half_rounded_top_bg);
         view.findViewById(R.id.feedback_card).setVisibility(View.VISIBLE);
 
-        mThumbUpButton = (ImageButton) view.findViewById(R.id.thumb_up);
-        mThumbUpButton.setOnClickListener(this);
-        mThumbDownButton = (ImageButton) view.findViewById(R.id.thumb_down);
-        mThumbDownButton.setOnClickListener(this);
+        ImageButton thumbUpButton = (ImageButton) view.findViewById(R.id.thumb_up);
+        thumbUpButton.setOnClickListener(this);
+        ImageButton thumbDownButton = (ImageButton) view.findViewById(R.id.thumb_down);
+        thumbDownButton.setOnClickListener(this);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
index bcedd4f..991a8f6 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
@@ -17,13 +17,18 @@
 package com.android.settings.fuelgauge.batteryusage;
 
 import android.content.Context;
+import android.text.TextUtils;
 
 import androidx.preference.PreferenceScreen;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 
+import java.util.function.Function;
+
 /** Controls the update for battery tips card */
 public class BatteryTipsController extends BasePreferenceController {
 
@@ -31,15 +36,23 @@
     private static final String ROOT_PREFERENCE_KEY = "battery_tips_category";
     private static final String CARD_PREFERENCE_KEY = "battery_tips_card";
 
-    private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
+    private final String[] mPowerAnomalyKeys;
 
-    private Context mPrefContext;
-    private BatteryTipsCardPreference mCardPreference;
+    @VisibleForTesting
+    BatteryTipsCardPreference mCardPreference;
+    @VisibleForTesting
+    PowerUsageFeatureProvider mPowerUsageFeatureProvider;
 
     public BatteryTipsController(Context context) {
         super(context, ROOT_PREFERENCE_KEY);
         mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)
                 .getPowerUsageFeatureProvider(context);
+        mPowerAnomalyKeys = context.getResources().getStringArray(R.array.power_anomaly_keys);
+    }
+
+    private boolean isTipsCardVisible() {
+        // TODO: compared with the timestamp of last user dismiss action in sharedPreference.
+        return mPowerUsageFeatureProvider.isBatteryTipsEnabled();
     }
 
     @Override
@@ -50,28 +63,89 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        mPrefContext = screen.getContext();
         mCardPreference = screen.findPreference(CARD_PREFERENCE_KEY);
     }
 
-    /**
-     * Update the card visibility and contents.
-     * @param title a string not extend 2 lines.
-     * @param summary a string not extend 10 lines.
-     */
-    // TODO: replace parameters with SettingsAnomaly Data Proto
-    public void handleBatteryTipsCardUpdated(String title, String summary) {
-        if (!mPowerUsageFeatureProvider.isBatteryTipsEnabled()) {
-            mCardPreference.setVisible(false);
-            return;
+    @VisibleForTesting
+    int getPowerAnomalyEventIndex(String powerAnomalyKey) {
+        for (int index = 0; index < mPowerAnomalyKeys.length; index++) {
+            if (mPowerAnomalyKeys[index].equals(powerAnomalyKey)) {
+                return index;
+            }
         }
-        if (title == null || summary == null) {
-            mCardPreference.setVisible(false);
-            return;
-        }
-        mCardPreference.setTitle(title);
-        mCardPreference.setSummary(summary);
-        mCardPreference.setVisible(true);
+        return -1;
     }
 
+    private <T> T getInfo(PowerAnomalyEvent powerAnomalyEvent,
+                          Function<WarningBannerInfo, T> warningBannerInfoSupplier,
+                          Function<WarningItemInfo, T> warningItemInfoSupplier) {
+        if (powerAnomalyEvent.hasWarningBannerInfo() && warningBannerInfoSupplier != null) {
+            return warningBannerInfoSupplier.apply(powerAnomalyEvent.getWarningBannerInfo());
+        } else if (powerAnomalyEvent.hasWarningItemInfo() && warningItemInfoSupplier != null) {
+            return warningItemInfoSupplier.apply(powerAnomalyEvent.getWarningItemInfo());
+        }
+        return null;
+    }
+
+    private String getString(PowerAnomalyEvent powerAnomalyEvent,
+                             Function<WarningBannerInfo, String> warningBannerInfoSupplier,
+                             Function<WarningItemInfo, String> warningItemInfoSupplier,
+                             int resourceId, int resourceIndex) {
+        String string =
+                getInfo(powerAnomalyEvent, warningBannerInfoSupplier, warningItemInfoSupplier);
+
+        if (!TextUtils.isEmpty(string) || resourceId < 0) {
+            return string;
+        }
+
+        if (resourceIndex >= 0) {
+            string = mContext.getResources().getStringArray(resourceId)[resourceIndex];
+        }
+
+        return string;
+    }
+
+    @VisibleForTesting
+    void handleBatteryTipsCardUpdated(PowerAnomalyEvent powerAnomalyEvent) {
+        if (!isTipsCardVisible()) {
+            mCardPreference.setVisible(false);
+            return;
+        }
+        if (powerAnomalyEvent == null) {
+            mCardPreference.setVisible(false);
+            return;
+        }
+
+        // Get card preference strings and navigate fragment info
+        final int index = getPowerAnomalyEventIndex(powerAnomalyEvent.getKey());
+
+        String titleString = getString(powerAnomalyEvent, WarningBannerInfo::getTitleString,
+                WarningItemInfo::getTitleString, R.array.power_anomaly_titles, index);
+        if (titleString.isEmpty()) {
+            mCardPreference.setVisible(false);
+            return;
+        }
+
+        String mainBtnString = getString(powerAnomalyEvent,
+                WarningBannerInfo::getMainButtonString, WarningItemInfo::getMainButtonString,
+                R.array.power_anomaly_main_btn_strings, index);
+        String dismissBtnString = getString(powerAnomalyEvent,
+                WarningBannerInfo::getCancelButtonString, WarningItemInfo::getCancelButtonString,
+                R.array.power_anomaly_dismiss_btn_strings, index);
+
+        String destinationClassName = getString(powerAnomalyEvent,
+                WarningBannerInfo::getMainButtonDestination,
+                WarningItemInfo::getMainButtonDestination,
+                -1, -1);
+        Integer sourceMetricsCategory = getInfo(powerAnomalyEvent,
+                WarningBannerInfo::getMainButtonSourceMetricsCategory,
+                WarningItemInfo::getMainButtonSourceMetricsCategory);
+
+        // Updated card preference and main button fragment launcher
+        mCardPreference.setTitle(titleString);
+        mCardPreference.setMainButtonLabel(mainBtnString);
+        mCardPreference.setDismissButtonLabel(dismissBtnString);
+        mCardPreference.setMainButtonLauncherInfo(destinationClassName, sourceMetricsCategory);
+        mCardPreference.setVisible(true);
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
index 3fc44cc..5fc4ad5 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
@@ -17,6 +17,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageEvents.Event;
 import android.app.usage.UsageStatsManager;
 import android.content.ContentValues;
@@ -185,7 +186,8 @@
     /** Converts to {@link AppUsageEvent} from {@link Event} */
     @Nullable
     public static AppUsageEvent convertToAppUsageEvent(
-            Context context, final Event event, final long userId) {
+            Context context, IUsageStatsManager usageStatsManager, final Event event,
+            final long userId) {
         final String packageName = event.getPackageName();
         if (packageName == null) {
             // See b/190609174: Event package names should never be null, but sometimes they are.
@@ -210,7 +212,8 @@
         }
 
         final String effectivePackageName =
-                getEffectivePackageName(context, packageName, taskRootPackageName);
+                getEffectivePackageName(
+                        context, usageStatsManager, packageName, taskRootPackageName);
         try {
             final long uid = context
                     .getPackageManager()
@@ -326,8 +329,9 @@
      */
     @VisibleForTesting
     static String getEffectivePackageName(
-            Context context, final String packageName, final String taskRootPackageName) {
-        final int usageSource = getUsageSource(context);
+            Context context, IUsageStatsManager usageStatsManager, final String packageName,
+            final String taskRootPackageName) {
+        final int usageSource = getUsageSource(context, usageStatsManager);
         switch (usageSource) {
             case UsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY:
                 return !TextUtils.isEmpty(taskRootPackageName)
@@ -372,9 +376,9 @@
         }
     }
 
-    private static int getUsageSource(Context context) {
+    private static int getUsageSource(Context context, IUsageStatsManager usageStatsManager) {
         if (sUsageSource == EMPTY_USAGE_SOURCE) {
-            sUsageSource = DatabaseUtils.getUsageSource(context);
+            sUsageSource = DatabaseUtils.getUsageSource(context, usageStatsManager);
         }
         return sUsageSource;
     }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
index badc359..620ae31 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
@@ -32,6 +32,7 @@
 import android.os.BatteryUsageStatsQuery;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UidBatteryConsumer;
 import android.os.UserBatteryConsumer;
 import android.os.UserHandle;
@@ -108,6 +109,11 @@
     @VisibleForTesting
     static Set<String> sTestSystemAppsPackageNames;
 
+    @VisibleForTesting
+    static IUsageStatsManager sUsageStatsManager =
+            IUsageStatsManager.Stub.asInterface(
+                    ServiceManager.getService(Context.USAGE_STATS_SERVICE));
+
     public static final String CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER =
             "CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER";
 
@@ -338,7 +344,8 @@
                             break;
                         }
                         final AppUsageEvent appUsageEvent =
-                                ConvertUtils.convertToAppUsageEvent(context, event, userId);
+                                ConvertUtils.convertToAppUsageEvent(
+                                        context, sUsageStatsManager, event, userId);
                         if (appUsageEvent != null) {
                             numEventsFetched++;
                             appUsageEventList.add(appUsageEvent);
@@ -694,6 +701,7 @@
             final long eventUserId = firstEvent.getUserId();
             final String packageName = getEffectivePackageName(
                     context,
+                    sUsageStatsManager,
                     firstEvent.getPackageName(),
                     firstEvent.getTaskRootPackageName());
             usageEvents.addAll(deviceEvents);
@@ -966,7 +974,7 @@
         final long startTime = DatabaseUtils.getAppUsageStartTimestampOfUser(
                 context, userID, earliestTimestamp);
         return loadAppUsageEventsForUserFromService(
-                DatabaseUtils.sUsageStatsManager, startTime, now, userID, callingPackage);
+                sUsageStatsManager, startTime, now, userID, callingPackage);
     }
 
     @Nullable
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
index ea1f3ed..b54563b 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
@@ -31,7 +31,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserManager;
 import android.util.Log;
@@ -117,11 +116,6 @@
     @VisibleForTesting
     static Supplier<Cursor> sFakeSupplier;
 
-    @VisibleForTesting
-    static IUsageStatsManager sUsageStatsManager =
-            IUsageStatsManager.Stub.asInterface(
-                    ServiceManager.getService(Context.USAGE_STATS_SERVICE));
-
     private DatabaseUtils() {
     }
 
@@ -488,7 +482,7 @@
      *
      * @see UsageStatsManager#getUsageSource()
      */
-    static int getUsageSource(Context context) {
+    static int getUsageSource(Context context, IUsageStatsManager usageStatsManager) {
         final SharedPreferences sharedPreferences = getSharedPreferences(context);
         if (sharedPreferences != null && sharedPreferences.contains(KEY_LAST_USAGE_SOURCE)) {
             return sharedPreferences
@@ -497,7 +491,7 @@
         int usageSource = ConvertUtils.DEFAULT_USAGE_SOURCE;
 
         try {
-            usageSource = sUsageStatsManager.getUsageSource();
+            usageSource = usageStatsManager.getUsageSource();
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to getUsageSource", e);
         }
diff --git a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
index b4277c4..380c786 100644
--- a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
+++ b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
@@ -4,14 +4,19 @@
 option java_package = "com.android.settings.fuelgauge.batteryusage";
 option java_outer_classname = "PowerAnomalyEventProto";
 
+message PowerAnomalyEventList {
+  repeated PowerAnomalyEvent power_anomaly_events = 1;
+}
+
 message PowerAnomalyEvent {
-  optional int64 timestamp = 1;
-  optional string type = 2;  // e.g. settings, apps
-  optional string key = 3;  // e.g. brightness, significant_increase
-  optional float score = 4;
+  optional string event_id = 1;
+  optional int64 timestamp = 2;
+  optional string type = 3;  // e.g. settings, apps
+  optional string key = 4;  // e.g. brightness, significant_increase
+  optional float score = 5;
   oneof info {
-    WarningBannerInfo warning_banner_info = 5;
-    WarningItemInfo warning_item_info = 6;
+    WarningBannerInfo warning_banner_info = 6;
+    WarningItemInfo warning_item_info = 7;
   }
 }
 
@@ -19,9 +24,11 @@
   optional string title_string = 1;
   optional string description_string = 2;
   optional string main_button_string = 3;
-  optional string main_button_action = 4;
-  optional string cancel_button_string = 5;
-  optional string cancel_button_action = 6;
+  // Used in the SubSettingLauncher.setDestination().
+  optional string main_button_destination = 4;
+  // Used in the SubSettingLauncher.setSourceMetricsCategory().
+  optional int32 main_button_source_metrics_category = 5;
+  optional string cancel_button_string = 6;
 }
 
 message WarningItemInfo {
@@ -31,7 +38,9 @@
   optional string title_string = 4;
   optional string description_string = 5;
   optional string main_button_string = 6;
-  optional string main_button_action = 7;
-  optional string cancel_button_string = 8;
-  optional string cancel_button_action = 9;
+  // Used in the SubSettingLauncher.setDestination().
+  optional string main_button_destination = 7;
+  // Used in the SubSettingLauncher.setSourceMetricsCategory().
+  optional int32 main_button_source_metrics_category = 8;
+  optional string cancel_button_string = 9;
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java
index 5922016..2ba655a 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusUsbFirmwareControllerTest.java
@@ -157,7 +157,7 @@
         when(mFeatureFactory.getStylusFeatureProvider()
                 .isUsbFirmwareUpdateEnabled(any())).thenReturn(true);
         when(mFeatureFactory.getStylusFeatureProvider()
-                .getUsbFirmwareUpdatePreferences(any()))
+                .getUsbFirmwareUpdatePreferences(any(), any()))
                 .thenReturn(Collections.singletonList(mock(Preference.class)));
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
index c9591a5..bf4e893 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
@@ -73,8 +73,8 @@
     }
 
     @Test
-    public void testIsBatteryTipsFeedbackEnabled_returnTrue() {
-        assertThat(mPowerFeatureProvider.isBatteryTipsFeedbackEnabled()).isTrue();
+    public void testIsBatteryTipsFeedbackEnabled_returnFalse() {
+        assertThat(mPowerFeatureProvider.isBatteryTipsFeedbackEnabled()).isFalse();
     }
     @Test
     public void testGetBatteryUsageListConsumePowerThreshold_return0() {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
index 6f9a474..bc787f1 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
@@ -35,11 +35,14 @@
 
     private Context mContext;
     private BatteryTipsCardPreference mBatteryTipsCardPreference;
+    private BatteryTipsController mBatteryTipsController;
 
     @Before
     public void setUp() {
         mContext = spy(RuntimeEnvironment.application);
         mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null);
+        mBatteryTipsController = new BatteryTipsController(mContext);
+        mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
new file mode 100644
index 0000000..0c9a0b0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.LocaleList;
+
+import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.testutils.BatteryTestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.Locale;
+import java.util.TimeZone;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryTipsControllerTest {
+
+    private Context mContext;
+    private BatteryTipsController mBatteryTipsController;
+
+    @Mock
+    private BatteryTipsCardPreference mBatteryTipsCardPreference;
+
+    @Mock
+    private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Locale.setDefault(new Locale("en_US"));
+        org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false);
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        mContext = spy(RuntimeEnvironment.application);
+        final Resources resources = spy(mContext.getResources());
+        resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US")));
+        doReturn(resources).when(mContext).getResources();
+        mBatteryTipsController = new BatteryTipsController(mContext);
+        mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
+        mBatteryTipsController.mPowerUsageFeatureProvider = mPowerUsageFeatureProvider;
+    }
+
+    @Test
+    public void parsePowerAnomalyKey_preDefinedKeys_returnTrue() {
+        final String[] keys = {"adaptive_brightness", "screen_timeout"};
+        for (int index = 0; index < keys.length; index++) {
+            assertThat(mBatteryTipsController.getPowerAnomalyEventIndex(keys[index]))
+                    .isEqualTo(index);
+        }
+    }
+
+    @Test
+    public void parsePowerAnomalyKey_unknownKey_returnTrue() {
+        final String key = "unknown_key_for_test";
+        assertThat(mBatteryTipsController.getPowerAnomalyEventIndex(key)).isEqualTo(-1);
+    }
+
+    @Test
+    public void handleBatteryTipsCardUpdated_null_hidePreference() {
+        mBatteryTipsController.handleBatteryTipsCardUpdated(/* powerAnomalyEvents= */ null);
+
+        verify(mBatteryTipsCardPreference).setVisible(false);
+    }
+
+    @Test
+    public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() {
+        PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
+        when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+
+        mBatteryTipsController.handleBatteryTipsCardUpdated(event);
+
+        // Check pre-defined string
+        verify(mBatteryTipsCardPreference).setTitle(
+                "Turn on adaptive brightness to extend battery life");
+        verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
+        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
+        // Check proto info
+        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
+                "com.android.settings.display.AutoBrightnessSettings",
+                1381);
+        verify(mBatteryTipsCardPreference).setVisible(true);
+    }
+
+    @Test
+    public void handleBatteryTipsCardUpdated_screenTimeoutAnomaly_showAnomaly() {
+        PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent();
+        when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+
+        mBatteryTipsController.handleBatteryTipsCardUpdated(event);
+
+        verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
+        verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
+        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
+        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
+                "com.android.settings.display.ScreenTimeoutSettings",
+                1852);
+        verify(mBatteryTipsCardPreference).setVisible(true);
+    }
+    @Test
+    public void handleBatteryTipsCardUpdated_screenTimeoutAnomalyHasTitle_showAnomaly() {
+        PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent();
+        String testTitle = "TestTitle";
+        event = event.toBuilder()
+                .setWarningBannerInfo(
+                        event.getWarningBannerInfo().toBuilder()
+                                .setTitleString(testTitle)
+                                .build())
+                .build();
+        when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+
+        mBatteryTipsController.handleBatteryTipsCardUpdated(event);
+
+        verify(mBatteryTipsCardPreference).setTitle(testTitle);
+        verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
+        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
+        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
+                "com.android.settings.display.ScreenTimeoutSettings",
+                1852);
+        verify(mBatteryTipsCardPreference).setVisible(true);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java
index 3cbe8a4..e9108bc 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageEvents.Event;
 import android.content.ContentValues;
@@ -61,6 +62,8 @@
     private BatteryUsageStats mBatteryUsageStats;
     @Mock
     private BatteryEntry mMockBatteryEntry;
+    @Mock
+    private IUsageStatsManager mUsageStatsManager;
 
     @Before
     public void setUp() {
@@ -68,6 +71,7 @@
         mContext = spy(RuntimeEnvironment.application);
         ConvertUtils.sUsageSource = ConvertUtils.EMPTY_USAGE_SOURCE;
         when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
+        DataProcessor.sUsageStatsManager = mUsageStatsManager;
     }
 
     @Test
@@ -299,7 +303,7 @@
 
         final long userId = 2;
         final AppUsageEvent appUsageEvent = ConvertUtils.convertToAppUsageEvent(
-                mContext, event, userId);
+                mContext, mUsageStatsManager, event, userId);
         assertThat(appUsageEvent.getTimestamp()).isEqualTo(101L);
         assertThat(appUsageEvent.getType()).isEqualTo(AppUsageEventType.ACTIVITY_RESUMED);
         assertThat(appUsageEvent.getPackageName()).isEqualTo("com.android.settings1");
@@ -320,7 +324,7 @@
 
         final long userId = 1;
         final AppUsageEvent appUsageEvent =
-                ConvertUtils.convertToAppUsageEvent(mContext, event, userId);
+                ConvertUtils.convertToAppUsageEvent(mContext, mUsageStatsManager, event, userId);
         assertThat(appUsageEvent.getTimestamp()).isEqualTo(101L);
         assertThat(appUsageEvent.getType()).isEqualTo(AppUsageEventType.DEVICE_SHUTDOWN);
         assertThat(appUsageEvent.getPackageName()).isEqualTo("com.android.settings1");
@@ -336,7 +340,8 @@
         event.mPackage = null;
 
         final AppUsageEvent appUsageEvent =
-                ConvertUtils.convertToAppUsageEvent(mContext, event, /*userId=*/ 0);
+                ConvertUtils.convertToAppUsageEvent(
+                        mContext, mUsageStatsManager, event, /*userId=*/ 0);
 
         assertThat(appUsageEvent).isNull();
     }
@@ -352,7 +357,7 @@
 
         final long userId = 1;
         final AppUsageEvent appUsageEvent =
-                ConvertUtils.convertToAppUsageEvent(mContext, event, userId);
+                ConvertUtils.convertToAppUsageEvent(mContext, mUsageStatsManager, event, userId);
 
         assertThat(appUsageEvent).isNull();
     }
@@ -453,7 +458,7 @@
         final String taskRootPackageName = "com.android.settings2";
 
         assertThat(ConvertUtils.getEffectivePackageName(
-                mContext, packageName, taskRootPackageName))
+                mContext, mUsageStatsManager, packageName, taskRootPackageName))
                 .isEqualTo(packageName);
     }
 
@@ -463,7 +468,7 @@
         final String taskRootPackageName = "com.android.settings2";
 
         assertThat(ConvertUtils.getEffectivePackageName(
-                mContext, packageName, taskRootPackageName))
+                mContext, mUsageStatsManager, packageName, taskRootPackageName))
                 .isEqualTo(packageName);
     }
 
@@ -474,7 +479,7 @@
         final String taskRootPackageName = "com.android.settings2";
 
         assertThat(ConvertUtils.getEffectivePackageName(
-                mContext, packageName, taskRootPackageName))
+                mContext, mUsageStatsManager, packageName, taskRootPackageName))
                 .isEqualTo(taskRootPackageName);
     }
 
@@ -484,10 +489,10 @@
         final String packageName = "com.android.settings1";
 
         assertThat(ConvertUtils.getEffectivePackageName(
-                mContext, packageName, /*taskRootPackageName=*/ null))
+                mContext, mUsageStatsManager, packageName, /*taskRootPackageName=*/ null))
                 .isEqualTo(packageName);
         assertThat(ConvertUtils.getEffectivePackageName(
-                mContext, packageName, /*taskRootPackageName=*/ ""))
+                mContext, mUsageStatsManager, packageName, /*taskRootPackageName=*/ ""))
                 .isEqualTo(packageName);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
index 7f7fe43..b610cfb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
@@ -72,7 +72,7 @@
         MockitoAnnotations.initMocks(this);
 
         mContext = spy(RuntimeEnvironment.application);
-        DatabaseUtils.sUsageStatsManager = mUsageStatsManager;
+        DataProcessor.sUsageStatsManager = mUsageStatsManager;
         doReturn(mContext).when(mContext).getApplicationContext();
         doReturn(mUserManager)
                 .when(mContext)
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
index 8bed054..c9b635e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
@@ -93,7 +93,7 @@
         mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider;
 
         DataProcessor.sTestSystemAppsPackageNames = Set.of();
-        DatabaseUtils.sUsageStatsManager = mUsageStatsManager;
+        DataProcessor.sUsageStatsManager = mUsageStatsManager;
         doReturn(mIntent).when(mContext).registerReceiver(
                 isA(BroadcastReceiver.class), isA(IntentFilter.class));
         doReturn(100).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_SCALE), anyInt());
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java
index 24be769..8a1ba13 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java
@@ -85,7 +85,7 @@
         doReturn(mPackageManager).when(mMockContext).getPackageManager();
         doReturn(mPackageManager).when(mContext).getPackageManager();
         DatabaseUtils.getSharedPreferences(mContext).edit().clear().apply();
-        DatabaseUtils.sUsageStatsManager = mUsageStatsManager;
+        DataProcessor.sUsageStatsManager = mUsageStatsManager;
     }
 
     @Test
@@ -466,7 +466,7 @@
                 .putInt(DatabaseUtils.KEY_LAST_USAGE_SOURCE, USAGE_SOURCE_TASK_ROOT_ACTIVITY)
                 .apply();
 
-        assertThat(DatabaseUtils.getUsageSource(mContext))
+        assertThat(DatabaseUtils.getUsageSource(mContext, mUsageStatsManager))
                 .isEqualTo(USAGE_SOURCE_TASK_ROOT_ACTIVITY);
     }
 
@@ -474,7 +474,7 @@
     public void getUsageSource_notHasData_writeLoadedData() throws RemoteException {
         when(mUsageStatsManager.getUsageSource()).thenReturn(USAGE_SOURCE_TASK_ROOT_ACTIVITY);
 
-        assertThat(DatabaseUtils.getUsageSource(mContext))
+        assertThat(DatabaseUtils.getUsageSource(mContext, mUsageStatsManager))
                 .isEqualTo(USAGE_SOURCE_TASK_ROOT_ACTIVITY);
         assertThat(
                 DatabaseUtils
@@ -487,7 +487,7 @@
     public void getUsageSource_throwException_writeDefaultData() throws RemoteException {
         when(mUsageStatsManager.getUsageSource()).thenThrow(new RemoteException());
 
-        assertThat(DatabaseUtils.getUsageSource(mContext))
+        assertThat(DatabaseUtils.getUsageSource(mContext, mUsageStatsManager))
                 .isEqualTo(USAGE_SOURCE_CURRENT_ACTIVITY);
         assertThat(
                 DatabaseUtils
diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index c54b750..e99b17f 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.Mockito.when;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.usb.UsbManager;
@@ -25,11 +26,17 @@
 import android.hardware.usb.UsbPortStatus;
 import android.os.BatteryManager;
 import android.os.UserManager;
+
 import androidx.room.Room;
 
+import com.android.settings.display.AutoBrightnessSettings;
+import com.android.settings.display.ScreenTimeoutSettings;
 import com.android.settings.fuelgauge.batteryusage.BatteryInformation;
 import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
 import com.android.settings.fuelgauge.batteryusage.DeviceBatteryState;
+import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEvent;
+import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
+import com.android.settings.fuelgauge.batteryusage.WarningBannerInfo;
 import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao;
 import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
 import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
@@ -193,4 +200,33 @@
         when(mockUsbPortStatus.getComplianceWarnings())
                 .thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_OTHER});
     }
+
+    /** Create an empty power anomaly event list proto. */
+    public static PowerAnomalyEventList createEmptyPowerAnomalyEventList() {
+        return PowerAnomalyEventList.getDefaultInstance();
+    }
+
+    /** Create a power anomaly event proto of adaptive brightness. */
+    public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() {
+        return PowerAnomalyEvent.newBuilder()
+                .setType("settings banner")
+                .setKey("adaptive_brightness")
+                .setWarningBannerInfo(WarningBannerInfo.newBuilder()
+                        .setMainButtonDestination(AutoBrightnessSettings.class.getName())
+                        .setMainButtonSourceMetricsCategory(SettingsEnums.SETTINGS_AUTO_BRIGHTNESS)
+                        .build())
+                .build();
+    }
+
+    /** Create a power anomaly event proto of screen timeout. */
+    public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() {
+        return PowerAnomalyEvent.newBuilder()
+                .setType("settings banner")
+                .setKey("screen_timeout")
+                .setWarningBannerInfo(WarningBannerInfo.newBuilder()
+                        .setMainButtonDestination(ScreenTimeoutSettings.class.getName())
+                        .setMainButtonSourceMetricsCategory(SettingsEnums.SCREEN_TIMEOUT)
+                        .build())
+                .build();
+    }
 }