Impl highlight effect on BatteryChartView slots. am: 6750634259

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/24498956

Change-Id: Iff96ebb33e50b2c2bddbe44eada5bf35f7118531
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/res/layout/battery_chart_graph.xml b/res/layout/battery_chart_graph.xml
index f116c8e..9e816ed 100644
--- a/res/layout/battery_chart_graph.xml
+++ b/res/layout/battery_chart_graph.xml
@@ -27,6 +27,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginVertical="16dp"
+        android:textAlignment="viewStart"
         android:textAppearance="?android:attr/textAppearanceSmall"
         android:textColor="?android:attr/textColorSecondary"
         android:text="@string/battery_usage_chart_graph_hint_last_full_charge" />
@@ -40,7 +41,7 @@
         <com.android.settings.fuelgauge.batteryusage.BatteryChartView
             android:id="@+id/daily_battery_chart"
             android:layout_width="match_parent"
-            android:layout_height="170dp"
+            android:layout_height="@dimen/chartview_layout_height"
             android:layout_marginBottom="16dp"
             android:visibility="gone"
             android:contentDescription="@string/daily_battery_usage_chart"
@@ -50,7 +51,7 @@
         <com.android.settings.fuelgauge.batteryusage.BatteryChartView
             android:id="@+id/hourly_battery_chart"
             android:layout_width="match_parent"
-            android:layout_height="170dp"
+            android:layout_height="@dimen/chartview_layout_height"
             android:layout_marginBottom="16dp"
             android:visibility="visible"
             android:contentDescription="@string/hourly_battery_usage_chart"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index fd582de..4ae140e 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -369,6 +369,12 @@
     <dimen name="chartview_text_padding">6dp</dimen>
     <dimen name="chartview_divider_width">1dp</dimen>
     <dimen name="chartview_divider_height">4dp</dimen>
+    <dimen name="chartview_transom_width">4dp</dimen>
+    <dimen name="chartview_transom_radius">4dp</dimen>
+    <dimen name="chartview_transom_icon_size">12dp</dimen>
+    <dimen name="chartview_transom_padding_top">2dp</dimen>
+    <dimen name="chartview_transom_layout_height">12dp</dimen>
+    <dimen name="chartview_layout_height">182dp</dimen>
     <dimen name="chartview_trapezoid_radius">5dp</dimen>
     <dimen name="chartview_trapezoid_margin_start">1dp</dimen>
     <dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
index d04ab0b..1893096 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
@@ -85,6 +85,10 @@
     int mDailyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
     @VisibleForTesting
     int mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
+    @VisibleForTesting
+    int mDailyHighlightSlotIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
+    @VisibleForTesting
+    int mHourlyHighlightSlotIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
 
     private boolean mIs24HourFormat;
     private View mBatteryChartViewGroup;
@@ -217,6 +221,37 @@
         refreshUi();
     }
 
+    void onHighlightSlotIndexUpdate(int dailyHighlightSlotIndex, int hourlyHighlightSlotIndex) {
+        if (mDailyHighlightSlotIndex == dailyHighlightSlotIndex
+                && mHourlyHighlightSlotIndex == hourlyHighlightSlotIndex) {
+            return;
+        }
+        mDailyHighlightSlotIndex = dailyHighlightSlotIndex;
+        mHourlyHighlightSlotIndex = hourlyHighlightSlotIndex;
+        refreshUi();
+    }
+
+    void selectHighlightSlotIndex() {
+        if (mDailyHighlightSlotIndex == BatteryChartViewModel.SELECTED_INDEX_INVALID
+                || mHourlyHighlightSlotIndex == BatteryChartViewModel.SELECTED_INDEX_INVALID) {
+            return;
+        }
+        if (mDailyHighlightSlotIndex == mDailyChartIndex
+                && mHourlyHighlightSlotIndex == mHourlyChartIndex) {
+            return;
+        }
+        mDailyChartIndex = mDailyHighlightSlotIndex;
+        mHourlyChartIndex = mHourlyHighlightSlotIndex;
+        Log.d(TAG, String.format("onDailyChartSelect:%d, onHourlyChartSelect:%d",
+                mDailyChartIndex, mHourlyChartIndex));
+        refreshUi();
+        mHandler.post(() -> mDailyChartView.announceForAccessibility(
+                getAccessibilityAnnounceMessage()));
+        if (mOnSelectedIndexUpdatedListener != null) {
+            mOnSelectedIndexUpdatedListener.onSelectedIndexUpdated();
+        }
+    }
+
     void setBatteryChartView(@NonNull final BatteryChartView dailyChartView,
             @NonNull final BatteryChartView hourlyChartView) {
         final View parentView = (View) dailyChartView.getParent();
@@ -320,6 +355,7 @@
                 mDailyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
             }
             mDailyViewModel.setSelectedIndex(mDailyChartIndex);
+            mDailyViewModel.setHighlightSlotIndex(mDailyHighlightSlotIndex);
             mDailyChartView.setViewModel(mDailyViewModel);
         }
 
@@ -334,6 +370,9 @@
                 mHourlyChartIndex = BatteryChartViewModel.SELECTED_INDEX_ALL;
             }
             hourlyViewModel.setSelectedIndex(mHourlyChartIndex);
+            hourlyViewModel.setHighlightSlotIndex((mDailyChartIndex == mDailyHighlightSlotIndex)
+                    ? mHourlyHighlightSlotIndex
+                    : BatteryChartViewModel.SELECTED_INDEX_INVALID);
             mHourlyChartView.setViewModel(hourlyViewModel);
         }
     }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index 086f56c..bb468fe 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -31,6 +31,7 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -90,6 +91,15 @@
     private int mTrapezoidHoverColor;
     private int mDefaultTextColor;
     private int mTextPadding;
+    private int mTransomIconSize;
+    private int mTransomTop;
+    private int mTransomViewHeight;
+    private int mTransomLineDefaultColor;
+    private int mTransomLineSelectedColor;
+    private float mTransomPadding;
+    private Drawable mTransomIcon;
+    private Paint mTransomLinePaint;
+    private Paint mTransomSelectedSlotPaint;
     private Paint mDividerPaint;
     private Paint mTrapezoidPaint;
     private Paint mTextPaint;
@@ -123,8 +133,9 @@
             return;
         }
 
-        Log.d(TAG, String.format("setViewModel(): size: %d, selectedIndex: %d.",
-                viewModel.size(), viewModel.selectedIndex()));
+        Log.d(TAG, String.format(
+                "setViewModel(): size: %d, selectedIndex: %d, getHighlightSlotIndex: %d",
+                viewModel.size(), viewModel.selectedIndex(), viewModel.getHighlightSlotIndex()));
         mViewModel = viewModel;
         initializeAxisLabelsBounds();
         initializeTrapezoidSlots(viewModel.size() - 1);
@@ -162,7 +173,7 @@
                         mPercentageBounds[index]);
             }
             // Updates the indent configurations.
-            mIndent.top = mPercentageBounds[0].height();
+            mIndent.top = mPercentageBounds[0].height() + mTransomViewHeight;
             final int textWidth = mPercentageBounds[0].width() + mTextPadding;
             if (isRTL()) {
                 mIndent.left = textWidth;
@@ -196,6 +207,7 @@
         }
         drawVerticalDividers(canvas);
         drawTrapezoids(canvas);
+        drawTransomLine(canvas);
     }
 
     @Override
@@ -340,6 +352,40 @@
                         resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius)));
         // Initializes for drawing text information.
         mTextPadding = resources.getDimensionPixelSize(R.dimen.chartview_text_padding);
+        // Initializes the padding top for drawing text information.
+        mTransomViewHeight = resources.getDimensionPixelSize(
+                R.dimen.chartview_transom_layout_height);
+    }
+
+    private void initializeTransomPaint() {
+        if (mTransomLinePaint != null && mTransomSelectedSlotPaint != null
+                && mTransomIcon != null) {
+            return;
+        }
+        // Initializes the transom line paint.
+        final Resources resources = getContext().getResources();
+        final int transomLineWidth = resources.getDimensionPixelSize(
+                R.dimen.chartview_transom_width);
+        final int transomRadius = resources.getDimensionPixelSize(R.dimen.chartview_transom_radius);
+        mTransomPadding = transomRadius * .5f;
+        mTransomTop = resources.getDimensionPixelSize(R.dimen.chartview_transom_padding_top);
+        mTransomLineDefaultColor = Utils.getDisabled(mContext, DIVIDER_COLOR);
+        mTransomLineSelectedColor = resources.getColor(
+                R.color.color_battery_anomaly_yellow_selector);
+        final int slotHighlightColor = Utils.getDisabled(mContext, mTransomLineSelectedColor);
+        mTransomIconSize = resources.getDimensionPixelSize(R.dimen.chartview_transom_icon_size);
+        mTransomLinePaint = new Paint();
+        mTransomLinePaint.setAntiAlias(true);
+        mTransomLinePaint.setStyle(Paint.Style.STROKE);
+        mTransomLinePaint.setStrokeWidth(transomLineWidth);
+        mTransomLinePaint.setStrokeCap(Paint.Cap.ROUND);
+        mTransomLinePaint.setPathEffect(new CornerPathEffect(transomRadius));
+        mTransomSelectedSlotPaint = new Paint();
+        mTransomSelectedSlotPaint.setAntiAlias(true);
+        mTransomSelectedSlotPaint.setColor(slotHighlightColor);
+        mTransomSelectedSlotPaint.setStyle(Paint.Style.FILL);
+        // Get the companion icon beside transom line
+        mTransomIcon = getResources().getDrawable(R.drawable.ic_battery_tips_warning_icon);
     }
 
     private void drawHorizontalDividers(Canvas canvas) {
@@ -592,6 +638,50 @@
         }
     }
 
+    private boolean isHighlightSlotValid() {
+        return mViewModel != null && mViewModel.getHighlightSlotIndex()
+                != BatteryChartViewModel.SELECTED_INDEX_INVALID;
+    }
+
+    private void drawTransomLine(Canvas canvas) {
+        if (!isHighlightSlotValid()) {
+            return;
+        }
+        initializeTransomPaint();
+        // Draw the whole transom line and a warning icon
+        mTransomLinePaint.setColor(mTransomLineDefaultColor);
+        final int width = getWidth() - abs(mIndent.width());
+        final float transomOffset = mTrapezoidHOffset + mDividerWidth * .5f + mTransomPadding;
+        final float trapezoidBottom = getHeight() - mIndent.bottom - mDividerHeight - mDividerWidth
+                - mTrapezoidVOffset;
+        canvas.drawLine(mIndent.left + transomOffset, mTransomTop,
+                mIndent.left + width - transomOffset, mTransomTop,
+                mTransomLinePaint);
+        drawTransomIcon(canvas);
+        // Draw selected segment of transom line and a highlight slot
+        mTransomLinePaint.setColor(mTransomLineSelectedColor);
+        final int index = mViewModel.getHighlightSlotIndex();
+        final float startX = mTrapezoidSlots[index].mLeft;
+        final float endX = mTrapezoidSlots[index].mRight;
+        canvas.drawLine(startX + mTransomPadding, mTransomTop,
+                endX - mTransomPadding, mTransomTop,
+                mTransomLinePaint);
+        canvas.drawRect(startX, mTransomTop, endX, trapezoidBottom,
+                mTransomSelectedSlotPaint);
+    }
+
+    private void drawTransomIcon(Canvas canvas) {
+        if (mTransomIcon == null) {
+            return;
+        }
+        final int left = isRTL()
+                ? mIndent.left - mTextPadding - mTransomIconSize
+                : getWidth() - abs(mIndent.width()) + mTextPadding;
+        mTransomIcon.setBounds(left, mTransomTop - mTransomIconSize / 2,
+                left + mTransomIconSize, mTransomTop + mTransomIconSize / 2);
+        mTransomIcon.draw(canvas);
+    }
+
     // Searches the corresponding trapezoid index from x location.
     private int getTrapezoidIndex(float x) {
         if (mTrapezoidSlots == null) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java
index f58d241..bf8a771 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewModel.java
@@ -55,6 +55,7 @@
     private final String[] mFullTexts;
 
     private int mSelectedIndex = SELECTED_INDEX_ALL;
+    private int mHighlightSlotIndex = SELECTED_INDEX_INVALID;
 
     BatteryChartViewModel(@NonNull List<Integer> levels, @NonNull List<Long> timestamps,
             @NonNull AxisLabelPosition axisLabelPosition,
@@ -106,6 +107,14 @@
         mSelectedIndex = index;
     }
 
+    public int getHighlightSlotIndex() {
+        return mHighlightSlotIndex;
+    }
+
+    public void setHighlightSlotIndex(int index) {
+        mHighlightSlotIndex = index;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(mLevels, mTimestamps, mSelectedIndex, mAxisLabelPosition);
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java
index 53ebbd9..09d66c7 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelData.java
@@ -20,6 +20,7 @@
 
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
+import android.util.Pair;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -69,6 +70,16 @@
             return String.format(Locale.ENGLISH, "timestamps: %s; levels: %s",
                     Objects.toString(mTimestamps), Objects.toString(mLevels));
         }
+
+        private int getIndexByTimestamps(long startTimestamp, long endTimestamp) {
+            for (int index = 0; index < mTimestamps.size() - 1; index++) {
+                if (mTimestamps.get(index) <= startTimestamp
+                        && endTimestamp <= mTimestamps.get(index + 1)) {
+                    return index;
+                }
+            }
+            return BatteryChartViewModel.SELECTED_INDEX_INVALID;
+        }
     }
 
     /**
@@ -100,6 +111,18 @@
         }
     }
 
+    /** Gets daily and hourly index between start and end timestamps. */
+    public Pair<Integer, Integer> getIndexByTimestamps(long startTimestamp, long endTimestamp) {
+        final int dailyHighlightIndex =
+                mDailyBatteryLevels.getIndexByTimestamps(startTimestamp, endTimestamp);
+        final int hourlyHighlightIndex =
+                (dailyHighlightIndex == BatteryChartViewModel.SELECTED_INDEX_INVALID)
+                        ? BatteryChartViewModel.SELECTED_INDEX_INVALID
+                        : mHourlyBatteryLevelsPerDay.get(dailyHighlightIndex)
+                        .getIndexByTimestamps(startTimestamp, endTimestamp);
+        return Pair.create(dailyHighlightIndex, hourlyHighlightIndex);
+    }
+
     public PeriodBatteryLevelData getDailyBatteryLevels() {
         return mDailyBatteryLevels;
     }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
index 763a0f8..e98077c 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
@@ -16,9 +16,7 @@
 
 package com.android.settings.fuelgauge.batteryusage;
 
-import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.os.Bundle;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
@@ -31,8 +29,6 @@
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
@@ -45,10 +41,17 @@
 
     private static final String TAG = "BatteryTipsCardPreference";
 
-    private final MetricsFeatureProvider mMetricsFeatureProvider;
+    interface OnConfirmListener {
+        void onConfirm();
+    }
 
-    private String mAnomalyEventId;
-    private PowerAnomalyKey mPowerAnomalyKey;
+    interface OnRejectListener {
+        void onReject();
+    }
+
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
+    private OnConfirmListener mOnConfirmListener;
+    private OnRejectListener mOnRejectListener;
     private int mIconResourceId = 0;
     private int mMainButtonStrokeColorResourceId = 0;
 
@@ -56,12 +59,6 @@
     CharSequence mMainButtonLabel;
     @VisibleForTesting
     CharSequence mDismissButtonLabel;
-    @VisibleForTesting
-    String mDestinationComponentName;
-    @VisibleForTesting
-    String mPreferenceHighlightKey;
-    @VisibleForTesting
-    Integer mSourceMetricsCategory;
 
     public BatteryTipsCardPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -69,7 +66,14 @@
         setSelectable(false);
         final FeatureFactory featureFactory = FeatureFactory.getFactory(context);
         mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
-        mPowerAnomalyKey = null;
+    }
+
+    public void setOnConfirmListener(OnConfirmListener listener) {
+        mOnConfirmListener = listener;
+    }
+
+    public void setOnRejectListener(OnRejectListener listener) {
+        mOnRejectListener = listener;
     }
 
     /**
@@ -93,13 +97,6 @@
     }
 
     /**
-     * Sets the anomaly event id which is used in metrics.
-     */
-    public void setAnomalyEventId(final String anomalyEventId) {
-        mAnomalyEventId = anomalyEventId;
-    }
-
-    /**
      * Sets the label of main button in tips card.
      */
     public void setMainButtonLabel(CharSequence label) {
@@ -119,50 +116,18 @@
         }
     }
 
-    /**
-     * Sets the power anomaly key of battery tips card.
-     */
-    public void setPowerAnomalyKey(final PowerAnomalyKey powerAnomalyKey) {
-        mPowerAnomalyKey = powerAnomalyKey;
-    }
-
-    /**
-     * Sets the info of target fragment launched by main button.
-     */
-    public void setMainButtonLauncherInfo(final String destinationClassName,
-            final Integer sourceMetricsCategory, final String highlightKey) {
-        mDestinationComponentName = destinationClassName;
-        mSourceMetricsCategory = sourceMetricsCategory;
-        mPreferenceHighlightKey = highlightKey;
-    }
-
     @Override
     public void onClick(View view) {
         final int viewId = view.getId();
         if (viewId == R.id.main_button || viewId == R.id.tips_card) {
-            if (TextUtils.isEmpty(mDestinationComponentName)) {
-                return;
-            }
-            Bundle arguments = Bundle.EMPTY;
-            if (!TextUtils.isEmpty(mPreferenceHighlightKey)) {
-                arguments = new Bundle(1);
-                arguments.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
-                        mPreferenceHighlightKey);
-            }
-            new SubSettingLauncher(getContext())
-                    .setDestination(mDestinationComponentName)
-                    .setSourceMetricsCategory(mSourceMetricsCategory)
-                    .setArguments(arguments)
-                    .launch();
             setVisible(false);
-            mMetricsFeatureProvider.action(
-                    getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, mAnomalyEventId);
+            if (mOnConfirmListener != null) {
+                mOnConfirmListener.onConfirm();
+            }
         } else if (viewId == R.id.dismiss_button) {
             setVisible(false);
-            mMetricsFeatureProvider.action(
-                    getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, mAnomalyEventId);
-            if (mPowerAnomalyKey != null) {
-                DatabaseUtils.setDismissedPowerAnomalyKeys(getContext(), mPowerAnomalyKey.name());
+            if (mOnRejectListener != null) {
+                mOnRejectListener.onReject();
             }
         }
     }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
index fd81e9b..400e70a 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
@@ -18,13 +18,16 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.os.Bundle;
 import android.text.TextUtils;
 
 import androidx.preference.PreferenceScreen;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
@@ -39,6 +42,21 @@
 
     private final MetricsFeatureProvider mMetricsFeatureProvider;
 
+    /** A callback listener for the battery tips is confirmed. */
+    interface OnAnomalyConfirmListener {
+        /** The callback function for the battery tips is confirmed. */
+        void onAnomalyConfirm();
+    }
+
+    /** A callback listener for the battery tips is rejected. */
+    interface OnAnomalyRejectListener {
+        /** The callback function for the battery tips is rejected. */
+        void onAnomalyReject();
+    }
+
+    private OnAnomalyConfirmListener mOnAnomalyConfirmListener;
+    private OnAnomalyRejectListener mOnAnomalyRejectListener;
+
     @VisibleForTesting
     BatteryTipsCardPreference mCardPreference;
 
@@ -59,6 +77,14 @@
         mCardPreference = screen.findPreference(CARD_PREFERENCE_KEY);
     }
 
+    void setOnAnomalyConfirmListener(OnAnomalyConfirmListener listener) {
+        mOnAnomalyConfirmListener = listener;
+    }
+
+    void setOnAnomalyRejectListener(OnAnomalyRejectListener listener) {
+        mOnAnomalyRejectListener = listener;
+    }
+
     private <T> T getInfo(PowerAnomalyEvent powerAnomalyEvent,
                           Function<WarningBannerInfo, T> warningBannerInfoSupplier,
                           Function<WarningItemInfo, T> warningItemInfoSupplier) {
@@ -95,6 +121,21 @@
                 : getStringFromResource(resourceId, resourceIndex);
     }
 
+    /** Generate a key string of current anomaly to record as dismissed in sharedPreferences. */
+    public static String getDismissRecordKey(PowerAnomalyEvent event) {
+        if (!event.hasKey()) {
+            return null;
+        }
+        switch (event.getKey()){
+            case KEY_APP:
+                return event.hasWarningItemInfo()
+                        && event.getWarningItemInfo().hasDismissRecordKey()
+                        ? event.getWarningItemInfo().getDismissRecordKey() : null;
+            default:
+                return event.getKey().name();
+        }
+    }
+
     void handleBatteryTipsCardUpdated(PowerAnomalyEvent powerAnomalyEvent) {
         if (powerAnomalyEvent == null) {
             mCardPreference.setVisible(false);
@@ -109,44 +150,76 @@
                 R.array.battery_tips_card_colors, cardStyleId, "color");
 
         // Get card preference strings and navigate fragment info
+        final String eventId = powerAnomalyEvent.hasEventId()
+                ? powerAnomalyEvent.getEventId() : null;
         final PowerAnomalyKey powerAnomalyKey = powerAnomalyEvent.hasKey()
                 ? powerAnomalyEvent.getKey() : null;
         final int resourceIndex = powerAnomalyKey != null ? powerAnomalyKey.getNumber() : -1;
 
-        String titleString = getString(powerAnomalyEvent, WarningBannerInfo::getTitleString,
+        final String titleString = getString(powerAnomalyEvent, WarningBannerInfo::getTitleString,
                 WarningItemInfo::getTitleString, R.array.power_anomaly_titles, resourceIndex);
         if (titleString.isEmpty()) {
             mCardPreference.setVisible(false);
             return;
         }
 
-        String mainBtnString = getString(powerAnomalyEvent,
+        final String mainBtnString = getString(powerAnomalyEvent,
                 WarningBannerInfo::getMainButtonString, WarningItemInfo::getMainButtonString,
                 R.array.power_anomaly_main_btn_strings, resourceIndex);
-        String dismissBtnString = getString(powerAnomalyEvent,
+        final String dismissBtnString = getString(powerAnomalyEvent,
                 WarningBannerInfo::getCancelButtonString, WarningItemInfo::getCancelButtonString,
                 R.array.power_anomaly_dismiss_btn_strings, resourceIndex);
 
-        String destinationClassName = getInfo(powerAnomalyEvent,
+        final String destinationClassName = getInfo(powerAnomalyEvent,
                 WarningBannerInfo::getMainButtonDestination, null);
-        Integer sourceMetricsCategory = getInfo(powerAnomalyEvent,
+        final Integer sourceMetricsCategory = getInfo(powerAnomalyEvent,
                 WarningBannerInfo::getMainButtonSourceMetricsCategory, null);
-        String preferenceHighlightKey = getInfo(powerAnomalyEvent,
+        final String preferenceHighlightKey = getInfo(powerAnomalyEvent,
                 WarningBannerInfo::getMainButtonSourceHighlightKey, null);
 
         // Update card preference and main button fragment launcher
-        mCardPreference.setAnomalyEventId(powerAnomalyEvent.getEventId());
-        mCardPreference.setPowerAnomalyKey(powerAnomalyKey);
         mCardPreference.setTitle(titleString);
         mCardPreference.setIconResourceId(iconResId);
         mCardPreference.setMainButtonStrokeColorResourceId(colorResId);
         mCardPreference.setMainButtonLabel(mainBtnString);
         mCardPreference.setDismissButtonLabel(dismissBtnString);
-        mCardPreference.setMainButtonLauncherInfo(
-                destinationClassName, sourceMetricsCategory, preferenceHighlightKey);
-        mCardPreference.setVisible(true);
 
-        mMetricsFeatureProvider.action(mContext,
-                SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, powerAnomalyEvent.getEventId());
+        // Set battery tips card listener
+        mCardPreference.setOnConfirmListener(() -> {
+            if (mOnAnomalyConfirmListener != null) {
+                mOnAnomalyConfirmListener.onAnomalyConfirm();
+            } else if (!TextUtils.isEmpty(destinationClassName)) {
+                // Navigate to sub setting page
+                Bundle arguments = Bundle.EMPTY;
+                if (!TextUtils.isEmpty(preferenceHighlightKey)) {
+                    arguments = new Bundle(1);
+                    arguments.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
+                            preferenceHighlightKey);
+                }
+                new SubSettingLauncher(mContext)
+                        .setDestination(destinationClassName)
+                        .setSourceMetricsCategory(sourceMetricsCategory)
+                        .setArguments(arguments)
+                        .launch();
+            }
+            mMetricsFeatureProvider.action(
+                    mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, eventId);
+        });
+        mCardPreference.setOnRejectListener(() -> {
+            if (mOnAnomalyRejectListener != null) {
+                mOnAnomalyRejectListener.onAnomalyReject();
+            }
+            // For anomaly events with same record key, dismissed until next time full charged.
+            final String dismissRecordKey = getDismissRecordKey(powerAnomalyEvent);
+            if (!TextUtils.isEmpty(dismissRecordKey)) {
+                DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, dismissRecordKey);
+            }
+            mMetricsFeatureProvider.action(
+                    mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, eventId);
+        });
+
+        mCardPreference.setVisible(true);
+        mMetricsFeatureProvider.action(
+                mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, eventId);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
index ccfc1e2..4e8e396 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
@@ -27,6 +27,7 @@
 import android.os.Looper;
 import android.provider.SearchIndexableResource;
 import android.util.Log;
+import android.util.Pair;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.loader.app.LoaderManager;
@@ -67,11 +68,6 @@
 
     private boolean mIsChartDataLoaded = false;
     private long mResumeTimestamp;
-    private BatteryTipsController mBatteryTipsController;
-    private BatteryChartPreferenceController mBatteryChartPreferenceController;
-    private ScreenOnTimeController mScreenOnTimeController;
-    private BatteryUsageBreakdownController mBatteryUsageBreakdownController;
-    private Optional<BatteryLevelData> mBatteryLevelData;
     private Map<Integer, Map<Integer, BatteryDiffData>> mBatteryUsageMap;
 
     private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@@ -87,6 +83,19 @@
                 }
             };
 
+    @VisibleForTesting
+    BatteryTipsController mBatteryTipsController;
+    @VisibleForTesting
+    BatteryChartPreferenceController mBatteryChartPreferenceController;
+    @VisibleForTesting
+    ScreenOnTimeController mScreenOnTimeController;
+    @VisibleForTesting
+    BatteryUsageBreakdownController mBatteryUsageBreakdownController;
+    @VisibleForTesting
+    PowerAnomalyEvent mPowerAnomalyEvent;
+    @VisibleForTesting
+    Optional<BatteryLevelData> mBatteryLevelData;
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -179,6 +188,7 @@
             mIsChartDataLoaded = true;
             mBatteryLevelData = null;
             mBatteryUsageMap = null;
+            mPowerAnomalyEvent = null;
             restartLoader(LoaderIndex.BATTERY_LEVEL_DATA_LOADER, bundle,
                     mBatteryLevelDataLoaderCallbacks);
         }
@@ -254,12 +264,45 @@
         Log.d(TAG, "anomalyEventList = " + anomalyEventList);
         final PowerAnomalyEvent displayEvent =
                 getHighestScoreAnomalyEvent(getContext(), anomalyEventList);
-        if (displayEvent == null) {
+        onDisplayAnomalyEventUpdated(displayEvent);
+    }
+
+    @VisibleForTesting
+    void onDisplayAnomalyEventUpdated(PowerAnomalyEvent event) {
+        mPowerAnomalyEvent = event;
+        if (mBatteryTipsController == null
+                || mBatteryChartPreferenceController == null
+                || mBatteryUsageBreakdownController == null) {
             return;
         }
-        if (mBatteryTipsController != null) {
-            mBatteryTipsController.handleBatteryTipsCardUpdated(displayEvent);
+
+        // Update battery tips card preference & behaviour
+        mBatteryTipsController.setOnAnomalyConfirmListener(null);
+        mBatteryTipsController.setOnAnomalyRejectListener(null);
+        mBatteryTipsController.handleBatteryTipsCardUpdated(mPowerAnomalyEvent);
+
+        // Update highlight slot effect in battery chart view
+        Pair<Integer, Integer> highlightSlotIndexPair = Pair.create(
+                BatteryChartViewModel.SELECTED_INDEX_INVALID,
+                BatteryChartViewModel.SELECTED_INDEX_INVALID);
+        if (mPowerAnomalyEvent != null && mPowerAnomalyEvent.hasWarningItemInfo()) {
+            final WarningItemInfo warningItemInfo = mPowerAnomalyEvent.getWarningItemInfo();
+            final Long startTimestamp = warningItemInfo.hasStartTimestamp()
+                    ? warningItemInfo.getStartTimestamp() : null;
+            final Long endTimestamp = warningItemInfo.hasEndTimestamp()
+                    ? warningItemInfo.getEndTimestamp() : null;
+            if (startTimestamp != null && endTimestamp != null) {
+                highlightSlotIndexPair = mBatteryLevelData.map(levelData ->
+                                levelData.getIndexByTimestamps(startTimestamp, endTimestamp))
+                        .orElse(highlightSlotIndexPair);
+                mBatteryTipsController.setOnAnomalyConfirmListener(
+                        mBatteryChartPreferenceController::selectHighlightSlotIndex);
+                mBatteryTipsController.setOnAnomalyRejectListener(
+                        () -> onDisplayAnomalyEventUpdated(null));
+            }
         }
+        mBatteryChartPreferenceController.onHighlightSlotIndexUpdate(
+                highlightSlotIndexPair.first, highlightSlotIndexPair.second);
     }
 
     private void setBatteryChartPreferenceController() {
@@ -307,8 +350,8 @@
 
         final PowerAnomalyEvent highestScoreEvent = anomalyEventList.getPowerAnomalyEventsList()
                 .stream()
-                .filter(event -> event.hasKey()
-                        && !dismissedPowerAnomalyKeys.contains(event.getKey().name()))
+                .filter(event -> !dismissedPowerAnomalyKeys.contains(
+                        BatteryTipsController.getDismissRecordKey(event)))
                 .max(Comparator.comparing(PowerAnomalyEvent::getScore))
                 .orElse(null);
         Log.d(TAG, "highestScoreAnomalyEvent = " + highestScoreEvent);
@@ -342,6 +385,7 @@
                     controllers.add(new BatteryUsageBreakdownController(
                             context, null /* lifecycle */, null /* activity */,
                             null /* fragment */));
+                    controllers.add(new BatteryTipsController(context));
                     return controllers;
                 }
             };
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 644ab9e..99df215 100644
--- a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
+++ b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
@@ -60,4 +60,6 @@
   optional string description_string = 5;
   optional string main_button_string = 6;
   optional string cancel_button_string = 7;
+  optional string dismiss_record_key = 8;
+  optional string item_key = 9;
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java
index 13d60bb..7dc4eab 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryLevelDataTest.java
@@ -18,6 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.util.Pair;
+
+import com.android.settings.testutils.BatteryTestUtils;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -211,4 +215,29 @@
         assertThat(result.getHourlyBatteryLevelsPerDay().get(0).getLevels())
                 .isEqualTo(List.of(100, 98));
     }
+
+    @Test
+    public void getIndexByTimestamps_returnExpectedResult() {
+        final BatteryLevelData batteryLevelData =
+                new BatteryLevelData(Map.of(
+                        1694354400000L, 1,      // 2023-09-10 22:00:00
+                        1694361600000L, 2,      // 2023-09-11 00:00:00
+                        1694368800000L, 3));    // 2023-09-11 02:00:00
+        final PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+
+        assertThat(batteryLevelData.getIndexByTimestamps(0L, 0L))
+                .isEqualTo(Pair.create(BatteryChartViewModel.SELECTED_INDEX_INVALID,
+                        BatteryChartViewModel.SELECTED_INDEX_INVALID));
+        assertThat(batteryLevelData.getIndexByTimestamps(1694361600000L + 1L, 1694368800000L + 1L))
+                .isEqualTo(Pair.create(BatteryChartViewModel.SELECTED_INDEX_INVALID,
+                        BatteryChartViewModel.SELECTED_INDEX_INVALID));
+        assertThat(batteryLevelData.getIndexByTimestamps(1694361600000L, 1694368800000L))
+                .isEqualTo(Pair.create(1, 0));
+        assertThat(batteryLevelData.getIndexByTimestamps(1694361600000L + 1L, 1694368800000L - 1L))
+                .isEqualTo(Pair.create(1, 0));
+        assertThat(batteryLevelData.getIndexByTimestamps(
+                event.getWarningItemInfo().getStartTimestamp(),
+                event.getWarningItemInfo().getEndTimestamp()))
+                .isEqualTo(Pair.create(1, 0));
+    }
 }
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 ac67dfd..630ff45 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
@@ -19,7 +19,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -45,16 +47,24 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
+import java.util.Map;
+import java.util.Optional;
+
 @RunWith(RobolectricTestRunner.class)
 public final class BatteryTipsCardPreferenceTest {
 
     private Context mContext;
     private FakeFeatureFactory mFeatureFactory;
     private BatteryTipsCardPreference mBatteryTipsCardPreference;
+    private PowerUsageAdvanced mPowerUsageAdvanced;
     private BatteryTipsController mBatteryTipsController;
 
     @Mock
     private View mFakeView;
+    @Mock
+    private BatteryChartPreferenceController mBatteryChartPreferenceController;
+    @Mock
+    private BatteryUsageBreakdownController mBatteryUsageBreakdownController;
 
     @Before
     public void setUp() {
@@ -64,6 +74,14 @@
         mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null);
         mBatteryTipsController = new BatteryTipsController(mContext);
         mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
+        mPowerUsageAdvanced = new PowerUsageAdvanced();
+        mPowerUsageAdvanced.mBatteryTipsController = mBatteryTipsController;
+        mPowerUsageAdvanced.mBatteryChartPreferenceController = mBatteryChartPreferenceController;
+        mPowerUsageAdvanced.mBatteryUsageBreakdownController = mBatteryUsageBreakdownController;
+        mPowerUsageAdvanced.mBatteryLevelData = Optional.of(new BatteryLevelData(Map.of(
+                1694354400000L, 1,      // 2023-09-10 22:00:00
+                1694361600000L, 2,      // 2023-09-11 00:00:00
+                1694368800000L, 3)));    // 2023-09-11 02:00:00
     }
 
     @Test
@@ -71,8 +89,9 @@
         assertThat(mBatteryTipsCardPreference.getLayoutResource()).isEqualTo(
                 R.layout.battery_tips_card);
     }
+
     @Test
-    public void onClick_mainBtn_getAdaptiveBrightnessLauncher() {
+    public void onClick_mainBtnOfSettingsAnomaly_getAdaptiveBrightnessLauncher() {
         final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         PowerAnomalyEvent adaptiveBrightnessAnomaly =
                 BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
@@ -80,10 +99,10 @@
         when(mFakeView.getId()).thenReturn(R.id.main_button);
         doNothing().when(mContext).startActivity(captor.capture());
 
-        mBatteryTipsController.handleBatteryTipsCardUpdated(adaptiveBrightnessAnomaly);
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(adaptiveBrightnessAnomaly);
         mBatteryTipsCardPreference.onClick(mFakeView);
 
-        assertThat(mBatteryTipsCardPreference.isVisible()).isEqualTo(false);
+        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
         verify(mContext).startActivity(any(Intent.class));
         final Intent intent = captor.getValue();
         assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
@@ -96,21 +115,53 @@
 
     @Test
     public void onClick_dismissBtn_cardDismissAndLogged() {
-        PowerAnomalyEvent screenTimeoutAnomaly =
+        final PowerAnomalyEvent screenTimeoutAnomaly =
                 BatteryTestUtils.createScreenTimeoutAnomalyEvent();
         DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
         when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
         when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
 
-        mBatteryTipsController.handleBatteryTipsCardUpdated(screenTimeoutAnomaly);
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(screenTimeoutAnomaly);
         mBatteryTipsCardPreference.onClick(mFakeView);
 
-        assertThat(mBatteryTipsCardPreference.isVisible()).isEqualTo(false);
-        assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext).size())
-                .isEqualTo(1);
+        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
+        assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext)).hasSize(1);
         assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext))
                 .contains(PowerAnomalyKey.KEY_SCREEN_TIMEOUT.name());
         verify(mFeatureFactory.metricsFeatureProvider).action(
                 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, "ScreenTimeoutAnomaly");
     }
+
+    @Test
+    public void onClick_mainBtnOfAppsAnomaly_selectHighlightSlot() {
+        final PowerAnomalyEvent appsAnomaly = BatteryTestUtils.createAppAnomalyEvent();
+        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+        when(mFakeView.getId()).thenReturn(R.id.main_button);
+
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(appsAnomaly);
+        mBatteryTipsCardPreference.onClick(mFakeView);
+
+        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
+        verify(mContext, never()).startActivity(any(Intent.class));
+        verify(mBatteryChartPreferenceController).selectHighlightSlotIndex();
+        verify(mFeatureFactory.metricsFeatureProvider).action(
+                mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, "AppAnomaly");
+    }
+
+    @Test
+    public void onClick_dismissBtnOfAppsAnomaly_removeHighlightSlotIndex() {
+        final PowerAnomalyEvent appsAnomaly = BatteryTestUtils.createAppAnomalyEvent();
+        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
+        when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
+
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(appsAnomaly);
+        mBatteryTipsCardPreference.onClick(mFakeView);
+
+        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
+        verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(
+                eq(BatteryChartViewModel.SELECTED_INDEX_INVALID),
+                eq(BatteryChartViewModel.SELECTED_INDEX_INVALID));
+        verify(mFeatureFactory.metricsFeatureProvider).action(
+                mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, "AppAnomaly");
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
index ac9de1f..913c00a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
@@ -16,6 +16,8 @@
 
 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;
@@ -74,13 +76,25 @@
     }
 
     @Test
+    public void getDismissRecordKey_returnExpectedResult() {
+        assertThat(BatteryTipsController.getDismissRecordKey(
+                BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent()))
+                .isEqualTo("KEY_BRIGHTNESS");
+        assertThat(BatteryTipsController.getDismissRecordKey(
+                BatteryTestUtils.createScreenTimeoutAnomalyEvent()))
+                .isEqualTo("KEY_SCREEN_TIMEOUT");
+        assertThat(BatteryTipsController.getDismissRecordKey(
+                BatteryTestUtils.createAppAnomalyEvent()))
+                .isEqualTo("KEY_APP_1");
+    }
+
+    @Test
     public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() {
         PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
         when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
 
         mBatteryTipsController.handleBatteryTipsCardUpdated(event);
 
-        verify(mBatteryTipsCardPreference).setAnomalyEventId("BrightnessAnomaly");
         // Check pre-defined string
         verify(mBatteryTipsCardPreference).setTitle(
                 "Turn on adaptive brightness to extend battery life");
@@ -90,9 +104,6 @@
         verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
         // Check proto info
-        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
-                "com.android.settings.DisplaySettings",
-                46, "auto_brightness_entry");
         verify(mBatteryTipsCardPreference).setVisible(true);
         verify(mFeatureFactory.metricsFeatureProvider).action(
                 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "BrightnessAnomaly");
@@ -105,16 +116,12 @@
 
         mBatteryTipsController.handleBatteryTipsCardUpdated(event);
 
-        verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
         verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
         verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
         verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
                 R.color.color_accent_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
-                "com.android.settings.display.ScreenTimeoutSettings",
-                1852, "60000");
         verify(mBatteryTipsCardPreference).setVisible(true);
         verify(mFeatureFactory.metricsFeatureProvider).action(
                 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
@@ -134,16 +141,12 @@
 
         mBatteryTipsController.handleBatteryTipsCardUpdated(event);
 
-        verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
         verify(mBatteryTipsCardPreference).setTitle(testTitle);
         verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
         verify(mBatteryTipsCardPreference).setMainButtonStrokeColorResourceId(
                 R.color.color_accent_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
-                "com.android.settings.display.ScreenTimeoutSettings",
-                1852, "60000");
         verify(mBatteryTipsCardPreference).setVisible(true);
         verify(mFeatureFactory.metricsFeatureProvider).action(
                 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
@@ -156,7 +159,6 @@
 
         mBatteryTipsController.handleBatteryTipsCardUpdated(event);
 
-        verify(mBatteryTipsCardPreference).setAnomalyEventId("AppAnomaly");
         verify(mBatteryTipsCardPreference).setTitle(
                 "Chrome used more battery than usual in foreground");
         verify(mBatteryTipsCardPreference).setIconResourceId(
@@ -165,8 +167,6 @@
                 R.color.color_battery_anomaly_yellow_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("Check");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        verify(mBatteryTipsCardPreference).setMainButtonLauncherInfo(
-                null, null, null);
         verify(mBatteryTipsCardPreference).setVisible(true);
         verify(mFeatureFactory.metricsFeatureProvider).action(
                 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "AppAnomaly");
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java
index ee2a8b2..953c2d4 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvancedTest.java
@@ -17,9 +17,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.notNull;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import android.content.Context;
+import android.util.Pair;
 
 import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.shadow.ShadowDashboardFragment;
@@ -27,19 +33,47 @@
 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 org.robolectric.annotation.Config;
 
+import java.util.Map;
+import java.util.Optional;
+import java.util.TimeZone;
+
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = ShadowDashboardFragment.class)
 public final class PowerUsageAdvancedTest {
 
     private Context mContext;
+    private PowerUsageAdvanced mPowerUsageAdvanced;
+
+    @Mock
+    private BatteryTipsController mBatteryTipsController;
+    @Mock
+    private BatteryChartPreferenceController mBatteryChartPreferenceController;
+    @Mock
+    private ScreenOnTimeController mScreenOnTimeController;
+    @Mock
+    private BatteryUsageBreakdownController mBatteryUsageBreakdownController;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
         mContext = spy(RuntimeEnvironment.application);
+
+        mPowerUsageAdvanced = new PowerUsageAdvanced();
+        mPowerUsageAdvanced.mBatteryTipsController = mBatteryTipsController;
+        mPowerUsageAdvanced.mBatteryChartPreferenceController = mBatteryChartPreferenceController;
+        mPowerUsageAdvanced.mScreenOnTimeController = mScreenOnTimeController;
+        mPowerUsageAdvanced.mBatteryUsageBreakdownController = mBatteryUsageBreakdownController;
+        mPowerUsageAdvanced.mBatteryLevelData = Optional.of(new BatteryLevelData(Map.of(
+                1694354400000L, 1,      // 2023-09-10 22:00:00
+                1694361600000L, 2,      // 2023-09-11 00:00:00
+                1694368800000L, 3)));    // 2023-09-11 02:00:00
     }
 
     @Test
@@ -87,6 +121,65 @@
         final PowerAnomalyEvent highestScoreEvent =
                 PowerUsageAdvanced.getHighestScoreAnomalyEvent(mContext, powerAnomalyEventList);
 
-        assertThat(highestScoreEvent).isEqualTo(null);
+        assertThat(highestScoreEvent).isNull();
+    }
+
+    @Test
+    public void onDisplayAnomalyEventUpdated_withSettingsAnomalyEvent_skipHighlightSlotEffect() {
+        final PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
+
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(event);
+
+        assertThat(mPowerUsageAdvanced.mPowerAnomalyEvent).isEqualTo(event);
+        verify(mBatteryTipsController).handleBatteryTipsCardUpdated(eq(event));
+        verify(mPowerUsageAdvanced.mBatteryTipsController).setOnAnomalyConfirmListener(isNull());
+        verify(mPowerUsageAdvanced.mBatteryTipsController).setOnAnomalyRejectListener(isNull());
+        verify(mPowerUsageAdvanced.mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(
+                eq(BatteryChartViewModel.SELECTED_INDEX_INVALID),
+                eq(BatteryChartViewModel.SELECTED_INDEX_INVALID));
+    }
+
+    @Test
+    public void onDisplayAnomalyEventUpdated_withAppAnomalyEvent_setHighlightSlotEffect() {
+        final PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(event);
+
+        assertThat(mPowerUsageAdvanced.mPowerAnomalyEvent).isEqualTo(event);
+        verify(mBatteryTipsController).handleBatteryTipsCardUpdated(eq(event));
+        verify(mBatteryTipsController).setOnAnomalyConfirmListener(isNull());
+        verify(mBatteryTipsController).setOnAnomalyRejectListener(isNull());
+
+        assertThat(event.getWarningItemInfo().hasStartTimestamp()).isTrue();
+        assertThat(event.getWarningItemInfo().hasEndTimestamp()).isTrue();
+        assertThat(mPowerUsageAdvanced.mBatteryLevelData.get().getIndexByTimestamps(
+                event.getWarningItemInfo().getStartTimestamp(),
+                event.getWarningItemInfo().getEndTimestamp()
+        )).isEqualTo(Pair.create(1, 0));
+        verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(eq(1), eq(0));
+        verify(mBatteryTipsController).setOnAnomalyConfirmListener(notNull());
+        verify(mBatteryTipsController).setOnAnomalyRejectListener(notNull());
+    }
+
+    @Test
+    public void onDisplayAnomalyEventUpdated_withNull_removeHighlightSlotEffect() {
+        final PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(event);
+        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(null);
+
+        assertThat(mPowerUsageAdvanced.mPowerAnomalyEvent).isNull();
+        verify(mBatteryTipsController, times(2))
+                .setOnAnomalyConfirmListener(isNull());
+        verify(mBatteryTipsController, times(2))
+                .setOnAnomalyRejectListener(isNull());
+        verify(mBatteryTipsController).setOnAnomalyConfirmListener(notNull());
+        verify(mBatteryTipsController).setOnAnomalyRejectListener(notNull());
+
+        verify(mBatteryChartPreferenceController)
+                .onHighlightSlotIndexUpdate(eq(1), eq(0));
+        verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(
+                eq(BatteryChartViewModel.SELECTED_INDEX_INVALID),
+                eq(BatteryChartViewModel.SELECTED_INDEX_INVALID));
     }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index 3297d1e..1035560 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -283,6 +283,9 @@
                 .setKey(PowerAnomalyKey.KEY_APP)
                 .setScore(2.0f)
                 .setWarningItemInfo(WarningItemInfo.newBuilder()
+                        .setDismissRecordKey("KEY_APP_1")
+                        .setStartTimestamp(1694361600000L)  // 2023-09-11 00:00:00
+                        .setEndTimestamp(1694368800000L)    // 2023-09-11 02:00:00
                         .setTitleString("Chrome used more battery than usual in foreground")
                         .setMainButtonString("Check")
                         .setCancelButtonString("Got it")