diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java
new file mode 100644
index 0000000..10f19f9
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge.batteryusage;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
+import com.android.settings.fuelgauge.BatteryUtils;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
+import com.android.settingslib.utils.StringUtil;
+import com.android.settingslib.widget.FooterPreference;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Controls the update for chart graph and the list items. */
+public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceController
+        implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnDestroy,
+        OnSaveInstanceState, BatteryChartViewV2.OnSelectListener, OnResume,
+        ExpandDividerPreference.OnExpandListener {
+    private static final String TAG = "BatteryChartPreferenceControllerV2";
+    private static final String KEY_FOOTER_PREF = "battery_graph_footer";
+    private static final String PACKAGE_NAME_NONE = "none";
+
+    /** Desired battery history size for timestamp slots. */
+    public static final int DESIRED_HISTORY_SIZE = 25;
+    private static final int CHART_LEVEL_ARRAY_SIZE = 13;
+    private static final int CHART_KEY_ARRAY_SIZE = DESIRED_HISTORY_SIZE;
+    private static final long VALID_USAGE_TIME_DURATION = DateUtils.HOUR_IN_MILLIS * 2;
+    private static final long VALID_DIFF_DURATION = DateUtils.MINUTE_IN_MILLIS * 3;
+
+    // Keys for bundle instance to restore configurations.
+    private static final String KEY_EXPAND_SYSTEM_INFO = "expand_system_info";
+    private static final String KEY_CURRENT_TIME_SLOT = "current_time_slot";
+
+    private static int sUiMode = Configuration.UI_MODE_NIGHT_UNDEFINED;
+
+    @VisibleForTesting
+    Map<Integer, List<BatteryDiffEntry>> mBatteryIndexedMap;
+
+    @VisibleForTesting
+    Context mPrefContext;
+    @VisibleForTesting
+    BatteryUtils mBatteryUtils;
+    @VisibleForTesting
+    PreferenceGroup mAppListPrefGroup;
+    @VisibleForTesting
+    BatteryChartViewV2 mBatteryChartView;
+    @VisibleForTesting
+    ExpandDividerPreference mExpandDividerPreference;
+
+    @VisibleForTesting
+    boolean mIsExpanded = false;
+    @VisibleForTesting
+    int[] mBatteryHistoryLevels;
+    @VisibleForTesting
+    long[] mBatteryHistoryKeys;
+    @VisibleForTesting
+    int mTrapezoidIndex = BatteryChartViewV2.SELECTED_INDEX_INVALID;
+
+    private boolean mIs24HourFormat = false;
+    private boolean mIsFooterPrefAdded = false;
+    private PreferenceScreen mPreferenceScreen;
+    private FooterPreference mFooterPreference;
+
+    private final String mPreferenceKey;
+    private final SettingsActivity mActivity;
+    private final InstrumentedPreferenceFragment mFragment;
+    private final CharSequence[] mNotAllowShowEntryPackages;
+    private final CharSequence[] mNotAllowShowSummaryPackages;
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    // Preference cache to avoid create new instance each time.
+    @VisibleForTesting
+    final Map<String, Preference> mPreferenceCache = new HashMap<>();
+    @VisibleForTesting
+    final List<BatteryDiffEntry> mSystemEntries = new ArrayList<>();
+
+    public BatteryChartPreferenceControllerV2(
+            Context context, String preferenceKey,
+            Lifecycle lifecycle, SettingsActivity activity,
+            InstrumentedPreferenceFragment fragment) {
+        super(context);
+        mActivity = activity;
+        mFragment = fragment;
+        mPreferenceKey = preferenceKey;
+        mIs24HourFormat = DateFormat.is24HourFormat(context);
+        mMetricsFeatureProvider =
+                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
+        mNotAllowShowEntryPackages =
+                FeatureFactory.getFactory(context)
+                        .getPowerUsageFeatureProvider(context)
+                        .getHideApplicationEntries(context);
+        mNotAllowShowSummaryPackages =
+                FeatureFactory.getFactory(context)
+                        .getPowerUsageFeatureProvider(context)
+                        .getHideApplicationSummary(context);
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        if (savedInstanceState == null) {
+            return;
+        }
+        mTrapezoidIndex =
+                savedInstanceState.getInt(KEY_CURRENT_TIME_SLOT, mTrapezoidIndex);
+        mIsExpanded =
+                savedInstanceState.getBoolean(KEY_EXPAND_SYSTEM_INFO, mIsExpanded);
+        Log.d(TAG, String.format("onCreate() slotIndex=%d isExpanded=%b",
+                mTrapezoidIndex, mIsExpanded));
+    }
+
+    @Override
+    public void onResume() {
+        final int currentUiMode =
+                mContext.getResources().getConfiguration().uiMode
+                        & Configuration.UI_MODE_NIGHT_MASK;
+        if (sUiMode != currentUiMode) {
+            sUiMode = currentUiMode;
+            BatteryDiffEntry.clearCache();
+            Log.d(TAG, "clear icon and label cache since uiMode is changed");
+        }
+        mIs24HourFormat = DateFormat.is24HourFormat(mContext);
+        mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle savedInstance) {
+        if (savedInstance == null) {
+            return;
+        }
+        savedInstance.putInt(KEY_CURRENT_TIME_SLOT, mTrapezoidIndex);
+        savedInstance.putBoolean(KEY_EXPAND_SYSTEM_INFO, mIsExpanded);
+        Log.d(TAG, String.format("onSaveInstanceState() slotIndex=%d isExpanded=%b",
+                mTrapezoidIndex, mIsExpanded));
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mActivity.isChangingConfigurations()) {
+            BatteryDiffEntry.clearCache();
+        }
+        mHandler.removeCallbacksAndMessages(/*token=*/ null);
+        mPreferenceCache.clear();
+        if (mAppListPrefGroup != null) {
+            mAppListPrefGroup.removeAll();
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreferenceScreen = screen;
+        mPrefContext = screen.getContext();
+        mAppListPrefGroup = screen.findPreference(mPreferenceKey);
+        mAppListPrefGroup.setOrderingAsAdded(false);
+        mAppListPrefGroup.setTitle(
+                mPrefContext.getString(R.string.battery_app_usage_for_past_24));
+        mFooterPreference = screen.findPreference(KEY_FOOTER_PREF);
+        // Removes footer first until usage data is loaded to avoid flashing.
+        if (mFooterPreference != null) {
+            screen.removePreference(mFooterPreference);
+        }
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return mPreferenceKey;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!(preference instanceof PowerGaugePreference)) {
+            return false;
+        }
+        final PowerGaugePreference powerPref = (PowerGaugePreference) preference;
+        final BatteryDiffEntry diffEntry = powerPref.getBatteryDiffEntry();
+        final BatteryHistEntry histEntry = diffEntry.mBatteryHistEntry;
+        final String packageName = histEntry.mPackageName;
+        final boolean isAppEntry = histEntry.isAppEntry();
+        mMetricsFeatureProvider.action(
+                /* attribution */ SettingsEnums.OPEN_BATTERY_USAGE,
+                /* action */ isAppEntry
+                        ? SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM
+                        : SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM,
+                /* pageId */ SettingsEnums.OPEN_BATTERY_USAGE,
+                TextUtils.isEmpty(packageName) ? PACKAGE_NAME_NONE : packageName,
+                (int) Math.round(diffEntry.getPercentOfTotal()));
+        Log.d(TAG, String.format("handleClick() label=%s key=%s package=%s",
+                diffEntry.getAppLabel(), histEntry.getKey(), histEntry.mPackageName));
+        AdvancedPowerUsageDetail.startBatteryDetailPage(
+                mActivity, mFragment, diffEntry, powerPref.getPercent(),
+                isValidToShowSummary(packageName), getSlotInformation());
+        return true;
+    }
+
+    @Override
+    public void onSelect(int trapezoidIndex) {
+        Log.d(TAG, "onChartSelect:" + trapezoidIndex);
+        refreshUi(trapezoidIndex, /*isForce=*/ false);
+        mMetricsFeatureProvider.action(
+                mPrefContext,
+                trapezoidIndex == BatteryChartViewV2.SELECTED_INDEX_ALL
+                        ? SettingsEnums.ACTION_BATTERY_USAGE_SHOW_ALL
+                        : SettingsEnums.ACTION_BATTERY_USAGE_TIME_SLOT);
+    }
+
+    @Override
+    public void onExpand(boolean isExpanded) {
+        mIsExpanded = isExpanded;
+        mMetricsFeatureProvider.action(
+                mPrefContext,
+                SettingsEnums.ACTION_BATTERY_USAGE_EXPAND_ITEM,
+                isExpanded);
+        refreshExpandUi();
+    }
+
+    void setBatteryHistoryMap(
+            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
+        // Resets all battery history data relative variables.
+        if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
+            mBatteryIndexedMap = null;
+            mBatteryHistoryKeys = null;
+            mBatteryHistoryLevels = null;
+            addFooterPreferenceIfNeeded(false);
+            return;
+        }
+        mBatteryHistoryKeys = getBatteryHistoryKeys(batteryHistoryMap);
+        mBatteryHistoryLevels = new int[CHART_LEVEL_ARRAY_SIZE];
+        for (int index = 0; index < CHART_LEVEL_ARRAY_SIZE; index++) {
+            final long timestamp = mBatteryHistoryKeys[index * 2];
+            final Map<String, BatteryHistEntry> entryMap = batteryHistoryMap.get(timestamp);
+            if (entryMap == null || entryMap.isEmpty()) {
+                Log.e(TAG, "abnormal entry list in the timestamp:"
+                        + ConvertUtils.utcToLocalTime(mPrefContext, timestamp));
+                continue;
+            }
+            // Averages the battery level in each time slot to avoid corner conditions.
+            float batteryLevelCounter = 0;
+            for (BatteryHistEntry entry : entryMap.values()) {
+                batteryLevelCounter += entry.mBatteryLevel;
+            }
+            mBatteryHistoryLevels[index] =
+                    Math.round(batteryLevelCounter / entryMap.size());
+        }
+        forceRefreshUi();
+        Log.d(TAG, String.format(
+                "setBatteryHistoryMap() size=%d key=%s\nlevels=%s",
+                batteryHistoryMap.size(),
+                ConvertUtils.utcToLocalTime(mPrefContext,
+                        mBatteryHistoryKeys[mBatteryHistoryKeys.length - 1]),
+                Arrays.toString(mBatteryHistoryLevels)));
+
+        // Loads item icon and label in the background.
+        new LoadAllItemsInfoTask(batteryHistoryMap).execute();
+    }
+
+    void setBatteryChartView(final BatteryChartViewV2 batteryChartView) {
+        if (mBatteryChartView != batteryChartView) {
+            mHandler.post(() -> setBatteryChartViewInner(batteryChartView));
+        }
+    }
+
+    private void setBatteryChartViewInner(final BatteryChartViewV2 batteryChartView) {
+        mBatteryChartView = batteryChartView;
+        mBatteryChartView.setOnSelectListener(this);
+        forceRefreshUi();
+    }
+
+    private void forceRefreshUi() {
+        final int refreshIndex =
+                mTrapezoidIndex == BatteryChartViewV2.SELECTED_INDEX_INVALID
+                        ? BatteryChartViewV2.SELECTED_INDEX_ALL
+                        : mTrapezoidIndex;
+        if (mBatteryChartView != null) {
+            mBatteryChartView.setLevels(mBatteryHistoryLevels);
+            mBatteryChartView.setSelectedIndex(refreshIndex);
+            setTimestampLabel();
+        }
+        refreshUi(refreshIndex, /*isForce=*/ true);
+    }
+
+    @VisibleForTesting
+    boolean refreshUi(int trapezoidIndex, boolean isForce) {
+        // Invalid refresh condition.
+        if (mBatteryIndexedMap == null
+                || mBatteryChartView == null
+                || (mTrapezoidIndex == trapezoidIndex && !isForce)) {
+            return false;
+        }
+        Log.d(TAG, String.format("refreshUi: index=%d size=%d isForce:%b",
+                trapezoidIndex, mBatteryIndexedMap.size(), isForce));
+
+        mTrapezoidIndex = trapezoidIndex;
+        mHandler.post(() -> {
+            final long start = System.currentTimeMillis();
+            removeAndCacheAllPrefs();
+            addAllPreferences();
+            refreshCategoryTitle();
+            Log.d(TAG, String.format("refreshUi is finished in %d/ms",
+                    (System.currentTimeMillis() - start)));
+        });
+        return true;
+    }
+
+    private void addAllPreferences() {
+        final List<BatteryDiffEntry> entries =
+                mBatteryIndexedMap.get(Integer.valueOf(mTrapezoidIndex));
+        addFooterPreferenceIfNeeded(entries != null && !entries.isEmpty());
+        if (entries == null) {
+            Log.w(TAG, "cannot find BatteryDiffEntry for:" + mTrapezoidIndex);
+            return;
+        }
+        // Separates data into two groups and sort them individually.
+        final List<BatteryDiffEntry> appEntries = new ArrayList<>();
+        mSystemEntries.clear();
+        entries.forEach(entry -> {
+            final String packageName = entry.getPackageName();
+            if (!isValidToShowEntry(packageName)) {
+                Log.w(TAG, "ignore showing item:" + packageName);
+                return;
+            }
+            if (entry.isSystemEntry()) {
+                mSystemEntries.add(entry);
+            } else {
+                appEntries.add(entry);
+            }
+            // Validates the usage time if users click a specific slot.
+            if (mTrapezoidIndex >= 0) {
+                validateUsageTime(entry);
+            }
+        });
+        Collections.sort(appEntries, BatteryDiffEntry.COMPARATOR);
+        Collections.sort(mSystemEntries, BatteryDiffEntry.COMPARATOR);
+        Log.d(TAG, String.format("addAllPreferences() app=%d system=%d",
+                appEntries.size(), mSystemEntries.size()));
+
+        // Adds app entries to the list if it is not empty.
+        if (!appEntries.isEmpty()) {
+            addPreferenceToScreen(appEntries);
+        }
+        // Adds the expabable divider if we have system entries data.
+        if (!mSystemEntries.isEmpty()) {
+            if (mExpandDividerPreference == null) {
+                mExpandDividerPreference = new ExpandDividerPreference(mPrefContext);
+                mExpandDividerPreference.setOnExpandListener(this);
+                mExpandDividerPreference.setIsExpanded(mIsExpanded);
+            }
+            mExpandDividerPreference.setOrder(
+                    mAppListPrefGroup.getPreferenceCount());
+            mAppListPrefGroup.addPreference(mExpandDividerPreference);
+        }
+        refreshExpandUi();
+    }
+
+    @VisibleForTesting
+    void addPreferenceToScreen(List<BatteryDiffEntry> entries) {
+        if (mAppListPrefGroup == null || entries.isEmpty()) {
+            return;
+        }
+        int prefIndex = mAppListPrefGroup.getPreferenceCount();
+        for (BatteryDiffEntry entry : entries) {
+            boolean isAdded = false;
+            final String appLabel = entry.getAppLabel();
+            final Drawable appIcon = entry.getAppIcon();
+            if (TextUtils.isEmpty(appLabel) || appIcon == null) {
+                Log.w(TAG, "cannot find app resource for:" + entry.getPackageName());
+                continue;
+            }
+            final String prefKey = entry.mBatteryHistEntry.getKey();
+            PowerGaugePreference pref = mAppListPrefGroup.findPreference(prefKey);
+            if (pref != null) {
+                isAdded = true;
+                Log.w(TAG, "preference should be removed for:" + entry.getPackageName());
+            } else {
+                pref = (PowerGaugePreference) mPreferenceCache.get(prefKey);
+            }
+            // Creates new innstance if cached preference is not found.
+            if (pref == null) {
+                pref = new PowerGaugePreference(mPrefContext);
+                pref.setKey(prefKey);
+                mPreferenceCache.put(prefKey, pref);
+            }
+            pref.setIcon(appIcon);
+            pref.setTitle(appLabel);
+            pref.setOrder(prefIndex);
+            pref.setPercent(entry.getPercentOfTotal());
+            pref.setSingleLineTitle(true);
+            // Sets the BatteryDiffEntry to preference for launching detailed page.
+            pref.setBatteryDiffEntry(entry);
+            pref.setEnabled(entry.validForRestriction());
+            setPreferenceSummary(pref, entry);
+            if (!isAdded) {
+                mAppListPrefGroup.addPreference(pref);
+            }
+            prefIndex++;
+        }
+    }
+
+    private void removeAndCacheAllPrefs() {
+        if (mAppListPrefGroup == null
+                || mAppListPrefGroup.getPreferenceCount() == 0) {
+            return;
+        }
+        final int prefsCount = mAppListPrefGroup.getPreferenceCount();
+        for (int index = 0; index < prefsCount; index++) {
+            final Preference pref = mAppListPrefGroup.getPreference(index);
+            if (TextUtils.isEmpty(pref.getKey())) {
+                continue;
+            }
+            mPreferenceCache.put(pref.getKey(), pref);
+        }
+        mAppListPrefGroup.removeAll();
+    }
+
+    private void refreshExpandUi() {
+        if (mIsExpanded) {
+            addPreferenceToScreen(mSystemEntries);
+        } else {
+            // Removes and recycles all system entries to hide all of them.
+            for (BatteryDiffEntry entry : mSystemEntries) {
+                final String prefKey = entry.mBatteryHistEntry.getKey();
+                final Preference pref = mAppListPrefGroup.findPreference(prefKey);
+                if (pref != null) {
+                    mAppListPrefGroup.removePreference(pref);
+                    mPreferenceCache.put(pref.getKey(), pref);
+                }
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void refreshCategoryTitle() {
+        final String slotInformation = getSlotInformation();
+        Log.d(TAG, String.format("refreshCategoryTitle:%s", slotInformation));
+        if (mAppListPrefGroup != null) {
+            mAppListPrefGroup.setTitle(
+                    getSlotInformation(/*isApp=*/ true, slotInformation));
+        }
+        if (mExpandDividerPreference != null) {
+            mExpandDividerPreference.setTitle(
+                    getSlotInformation(/*isApp=*/ false, slotInformation));
+        }
+    }
+
+    private String getSlotInformation(boolean isApp, String slotInformation) {
+        // Null means we show all information without a specific time slot.
+        if (slotInformation == null) {
+            return isApp
+                    ? mPrefContext.getString(R.string.battery_app_usage_for_past_24)
+                    : mPrefContext.getString(R.string.battery_system_usage_for_past_24);
+        } else {
+            return isApp
+                    ? mPrefContext.getString(R.string.battery_app_usage_for, slotInformation)
+                    : mPrefContext.getString(R.string.battery_system_usage_for, slotInformation);
+        }
+    }
+
+    private String getSlotInformation() {
+        if (mTrapezoidIndex < 0) {
+            return null;
+        }
+        final String fromHour = ConvertUtils.utcToLocalTimeHour(mPrefContext,
+                mBatteryHistoryKeys[mTrapezoidIndex * 2], mIs24HourFormat);
+        final String toHour = ConvertUtils.utcToLocalTimeHour(mPrefContext,
+                mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2], mIs24HourFormat);
+        return mIs24HourFormat
+                ? String.format("%s–%s", fromHour, toHour)
+                : String.format("%s – %s", fromHour, toHour);
+    }
+
+    @VisibleForTesting
+    void setPreferenceSummary(
+            PowerGaugePreference preference, BatteryDiffEntry entry) {
+        final long foregroundUsageTimeInMs = entry.mForegroundUsageTimeInMs;
+        final long backgroundUsageTimeInMs = entry.mBackgroundUsageTimeInMs;
+        final long totalUsageTimeInMs = foregroundUsageTimeInMs + backgroundUsageTimeInMs;
+        // Checks whether the package is allowed to show summary or not.
+        if (!isValidToShowSummary(entry.getPackageName())) {
+            preference.setSummary(null);
+            return;
+        }
+        String usageTimeSummary = null;
+        // Not shows summary for some system components without usage time.
+        if (totalUsageTimeInMs == 0) {
+            preference.setSummary(null);
+            // Shows background summary only if we don't have foreground usage time.
+        } else if (foregroundUsageTimeInMs == 0 && backgroundUsageTimeInMs != 0) {
+            usageTimeSummary = buildUsageTimeInfo(backgroundUsageTimeInMs, true);
+            // Shows total usage summary only if total usage time is small.
+        } else if (totalUsageTimeInMs < DateUtils.MINUTE_IN_MILLIS) {
+            usageTimeSummary = buildUsageTimeInfo(totalUsageTimeInMs, false);
+        } else {
+            usageTimeSummary = buildUsageTimeInfo(totalUsageTimeInMs, false);
+            // Shows background usage time if it is larger than a minute.
+            if (backgroundUsageTimeInMs > 0) {
+                usageTimeSummary +=
+                        "\n" + buildUsageTimeInfo(backgroundUsageTimeInMs, true);
+            }
+        }
+        preference.setSummary(usageTimeSummary);
+    }
+
+    private String buildUsageTimeInfo(long usageTimeInMs, boolean isBackground) {
+        if (usageTimeInMs < DateUtils.MINUTE_IN_MILLIS) {
+            return mPrefContext.getString(
+                    isBackground
+                            ? R.string.battery_usage_background_less_than_one_minute
+                            : R.string.battery_usage_total_less_than_one_minute);
+        }
+        final CharSequence timeSequence =
+                StringUtil.formatElapsedTime(mPrefContext, usageTimeInMs,
+                        /*withSeconds=*/ false, /*collapseTimeUnit=*/ false);
+        final int resourceId =
+                isBackground
+                        ? R.string.battery_usage_for_background_time
+                        : R.string.battery_usage_for_total_time;
+        return mPrefContext.getString(resourceId, timeSequence);
+    }
+
+    @VisibleForTesting
+    boolean isValidToShowSummary(String packageName) {
+        return !contains(packageName, mNotAllowShowSummaryPackages);
+    }
+
+    @VisibleForTesting
+    boolean isValidToShowEntry(String packageName) {
+        return !contains(packageName, mNotAllowShowEntryPackages);
+    }
+
+    @VisibleForTesting
+    void setTimestampLabel() {
+        if (mBatteryChartView == null || mBatteryHistoryKeys == null) {
+            return;
+        }
+        final long latestTimestamp =
+                mBatteryHistoryKeys[mBatteryHistoryKeys.length - 1];
+        mBatteryChartView.setLatestTimestamp(latestTimestamp);
+    }
+
+    private void addFooterPreferenceIfNeeded(boolean containAppItems) {
+        if (mIsFooterPrefAdded || mFooterPreference == null) {
+            return;
+        }
+        mIsFooterPrefAdded = true;
+        mFooterPreference.setTitle(mPrefContext.getString(
+                containAppItems
+                        ? R.string.battery_usage_screen_footer
+                        : R.string.battery_usage_screen_footer_empty));
+        mHandler.post(() -> mPreferenceScreen.addPreference(mFooterPreference));
+    }
+
+    private static boolean contains(String target, CharSequence[] packageNames) {
+        if (target != null && packageNames != null) {
+            for (CharSequence packageName : packageNames) {
+                if (TextUtils.equals(target, packageName)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    static boolean validateUsageTime(BatteryDiffEntry entry) {
+        final long foregroundUsageTimeInMs = entry.mForegroundUsageTimeInMs;
+        final long backgroundUsageTimeInMs = entry.mBackgroundUsageTimeInMs;
+        final long totalUsageTimeInMs = foregroundUsageTimeInMs + backgroundUsageTimeInMs;
+        if (foregroundUsageTimeInMs > VALID_USAGE_TIME_DURATION
+                || backgroundUsageTimeInMs > VALID_USAGE_TIME_DURATION
+                || totalUsageTimeInMs > VALID_USAGE_TIME_DURATION) {
+            Log.e(TAG, "validateUsageTime() fail for\n" + entry);
+            return false;
+        }
+        return true;
+    }
+
+    /** Used for {@link AppBatteryPreferenceController}. */
+    public static List<BatteryDiffEntry> getBatteryLast24HrUsageData(Context context) {
+        final long start = System.currentTimeMillis();
+        final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap =
+                FeatureFactory.getFactory(context)
+                        .getPowerUsageFeatureProvider(context)
+                        .getBatteryHistory(context);
+        if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
+            return null;
+        }
+        Log.d(TAG, String.format("getBatteryLast24HrData() size=%d time=%d/ms",
+                batteryHistoryMap.size(), (System.currentTimeMillis() - start)));
+        final Map<Integer, List<BatteryDiffEntry>> batteryIndexedMap =
+                ConvertUtils.getIndexedUsageMap(
+                        context,
+                        /*timeSlotSize=*/ CHART_LEVEL_ARRAY_SIZE - 1,
+                        getBatteryHistoryKeys(batteryHistoryMap),
+                        batteryHistoryMap,
+                        /*purgeLowPercentageAndFakeData=*/ true);
+        return batteryIndexedMap.get(BatteryChartViewV2.SELECTED_INDEX_ALL);
+    }
+
+    /** Used for {@link AppBatteryPreferenceController}. */
+    public static BatteryDiffEntry getBatteryLast24HrUsageData(
+            Context context, String packageName, int userId) {
+        if (packageName == null) {
+            return null;
+        }
+        final List<BatteryDiffEntry> entries = getBatteryLast24HrUsageData(context);
+        if (entries == null) {
+            return null;
+        }
+        for (BatteryDiffEntry entry : entries) {
+            final BatteryHistEntry batteryHistEntry = entry.mBatteryHistEntry;
+            if (batteryHistEntry != null
+                    && batteryHistEntry.mConsumerType == ConvertUtils.CONSUMER_TYPE_UID_BATTERY
+                    && batteryHistEntry.mUserId == userId
+                    && packageName.equals(entry.getPackageName())) {
+                return entry;
+            }
+        }
+        return null;
+    }
+
+    private static long[] getBatteryHistoryKeys(
+            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
+        final List<Long> batteryHistoryKeyList =
+                new ArrayList<>(batteryHistoryMap.keySet());
+        Collections.sort(batteryHistoryKeyList);
+        final long[] batteryHistoryKeys = new long[CHART_KEY_ARRAY_SIZE];
+        for (int index = 0; index < CHART_KEY_ARRAY_SIZE; index++) {
+            batteryHistoryKeys[index] = batteryHistoryKeyList.get(index);
+        }
+        return batteryHistoryKeys;
+    }
+
+    // Loads all items icon and label in the background.
+    private final class LoadAllItemsInfoTask
+            extends AsyncTask<Void, Void, Map<Integer, List<BatteryDiffEntry>>> {
+
+        private long[] mBatteryHistoryKeysCache;
+        private Map<Long, Map<String, BatteryHistEntry>> mBatteryHistoryMap;
+
+        private LoadAllItemsInfoTask(
+                Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
+            this.mBatteryHistoryMap = batteryHistoryMap;
+            this.mBatteryHistoryKeysCache = mBatteryHistoryKeys;
+        }
+
+        @Override
+        protected Map<Integer, List<BatteryDiffEntry>> doInBackground(Void... voids) {
+            if (mPrefContext == null || mBatteryHistoryKeysCache == null) {
+                return null;
+            }
+            final long startTime = System.currentTimeMillis();
+            final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap =
+                    ConvertUtils.getIndexedUsageMap(
+                            mPrefContext, /*timeSlotSize=*/ CHART_LEVEL_ARRAY_SIZE - 1,
+                            mBatteryHistoryKeysCache, mBatteryHistoryMap,
+                            /*purgeLowPercentageAndFakeData=*/ true);
+            // Pre-loads each BatteryDiffEntry relative icon and label for all slots.
+            for (List<BatteryDiffEntry> entries : indexedUsageMap.values()) {
+                entries.forEach(entry -> entry.loadLabelAndIcon());
+            }
+            Log.d(TAG, String.format("execute LoadAllItemsInfoTask in %d/ms",
+                    (System.currentTimeMillis() - startTime)));
+            return indexedUsageMap;
+        }
+
+        @Override
+        protected void onPostExecute(
+                Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
+            mBatteryHistoryMap = null;
+            mBatteryHistoryKeysCache = null;
+            if (indexedUsageMap == null) {
+                return;
+            }
+            // Posts results back to main thread to refresh UI.
+            mHandler.post(() -> {
+                mBatteryIndexedMap = indexedUsageMap;
+                forceRefreshUi();
+            });
+        }
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewV2.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewV2.java
new file mode 100644
index 0000000..7c55c40
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewV2.java
@@ -0,0 +1,633 @@
+/*
+ * Copyright (C) 2022 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.android.settings.Utils.formatPercentage;
+
+import static java.lang.Math.round;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.CornerPathEffect;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.Utils;
+
+import java.time.Clock;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/** A widget component to draw chart graph. */
+public class BatteryChartViewV2 extends AppCompatImageView implements View.OnClickListener,
+        AccessibilityManager.AccessibilityStateChangeListener {
+    private static final String TAG = "BatteryChartViewV2";
+    private static final List<String> ACCESSIBILITY_SERVICE_NAMES =
+            Arrays.asList("SwitchAccessService", "TalkBackService", "JustSpeakService");
+
+    private static final int DEFAULT_TRAPEZOID_COUNT = 12;
+    private static final int DEFAULT_TIMESTAMP_COUNT = 4;
+    private static final int TIMESTAMP_GAPS_COUNT = DEFAULT_TIMESTAMP_COUNT - 1;
+    private static final int DIVIDER_COLOR = Color.parseColor("#CDCCC5");
+    private static final long UPDATE_STATE_DELAYED_TIME = 500L;
+
+    /** Selects all trapezoid shapes. */
+    public static final int SELECTED_INDEX_ALL = -1;
+    public static final int SELECTED_INDEX_INVALID = -2;
+
+    /** A callback listener for selected group index is updated. */
+    public interface OnSelectListener {
+        /** The callback function for selected group index is updated. */
+        void onSelect(int trapezoidIndex);
+    }
+
+    private int mDividerWidth;
+    private int mDividerHeight;
+    private int mTrapezoidCount;
+    private float mTrapezoidVOffset;
+    private float mTrapezoidHOffset;
+    private boolean mIsSlotsClickabled;
+    private String[] mPercentages = getPercentages();
+
+    @VisibleForTesting
+    int mHoveredIndex = SELECTED_INDEX_INVALID;
+    @VisibleForTesting
+    int mSelectedIndex = SELECTED_INDEX_INVALID;
+    @VisibleForTesting
+    String[] mTimestamps;
+
+    // Colors for drawing the trapezoid shape and dividers.
+    private int mTrapezoidColor;
+    private int mTrapezoidSolidColor;
+    private int mTrapezoidHoverColor;
+    // For drawing the percentage information.
+    private int mTextPadding;
+    private final Rect mIndent = new Rect();
+    private final Rect[] mPercentageBounds =
+            new Rect[]{new Rect(), new Rect(), new Rect()};
+    // For drawing the timestamp information.
+    private final Rect[] mTimestampsBounds =
+            new Rect[]{new Rect(), new Rect(), new Rect(), new Rect()};
+
+    @VisibleForTesting
+    Handler mHandler = new Handler();
+    @VisibleForTesting
+    final Runnable mUpdateClickableStateRun = () -> updateClickableState();
+
+    private int[] mLevels;
+    private Paint mTextPaint;
+    private Paint mDividerPaint;
+    private Paint mTrapezoidPaint;
+
+    @VisibleForTesting
+    Paint mTrapezoidCurvePaint = null;
+    private TrapezoidSlot[] mTrapezoidSlots;
+    // Records the location to calculate selected index.
+    private float mTouchUpEventX = Float.MIN_VALUE;
+    private BatteryChartViewV2.OnSelectListener mOnSelectListener;
+
+    public BatteryChartViewV2(Context context) {
+        super(context, null);
+    }
+
+    public BatteryChartViewV2(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initializeColors(context);
+        // Registers the click event listener.
+        setOnClickListener(this);
+        setSelectedIndex(SELECTED_INDEX_ALL);
+        setTrapezoidCount(DEFAULT_TRAPEZOID_COUNT);
+        setClickable(false);
+        setLatestTimestamp(0);
+    }
+
+    /** Sets the total trapezoid count for drawing. */
+    public void setTrapezoidCount(int trapezoidCount) {
+        Log.i(TAG, "trapezoidCount:" + trapezoidCount);
+        mTrapezoidCount = trapezoidCount;
+        mTrapezoidSlots = new TrapezoidSlot[trapezoidCount];
+        // Allocates the trapezoid slot array.
+        for (int index = 0; index < trapezoidCount; index++) {
+            mTrapezoidSlots[index] = new TrapezoidSlot();
+        }
+        invalidate();
+    }
+
+    /** Sets all levels value to draw the trapezoid shape */
+    public void setLevels(int[] levels) {
+        Log.d(TAG, "setLevels() " + (levels == null ? "null" : levels.length));
+        if (levels == null) {
+            mLevels = null;
+            return;
+        }
+        // We should provide trapezoid count + 1 data to draw all trapezoids.
+        mLevels = levels.length == mTrapezoidCount + 1 ? levels : null;
+        setClickable(false);
+        invalidate();
+        if (mLevels == null) {
+            return;
+        }
+        // Sets the chart is clickable if there is at least one valid item in it.
+        for (int index = 0; index < mLevels.length - 1; index++) {
+            if (mLevels[index] != 0 && mLevels[index + 1] != 0) {
+                setClickable(true);
+                break;
+            }
+        }
+    }
+
+    /** Sets the selected group index to draw highlight effect. */
+    public void setSelectedIndex(int index) {
+        if (mSelectedIndex != index) {
+            mSelectedIndex = index;
+            invalidate();
+            // Callbacks to the listener if we have.
+            if (mOnSelectListener != null) {
+                mOnSelectListener.onSelect(mSelectedIndex);
+            }
+        }
+    }
+
+    /** Sets the callback to monitor the selected group index. */
+    public void setOnSelectListener(BatteryChartViewV2.OnSelectListener listener) {
+        mOnSelectListener = listener;
+    }
+
+    /** Sets the companion {@link TextView} for percentage information. */
+    public void setCompanionTextView(TextView textView) {
+        if (textView != null) {
+            // Pre-draws the view first to load style atttributions into paint.
+            textView.draw(new Canvas());
+            mTextPaint = textView.getPaint();
+        } else {
+            mTextPaint = null;
+        }
+        setVisibility(View.VISIBLE);
+        requestLayout();
+    }
+
+    /** Sets the latest timestamp for drawing into x-axis information. */
+    public void setLatestTimestamp(long latestTimestamp) {
+        if (latestTimestamp == 0) {
+            latestTimestamp = Clock.systemUTC().millis();
+        }
+        if (mTimestamps == null) {
+            mTimestamps = new String[DEFAULT_TIMESTAMP_COUNT];
+        }
+        final long timeSlotOffset =
+                DateUtils.HOUR_IN_MILLIS * (/*total 24 hours*/ 24 / TIMESTAMP_GAPS_COUNT);
+        final boolean is24HourFormat = DateFormat.is24HourFormat(getContext());
+        for (int index = 0; index < DEFAULT_TIMESTAMP_COUNT; index++) {
+            mTimestamps[index] =
+                    ConvertUtils.utcToLocalTimeHour(
+                            getContext(),
+                            latestTimestamp - (TIMESTAMP_GAPS_COUNT - index)
+                                    * timeSlotOffset,
+                            is24HourFormat);
+        }
+        requestLayout();
+    }
+
+    @Override
+    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        // Measures text bounds and updates indent configuration.
+        if (mTextPaint != null) {
+            for (int index = 0; index < mPercentages.length; index++) {
+                mTextPaint.getTextBounds(
+                        mPercentages[index], 0, mPercentages[index].length(),
+                        mPercentageBounds[index]);
+            }
+            // Updates the indent configurations.
+            mIndent.top = mPercentageBounds[0].height();
+            mIndent.right = mPercentageBounds[0].width() + mTextPadding;
+
+            if (mTimestamps != null) {
+                int maxHeight = 0;
+                for (int index = 0; index < DEFAULT_TIMESTAMP_COUNT; index++) {
+                    mTextPaint.getTextBounds(
+                            mTimestamps[index], 0, mTimestamps[index].length(),
+                            mTimestampsBounds[index]);
+                    maxHeight = Math.max(maxHeight, mTimestampsBounds[index].height());
+                }
+                mIndent.bottom = maxHeight + round(mTextPadding * 1.5f);
+            }
+            Log.d(TAG, "setIndent:" + mPercentageBounds[0]);
+        } else {
+            mIndent.set(0, 0, 0, 0);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+        drawHorizontalDividers(canvas);
+        drawVerticalDividers(canvas);
+        drawTrapezoids(canvas);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        // Caches the location to calculate selected trapezoid index.
+        final int action = event.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_UP:
+                mTouchUpEventX = event.getX();
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                mTouchUpEventX = Float.MIN_VALUE; // reset
+                break;
+        }
+        return super.onTouchEvent(event);
+    }
+
+    @Override
+    public boolean onHoverEvent(MotionEvent event) {
+        final int action = event.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_HOVER_ENTER:
+            case MotionEvent.ACTION_HOVER_MOVE:
+                final int trapezoidIndex = getTrapezoidIndex(event.getX());
+                if (mHoveredIndex != trapezoidIndex) {
+                    mHoveredIndex = trapezoidIndex;
+                    invalidate();
+                }
+                break;
+        }
+        return super.onHoverEvent(event);
+    }
+
+    @Override
+    public void onHoverChanged(boolean hovered) {
+        super.onHoverChanged(hovered);
+        if (!hovered) {
+            mHoveredIndex = SELECTED_INDEX_INVALID; // reset
+            invalidate();
+        }
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (mTouchUpEventX == Float.MIN_VALUE) {
+            Log.w(TAG, "invalid motion event for onClick() callback");
+            return;
+        }
+        final int trapezoidIndex = getTrapezoidIndex(mTouchUpEventX);
+        // Ignores the click event if the level is zero.
+        if (trapezoidIndex == SELECTED_INDEX_INVALID
+                || !isValidToDraw(trapezoidIndex)) {
+            return;
+        }
+        // Selects all if users click the same trapezoid item two times.
+        if (trapezoidIndex == mSelectedIndex) {
+            setSelectedIndex(SELECTED_INDEX_ALL);
+        } else {
+            setSelectedIndex(trapezoidIndex);
+        }
+        view.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateClickableState();
+        mContext.getSystemService(AccessibilityManager.class)
+                .addAccessibilityStateChangeListener(/*listener=*/ this);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mContext.getSystemService(AccessibilityManager.class)
+                .removeAccessibilityStateChangeListener(/*listener=*/ this);
+        mHandler.removeCallbacks(mUpdateClickableStateRun);
+    }
+
+    @Override
+    public void onAccessibilityStateChanged(boolean enabled) {
+        Log.d(TAG, "onAccessibilityStateChanged:" + enabled);
+        mHandler.removeCallbacks(mUpdateClickableStateRun);
+        // We should delay it a while since accessibility manager will spend
+        // some times to bind with new enabled accessibility services.
+        mHandler.postDelayed(
+                mUpdateClickableStateRun, UPDATE_STATE_DELAYED_TIME);
+    }
+
+    private void updateClickableState() {
+        final Context context = mContext;
+        mIsSlotsClickabled =
+                FeatureFactory.getFactory(context)
+                        .getPowerUsageFeatureProvider(context)
+                        .isChartGraphSlotsEnabled(context)
+                        && !isAccessibilityEnabled(context);
+        Log.d(TAG, "isChartGraphSlotsEnabled:" + mIsSlotsClickabled);
+        setClickable(isClickable());
+        // Initializes the trapezoid curve paint for non-clickable case.
+        if (!mIsSlotsClickabled && mTrapezoidCurvePaint == null) {
+            mTrapezoidCurvePaint = new Paint();
+            mTrapezoidCurvePaint.setAntiAlias(true);
+            mTrapezoidCurvePaint.setColor(mTrapezoidSolidColor);
+            mTrapezoidCurvePaint.setStyle(Paint.Style.STROKE);
+            mTrapezoidCurvePaint.setStrokeWidth(mDividerWidth * 2);
+        } else if (mIsSlotsClickabled) {
+            mTrapezoidCurvePaint = null;
+            // Sets levels again to force update the click state.
+            setLevels(mLevels);
+        }
+        invalidate();
+    }
+
+    @Override
+    public void setClickable(boolean clickable) {
+        super.setClickable(mIsSlotsClickabled && clickable);
+    }
+
+    @VisibleForTesting
+    void setClickableForce(boolean clickable) {
+        super.setClickable(clickable);
+    }
+
+    private void initializeColors(Context context) {
+        setBackgroundColor(Color.TRANSPARENT);
+        mTrapezoidSolidColor = Utils.getColorAccentDefaultColor(context);
+        mTrapezoidColor = Utils.getDisabled(context, mTrapezoidSolidColor);
+        mTrapezoidHoverColor = Utils.getColorAttrDefaultColor(context,
+                com.android.internal.R.attr.colorAccentSecondaryVariant);
+        // Initializes the divider line paint.
+        final Resources resources = getContext().getResources();
+        mDividerWidth = resources.getDimensionPixelSize(R.dimen.chartview_divider_width);
+        mDividerHeight = resources.getDimensionPixelSize(R.dimen.chartview_divider_height);
+        mDividerPaint = new Paint();
+        mDividerPaint.setAntiAlias(true);
+        mDividerPaint.setColor(DIVIDER_COLOR);
+        mDividerPaint.setStyle(Paint.Style.STROKE);
+        mDividerPaint.setStrokeWidth(mDividerWidth);
+        Log.i(TAG, "mDividerWidth:" + mDividerWidth);
+        Log.i(TAG, "mDividerHeight:" + mDividerHeight);
+        // Initializes the trapezoid paint.
+        mTrapezoidHOffset = resources.getDimension(R.dimen.chartview_trapezoid_margin_start);
+        mTrapezoidVOffset = resources.getDimension(R.dimen.chartview_trapezoid_margin_bottom);
+        mTrapezoidPaint = new Paint();
+        mTrapezoidPaint.setAntiAlias(true);
+        mTrapezoidPaint.setColor(mTrapezoidSolidColor);
+        mTrapezoidPaint.setStyle(Paint.Style.FILL);
+        mTrapezoidPaint.setPathEffect(
+                new CornerPathEffect(
+                        resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius)));
+        // Initializes for drawing text information.
+        mTextPadding = resources.getDimensionPixelSize(R.dimen.chartview_text_padding);
+    }
+
+    private void drawHorizontalDividers(Canvas canvas) {
+        final int width = getWidth() - mIndent.right;
+        final int height = getHeight() - mIndent.top - mIndent.bottom;
+        // Draws the top divider line for 100% curve.
+        float offsetY = mIndent.top + mDividerWidth * .5f;
+        canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
+        drawPercentage(canvas, /*index=*/ 0, offsetY);
+
+        // Draws the center divider line for 50% curve.
+        final float availableSpace =
+                height - mDividerWidth * 2 - mTrapezoidVOffset - mDividerHeight;
+        offsetY = mIndent.top + mDividerWidth + availableSpace * .5f;
+        canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
+        drawPercentage(canvas, /*index=*/ 1, offsetY);
+
+        // Draws the bottom divider line for 0% curve.
+        offsetY = mIndent.top + (height - mDividerHeight - mDividerWidth * .5f);
+        canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
+        drawPercentage(canvas, /*index=*/ 2, offsetY);
+    }
+
+    private void drawPercentage(Canvas canvas, int index, float offsetY) {
+        if (mTextPaint != null) {
+            canvas.drawText(
+                    mPercentages[index],
+                    getWidth() - mPercentageBounds[index].width()
+                            - mPercentageBounds[index].left,
+                    offsetY + mPercentageBounds[index].height() * .5f,
+                    mTextPaint);
+        }
+    }
+
+    private void drawVerticalDividers(Canvas canvas) {
+        final int width = getWidth() - mIndent.right;
+        final int dividerCount = mTrapezoidCount + 1;
+        final float dividerSpace = dividerCount * mDividerWidth;
+        final float unitWidth = (width - dividerSpace) / (float) mTrapezoidCount;
+        final float bottomY = getHeight() - mIndent.bottom;
+        final float startY = bottomY - mDividerHeight;
+        final float trapezoidSlotOffset = mTrapezoidHOffset + mDividerWidth * .5f;
+        // Draws each vertical dividers.
+        float startX = mDividerWidth * .5f;
+        for (int index = 0; index < dividerCount; index++) {
+            canvas.drawLine(startX, startY, startX, bottomY, mDividerPaint);
+            final float nextX = startX + mDividerWidth + unitWidth;
+            // Updates the trapezoid slots for drawing.
+            if (index < mTrapezoidSlots.length) {
+                mTrapezoidSlots[index].mLeft = round(startX + trapezoidSlotOffset);
+                mTrapezoidSlots[index].mRight = round(nextX - trapezoidSlotOffset);
+            }
+            startX = nextX;
+        }
+        // Draws the timestamp slot information.
+        if (mTimestamps != null) {
+            final float[] xOffsets = new float[DEFAULT_TIMESTAMP_COUNT];
+            final float baselineX = mDividerWidth * .5f;
+            final float offsetX = mDividerWidth + unitWidth;
+            final int slotBarOffset = (/*total 12 bars*/ 12) / TIMESTAMP_GAPS_COUNT;
+            for (int index = 0; index < DEFAULT_TIMESTAMP_COUNT; index++) {
+                xOffsets[index] = baselineX + index * offsetX * slotBarOffset;
+            }
+            drawTimestamp(canvas, xOffsets);
+        }
+    }
+
+    private void drawTimestamp(Canvas canvas, float[] xOffsets) {
+        // Draws the 1st timestamp info.
+        canvas.drawText(
+                mTimestamps[0],
+                xOffsets[0] - mTimestampsBounds[0].left,
+                getTimestampY(0), mTextPaint);
+        final int latestIndex = DEFAULT_TIMESTAMP_COUNT - 1;
+        // Draws the last timestamp info.
+        canvas.drawText(
+                mTimestamps[latestIndex],
+                xOffsets[latestIndex] - mTimestampsBounds[latestIndex].width()
+                        - mTimestampsBounds[latestIndex].left,
+                getTimestampY(latestIndex), mTextPaint);
+        // Draws the rest of timestamp info since it is located in the center.
+        for (int index = 1; index <= DEFAULT_TIMESTAMP_COUNT - 2; index++) {
+            canvas.drawText(
+                    mTimestamps[index],
+                    xOffsets[index]
+                            - (mTimestampsBounds[index].width() - mTimestampsBounds[index].left)
+                            * .5f,
+                    getTimestampY(index), mTextPaint);
+
+        }
+    }
+
+    private int getTimestampY(int index) {
+        return getHeight() - mTimestampsBounds[index].height()
+                + (mTimestampsBounds[index].height() + mTimestampsBounds[index].top)
+                + round(mTextPadding * 1.5f);
+    }
+
+    private void drawTrapezoids(Canvas canvas) {
+        // Ignores invalid trapezoid data.
+        if (mLevels == null) {
+            return;
+        }
+        final float trapezoidBottom =
+                getHeight() - mIndent.bottom - mDividerHeight - mDividerWidth
+                        - mTrapezoidVOffset;
+        final float availableSpace = trapezoidBottom - mDividerWidth * .5f - mIndent.top;
+        final float unitHeight = availableSpace / 100f;
+        // Draws all trapezoid shapes into the canvas.
+        final Path trapezoidPath = new Path();
+        Path trapezoidCurvePath = null;
+        for (int index = 0; index < mTrapezoidCount; index++) {
+            // Not draws the trapezoid for corner or not initialization cases.
+            if (!isValidToDraw(index)) {
+                if (mTrapezoidCurvePaint != null && trapezoidCurvePath != null) {
+                    canvas.drawPath(trapezoidCurvePath, mTrapezoidCurvePaint);
+                    trapezoidCurvePath = null;
+                }
+                continue;
+            }
+            // Configures the trapezoid paint color.
+            final int trapezoidColor =
+                    !mIsSlotsClickabled
+                            ? mTrapezoidColor
+                            : mSelectedIndex == index || mSelectedIndex == SELECTED_INDEX_ALL
+                                    ? mTrapezoidSolidColor : mTrapezoidColor;
+            final boolean isHoverState =
+                    mIsSlotsClickabled && mHoveredIndex == index && isValidToDraw(mHoveredIndex);
+            mTrapezoidPaint.setColor(isHoverState ? mTrapezoidHoverColor : trapezoidColor);
+
+            final float leftTop = round(trapezoidBottom - mLevels[index] * unitHeight);
+            final float rightTop = round(trapezoidBottom - mLevels[index + 1] * unitHeight);
+            trapezoidPath.reset();
+            trapezoidPath.moveTo(mTrapezoidSlots[index].mLeft, trapezoidBottom);
+            trapezoidPath.lineTo(mTrapezoidSlots[index].mLeft, leftTop);
+            trapezoidPath.lineTo(mTrapezoidSlots[index].mRight, rightTop);
+            trapezoidPath.lineTo(mTrapezoidSlots[index].mRight, trapezoidBottom);
+            // A tricky way to make the trapezoid shape drawing the rounded corner.
+            trapezoidPath.lineTo(mTrapezoidSlots[index].mLeft, trapezoidBottom);
+            trapezoidPath.lineTo(mTrapezoidSlots[index].mLeft, leftTop);
+            // Draws the trapezoid shape into canvas.
+            canvas.drawPath(trapezoidPath, mTrapezoidPaint);
+
+            // Generates path for non-clickable trapezoid curve.
+            if (mTrapezoidCurvePaint != null) {
+                if (trapezoidCurvePath == null) {
+                    trapezoidCurvePath = new Path();
+                    trapezoidCurvePath.moveTo(mTrapezoidSlots[index].mLeft, leftTop);
+                } else {
+                    trapezoidCurvePath.lineTo(mTrapezoidSlots[index].mLeft, leftTop);
+                }
+                trapezoidCurvePath.lineTo(mTrapezoidSlots[index].mRight, rightTop);
+            }
+        }
+        // Draws the trapezoid curve for non-clickable case.
+        if (mTrapezoidCurvePaint != null && trapezoidCurvePath != null) {
+            canvas.drawPath(trapezoidCurvePath, mTrapezoidCurvePaint);
+            trapezoidCurvePath = null;
+        }
+    }
+
+    // Searches the corresponding trapezoid index from x location.
+    private int getTrapezoidIndex(float x) {
+        for (int index = 0; index < mTrapezoidSlots.length; index++) {
+            final TrapezoidSlot slot = mTrapezoidSlots[index];
+            if (x >= slot.mLeft - mTrapezoidHOffset
+                    && x <= slot.mRight + mTrapezoidHOffset) {
+                return index;
+            }
+        }
+        return SELECTED_INDEX_INVALID;
+    }
+
+    private boolean isValidToDraw(int trapezoidIndex) {
+        return mLevels != null
+                && trapezoidIndex >= 0
+                && trapezoidIndex < mLevels.length - 1
+                && mLevels[trapezoidIndex] != 0
+                && mLevels[trapezoidIndex + 1] != 0;
+    }
+
+    private static String[] getPercentages() {
+        return new String[]{
+                formatPercentage(/*percentage=*/ 100, /*round=*/ true),
+                formatPercentage(/*percentage=*/ 50, /*round=*/ true),
+                formatPercentage(/*percentage=*/ 0, /*round=*/ true)};
+    }
+
+    @VisibleForTesting
+    static boolean isAccessibilityEnabled(Context context) {
+        final AccessibilityManager accessibilityManager =
+                context.getSystemService(AccessibilityManager.class);
+        if (!accessibilityManager.isEnabled()) {
+            return false;
+        }
+        final List<AccessibilityServiceInfo> serviceInfoList =
+                accessibilityManager.getEnabledAccessibilityServiceList(
+                        AccessibilityServiceInfo.FEEDBACK_SPOKEN
+                                | AccessibilityServiceInfo.FEEDBACK_GENERIC);
+        for (AccessibilityServiceInfo info : serviceInfoList) {
+            for (String serviceName : ACCESSIBILITY_SERVICE_NAMES) {
+                final String serviceId = info.getId();
+                if (serviceId != null && serviceId.contains(serviceName)) {
+                    Log.d(TAG, "acccessibilityEnabled:" + serviceId);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // A container class for each trapezoid left and right location.
+    private static final class TrapezoidSlot {
+        public float mLeft;
+        public float mRight;
+
+        @Override
+        public String toString() {
+            return String.format(Locale.US, "TrapezoidSlot[%f,%f]", mLeft, mRight);
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java
new file mode 100644
index 0000000..e9d6268
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2022 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.ArgumentMatchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.settings.SettingsEnums;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.LocaleList;
+import android.text.format.DateUtils;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceGroup;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.fuelgauge.BatteryUtils;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryChartPreferenceControllerV2Test {
+    private static final String PREF_KEY = "pref_key";
+    private static final String PREF_SUMMARY = "fake preference summary";
+    private static final int DESIRED_HISTORY_SIZE =
+            BatteryChartPreferenceControllerV2.DESIRED_HISTORY_SIZE;
+
+    @Mock
+    private InstrumentedPreferenceFragment mFragment;
+    @Mock
+    private SettingsActivity mSettingsActivity;
+    @Mock
+    private PreferenceGroup mAppListGroup;
+    @Mock
+    private Drawable mDrawable;
+    @Mock
+    private BatteryHistEntry mBatteryHistEntry;
+    @Mock
+    private BatteryChartViewV2 mBatteryChartView;
+    @Mock
+    private PowerGaugePreference mPowerGaugePreference;
+    @Mock
+    private BatteryUtils mBatteryUtils;
+
+    private Context mContext;
+    private FakeFeatureFactory mFeatureFactory;
+    private BatteryDiffEntry mBatteryDiffEntry;
+    private MetricsFeatureProvider mMetricsFeatureProvider;
+    private BatteryChartPreferenceControllerV2 mBatteryChartPreferenceController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Locale.setDefault(new Locale("en_US"));
+        org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
+        mContext = spy(RuntimeEnvironment.application);
+        final Resources resources = spy(mContext.getResources());
+        resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US")));
+        doReturn(resources).when(mContext).getResources();
+        doReturn(new String[]{"com.android.googlequicksearchbox"})
+                .when(mFeatureFactory.powerUsageFeatureProvider)
+                .getHideApplicationSummary(mContext);
+        doReturn(new String[]{"com.android.gms.persistent"})
+                .when(mFeatureFactory.powerUsageFeatureProvider)
+                .getHideApplicationEntries(mContext);
+        mBatteryChartPreferenceController = createController();
+        mBatteryChartPreferenceController.mPrefContext = mContext;
+        mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup;
+        mBatteryChartPreferenceController.mBatteryChartView = mBatteryChartView;
+        mBatteryDiffEntry = new BatteryDiffEntry(
+                mContext,
+                /*foregroundUsageTimeInMs=*/ 1,
+                /*backgroundUsageTimeInMs=*/ 2,
+                /*consumePower=*/ 3,
+                mBatteryHistEntry);
+        mBatteryDiffEntry = spy(mBatteryDiffEntry);
+        // Adds fake testing data.
+        BatteryDiffEntry.sResourceCache.put(
+                "fakeBatteryDiffEntryKey",
+                new BatteryEntry.NameAndIcon("fakeName", /*icon=*/ null, /*iconId=*/ 1));
+        mBatteryChartPreferenceController.setBatteryHistoryMap(
+                createBatteryHistoryMap());
+    }
+
+    @Test
+    public void testOnDestroy_activityIsChanging_clearBatteryEntryCache() {
+        doReturn(true).when(mSettingsActivity).isChangingConfigurations();
+        // Ensures the testing environment is correct.
+        assertThat(BatteryDiffEntry.sResourceCache).hasSize(1);
+
+        mBatteryChartPreferenceController.onDestroy();
+        assertThat(BatteryDiffEntry.sResourceCache).isEmpty();
+    }
+
+    @Test
+    public void testOnDestroy_activityIsNotChanging_notClearBatteryEntryCache() {
+        doReturn(false).when(mSettingsActivity).isChangingConfigurations();
+        // Ensures the testing environment is correct.
+        assertThat(BatteryDiffEntry.sResourceCache).hasSize(1);
+
+        mBatteryChartPreferenceController.onDestroy();
+        assertThat(BatteryDiffEntry.sResourceCache).isNotEmpty();
+    }
+
+    @Test
+    public void testOnDestroy_clearPreferenceCache() {
+        // Ensures the testing environment is correct.
+        mBatteryChartPreferenceController.mPreferenceCache.put(
+                PREF_KEY, mPowerGaugePreference);
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
+
+        mBatteryChartPreferenceController.onDestroy();
+        // Verifies the result after onDestroy.
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+    }
+
+    @Test
+    public void testOnDestroy_removeAllPreferenceFromPreferenceGroup() {
+        mBatteryChartPreferenceController.onDestroy();
+        verify(mAppListGroup).removeAll();
+    }
+
+    @Test
+    public void testSetBatteryHistoryMap_createExpectedKeysAndLevels() {
+        mBatteryChartPreferenceController.setBatteryHistoryMap(
+                createBatteryHistoryMap());
+
+        // Verifies the created battery keys array.
+        for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) {
+            assertThat(mBatteryChartPreferenceController.mBatteryHistoryKeys[index])
+                    // These values is are calculated by hand from createBatteryHistoryMap().
+                    .isEqualTo(index + 1);
+        }
+        // Verifies the created battery levels array.
+        for (int index = 0; index < 13; index++) {
+            assertThat(mBatteryChartPreferenceController.mBatteryHistoryLevels[index])
+                    // These values is are calculated by hand from createBatteryHistoryMap().
+                    .isEqualTo(100 - index * 2);
+        }
+        assertThat(mBatteryChartPreferenceController.mBatteryIndexedMap).hasSize(13);
+    }
+
+    @Test
+    public void testSetBatteryHistoryMap_largeSize_createExpectedKeysAndLevels() {
+        mBatteryChartPreferenceController.setBatteryHistoryMap(
+                createBatteryHistoryMap());
+
+        // Verifies the created battery keys array.
+        for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) {
+            assertThat(mBatteryChartPreferenceController.mBatteryHistoryKeys[index])
+                    // These values is are calculated by hand from createBatteryHistoryMap().
+                    .isEqualTo(index + 1);
+        }
+        // Verifies the created battery levels array.
+        for (int index = 0; index < 13; index++) {
+            assertThat(mBatteryChartPreferenceController.mBatteryHistoryLevels[index])
+                    // These values is are calculated by hand from createBatteryHistoryMap().
+                    .isEqualTo(100 - index * 2);
+        }
+        assertThat(mBatteryChartPreferenceController.mBatteryIndexedMap).hasSize(13);
+    }
+
+    @Test
+    public void testRefreshUi_batteryIndexedMapIsNull_ignoreRefresh() {
+        mBatteryChartPreferenceController.setBatteryHistoryMap(null);
+        assertThat(mBatteryChartPreferenceController.refreshUi(
+                /*trapezoidIndex=*/ 1, /*isForce=*/ false)).isFalse();
+    }
+
+    @Test
+    public void testRefreshUi_batteryChartViewIsNull_ignoreRefresh() {
+        mBatteryChartPreferenceController.mBatteryChartView = null;
+        assertThat(mBatteryChartPreferenceController.refreshUi(
+                /*trapezoidIndex=*/ 1, /*isForce=*/ false)).isFalse();
+    }
+
+    @Test
+    public void testRefreshUi_trapezoidIndexIsNotChanged_ignoreRefresh() {
+        final int trapezoidIndex = 1;
+        mBatteryChartPreferenceController.mTrapezoidIndex = trapezoidIndex;
+        assertThat(mBatteryChartPreferenceController.refreshUi(
+                trapezoidIndex, /*isForce=*/ false)).isFalse();
+    }
+
+    @Test
+    public void testRefreshUi_forceUpdate_refreshUi() {
+        final int trapezoidIndex = 1;
+        mBatteryChartPreferenceController.mTrapezoidIndex = trapezoidIndex;
+        assertThat(mBatteryChartPreferenceController.refreshUi(
+                trapezoidIndex, /*isForce=*/ true)).isTrue();
+    }
+
+    @Test
+    public void testForceRefreshUi_updateTrapezoidIndexIntoSelectAll() {
+        mBatteryChartPreferenceController.mTrapezoidIndex =
+                BatteryChartViewV2.SELECTED_INDEX_INVALID;
+        mBatteryChartPreferenceController.setBatteryHistoryMap(
+                createBatteryHistoryMap());
+
+        assertThat(mBatteryChartPreferenceController.mTrapezoidIndex)
+                .isEqualTo(BatteryChartViewV2.SELECTED_INDEX_ALL);
+    }
+
+    @Test
+    public void testRemoveAndCacheAllPrefs_emptyContent_ignoreRemoveAll() {
+        final int trapezoidIndex = 1;
+        doReturn(0).when(mAppListGroup).getPreferenceCount();
+
+        mBatteryChartPreferenceController.refreshUi(
+                trapezoidIndex, /*isForce=*/ true);
+        verify(mAppListGroup, never()).removeAll();
+    }
+
+    @Test
+    public void testRemoveAndCacheAllPrefs_buildCacheAndRemoveAllPreference() {
+        final int trapezoidIndex = 1;
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        doReturn(mPowerGaugePreference).when(mAppListGroup).getPreference(0);
+        doReturn(PREF_KEY).when(mPowerGaugePreference).getKey();
+        // Ensures the testing data is correct.
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+
+        mBatteryChartPreferenceController.refreshUi(
+                trapezoidIndex, /*isForce=*/ true);
+
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(PREF_KEY))
+                .isEqualTo(mPowerGaugePreference);
+        verify(mAppListGroup).removeAll();
+    }
+
+    @Test
+    public void testAddPreferenceToScreen_emptyContent_ignoreAddPreference() {
+        mBatteryChartPreferenceController.addPreferenceToScreen(
+                new ArrayList<BatteryDiffEntry>());
+        verify(mAppListGroup, never()).addPreference(any());
+    }
+
+    @Test
+    public void testAddPreferenceToScreen_addPreferenceIntoScreen() {
+        final String appLabel = "fake app label";
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+        doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel();
+        doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+        doReturn(null).when(mAppListGroup).findPreference(PREF_KEY);
+        doReturn(false).when(mBatteryDiffEntry).validForRestriction();
+
+        mBatteryChartPreferenceController.addPreferenceToScreen(
+                Arrays.asList(mBatteryDiffEntry));
+
+        // Verifies the preference cache.
+        final PowerGaugePreference pref =
+                (PowerGaugePreference) mBatteryChartPreferenceController.mPreferenceCache
+                        .get(PREF_KEY);
+        assertThat(pref).isNotNull();
+        // Verifies the added preference configuration.
+        verify(mAppListGroup).addPreference(pref);
+        assertThat(pref.getKey()).isEqualTo(PREF_KEY);
+        assertThat(pref.getTitle()).isEqualTo(appLabel);
+        assertThat(pref.getIcon()).isEqualTo(mDrawable);
+        assertThat(pref.getOrder()).isEqualTo(1);
+        assertThat(pref.getBatteryDiffEntry()).isSameInstanceAs(mBatteryDiffEntry);
+        assertThat(pref.isSingleLineTitle()).isTrue();
+        assertThat(pref.isEnabled()).isFalse();
+    }
+
+    @Test
+    public void testAddPreferenceToScreen_alreadyInScreen_notAddPreferenceAgain() {
+        final String appLabel = "fake app label";
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+        doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel();
+        doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+        doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY);
+
+        mBatteryChartPreferenceController.addPreferenceToScreen(
+                Arrays.asList(mBatteryDiffEntry));
+
+        verify(mAppListGroup, never()).addPreference(any());
+    }
+
+    @Test
+    public void testHandlePreferenceTreeiClick_notPowerGaugePreference_returnFalse() {
+        assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(mAppListGroup))
+                .isFalse();
+
+        verify(mMetricsFeatureProvider, never())
+                .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM);
+        verify(mMetricsFeatureProvider, never())
+                .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM);
+    }
+
+    @Test
+    public void testHandlePreferenceTreeClick_forAppEntry_returnTrue() {
+        doReturn(false).when(mBatteryHistEntry).isAppEntry();
+        doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry();
+
+        assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(
+                mPowerGaugePreference)).isTrue();
+        verify(mMetricsFeatureProvider)
+                .action(
+                        SettingsEnums.OPEN_BATTERY_USAGE,
+                        SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM,
+                        SettingsEnums.OPEN_BATTERY_USAGE,
+                        /* package name */ "none",
+                        /* percentage of total */ 0);
+    }
+
+    @Test
+    public void testHandlePreferenceTreeClick_forSystemEntry_returnTrue() {
+        mBatteryChartPreferenceController.mBatteryUtils = mBatteryUtils;
+        doReturn(true).when(mBatteryHistEntry).isAppEntry();
+        doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry();
+
+        assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(
+                mPowerGaugePreference)).isTrue();
+        verify(mMetricsFeatureProvider)
+                .action(
+                        SettingsEnums.OPEN_BATTERY_USAGE,
+                        SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM,
+                        SettingsEnums.OPEN_BATTERY_USAGE,
+                        /* package name */ "none",
+                        /* percentage of total */ 0);
+    }
+
+    @Test
+    public void testSetPreferenceSummary_setNullContentIfTotalUsageTimeIsZero() {
+        final PowerGaugePreference pref = new PowerGaugePreference(mContext);
+        pref.setSummary(PREF_SUMMARY);
+
+        mBatteryChartPreferenceController.setPreferenceSummary(
+                pref, createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ 0,
+                        /*backgroundUsageTimeInMs=*/ 0));
+        assertThat(pref.getSummary()).isNull();
+    }
+
+    @Test
+    public void testSetPreferenceSummary_setBackgroundUsageTimeOnly() {
+        final PowerGaugePreference pref = new PowerGaugePreference(mContext);
+        pref.setSummary(PREF_SUMMARY);
+
+        mBatteryChartPreferenceController.setPreferenceSummary(
+                pref, createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ 0,
+                        /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS));
+        assertThat(pref.getSummary()).isEqualTo("Background: 1 min");
+    }
+
+    @Test
+    public void testSetPreferenceSummary_setTotalUsageTimeLessThanAMinute() {
+        final PowerGaugePreference pref = new PowerGaugePreference(mContext);
+        pref.setSummary(PREF_SUMMARY);
+
+        mBatteryChartPreferenceController.setPreferenceSummary(
+                pref, createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ 100,
+                        /*backgroundUsageTimeInMs=*/ 200));
+        assertThat(pref.getSummary()).isEqualTo("Total: less than a min");
+    }
+
+    @Test
+    public void testSetPreferenceSummary_setTotalTimeIfBackgroundTimeLessThanAMinute() {
+        final PowerGaugePreference pref = new PowerGaugePreference(mContext);
+        pref.setSummary(PREF_SUMMARY);
+
+        mBatteryChartPreferenceController.setPreferenceSummary(
+                pref, createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS,
+                        /*backgroundUsageTimeInMs=*/ 200));
+        assertThat(pref.getSummary())
+                .isEqualTo("Total: 1 min\nBackground: less than a min");
+    }
+
+    @Test
+    public void testSetPreferenceSummary_setTotalAndBackgroundUsageTime() {
+        final PowerGaugePreference pref = new PowerGaugePreference(mContext);
+        pref.setSummary(PREF_SUMMARY);
+
+        mBatteryChartPreferenceController.setPreferenceSummary(
+                pref, createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS,
+                        /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS));
+        assertThat(pref.getSummary()).isEqualTo("Total: 2 min\nBackground: 1 min");
+    }
+
+    @Test
+    public void testSetPreferenceSummary_notAllowShownPackage_setSummayAsNull() {
+        final PowerGaugePreference pref = new PowerGaugePreference(mContext);
+        pref.setSummary(PREF_SUMMARY);
+        final BatteryDiffEntry batteryDiffEntry =
+                spy(createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS,
+                        /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS));
+        doReturn("com.android.googlequicksearchbox").when(batteryDiffEntry)
+                .getPackageName();
+
+        mBatteryChartPreferenceController.setPreferenceSummary(pref, batteryDiffEntry);
+        assertThat(pref.getSummary()).isNull();
+    }
+
+    @Test
+    public void testValidateUsageTime_returnTrueIfBatteryDiffEntryIsValid() {
+        assertThat(BatteryChartPreferenceControllerV2.validateUsageTime(
+                createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS,
+                        /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS)))
+                .isTrue();
+    }
+
+    @Test
+    public void testValidateUsageTime_foregroundTimeExceedThreshold_returnFalse() {
+        assertThat(BatteryChartPreferenceControllerV2.validateUsageTime(
+                createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ DateUtils.HOUR_IN_MILLIS * 3,
+                        /*backgroundUsageTimeInMs=*/ 0)))
+                .isFalse();
+    }
+
+    @Test
+    public void testValidateUsageTime_backgroundTimeExceedThreshold_returnFalse() {
+        assertThat(BatteryChartPreferenceControllerV2.validateUsageTime(
+                createBatteryDiffEntry(
+                        /*foregroundUsageTimeInMs=*/ 0,
+                        /*backgroundUsageTimeInMs=*/ DateUtils.HOUR_IN_MILLIS * 3)))
+                .isFalse();
+    }
+
+    @Test
+    public void testOnExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup() {
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
+        doReturn("label").when(mBatteryDiffEntry).getAppLabel();
+        doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+        doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+
+        mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ true);
+
+        final ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class);
+        verify(mAppListGroup).addPreference(captor.capture());
+        // Verifies the added preference.
+        assertThat(captor.getValue().getKey()).isEqualTo(PREF_KEY);
+        verify(mMetricsFeatureProvider)
+                .action(
+                        mContext,
+                        SettingsEnums.ACTION_BATTERY_USAGE_EXPAND_ITEM,
+                        true /*isExpanded*/);
+    }
+
+    @Test
+    public void testOnExpand_expandedIsFalse_removeSystemEntriesFromPreferenceGroup() {
+        doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+        doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY);
+        mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
+        // Verifies the cache is empty first.
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+
+        mBatteryChartPreferenceController.onExpand(/*isExpanded=*/ false);
+
+        verify(mAppListGroup).findPreference(PREF_KEY);
+        verify(mAppListGroup).removePreference(mPowerGaugePreference);
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
+        verify(mMetricsFeatureProvider)
+                .action(
+                        mContext,
+                        SettingsEnums.ACTION_BATTERY_USAGE_EXPAND_ITEM,
+                        false /*isExpanded*/);
+    }
+
+    @Test
+    public void testOnSelect_selectSpecificTimeSlot_logMetric() {
+        mBatteryChartPreferenceController.onSelect(1 /*slot index*/);
+
+        verify(mMetricsFeatureProvider)
+                .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_TIME_SLOT);
+    }
+
+    @Test
+    public void testOnSelect_selectAll_logMetric() {
+        mBatteryChartPreferenceController.onSelect(
+                BatteryChartViewV2.SELECTED_INDEX_ALL /*slot index*/);
+
+        verify(mMetricsFeatureProvider)
+                .action(mContext, SettingsEnums.ACTION_BATTERY_USAGE_SHOW_ALL);
+    }
+
+    @Test
+    public void testRefreshCategoryTitle_setHourIntoBothTitleTextView() {
+        mBatteryChartPreferenceController = createController();
+        setUpBatteryHistoryKeys();
+        mBatteryChartPreferenceController.mAppListPrefGroup =
+                spy(new PreferenceCategory(mContext));
+        mBatteryChartPreferenceController.mExpandDividerPreference =
+                spy(new ExpandDividerPreference(mContext));
+        // Simulates select the first slot.
+        mBatteryChartPreferenceController.mTrapezoidIndex = 0;
+
+        mBatteryChartPreferenceController.refreshCategoryTitle();
+
+        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+        // Verifies the title in the preference group.
+        verify(mBatteryChartPreferenceController.mAppListPrefGroup)
+                .setTitle(captor.capture());
+        assertThat(captor.getValue()).isNotEqualTo("App usage for past 24 hr");
+        // Verifies the title in the expandable divider.
+        captor = ArgumentCaptor.forClass(String.class);
+        verify(mBatteryChartPreferenceController.mExpandDividerPreference)
+                .setTitle(captor.capture());
+        assertThat(captor.getValue()).isNotEqualTo("System usage for past 24 hr");
+    }
+
+    @Test
+    public void testRefreshCategoryTitle_setLast24HrIntoBothTitleTextView() {
+        mBatteryChartPreferenceController = createController();
+        mBatteryChartPreferenceController.mAppListPrefGroup =
+                spy(new PreferenceCategory(mContext));
+        mBatteryChartPreferenceController.mExpandDividerPreference =
+                spy(new ExpandDividerPreference(mContext));
+        // Simulates select all condition.
+        mBatteryChartPreferenceController.mTrapezoidIndex =
+                BatteryChartViewV2.SELECTED_INDEX_ALL;
+
+        mBatteryChartPreferenceController.refreshCategoryTitle();
+
+        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+        // Verifies the title in the preference group.
+        verify(mBatteryChartPreferenceController.mAppListPrefGroup)
+                .setTitle(captor.capture());
+        assertThat(captor.getValue())
+                .isEqualTo("App usage for past 24 hr");
+        // Verifies the title in the expandable divider.
+        captor = ArgumentCaptor.forClass(String.class);
+        verify(mBatteryChartPreferenceController.mExpandDividerPreference)
+                .setTitle(captor.capture());
+        assertThat(captor.getValue())
+                .isEqualTo("System usage for past 24 hr");
+    }
+
+    @Test
+    public void testSetTimestampLabel_nullBatteryHistoryKeys_ignore() {
+        mBatteryChartPreferenceController = createController();
+        mBatteryChartPreferenceController.mBatteryHistoryKeys = null;
+        mBatteryChartPreferenceController.mBatteryChartView =
+                spy(new BatteryChartViewV2(mContext));
+        mBatteryChartPreferenceController.setTimestampLabel();
+
+        verify(mBatteryChartPreferenceController.mBatteryChartView, never())
+                .setLatestTimestamp(anyLong());
+    }
+
+    @Test
+    public void testSetTimestampLabel_setExpectedTimestampData() {
+        mBatteryChartPreferenceController = createController();
+        mBatteryChartPreferenceController.mBatteryChartView =
+                spy(new BatteryChartViewV2(mContext));
+        setUpBatteryHistoryKeys();
+
+        mBatteryChartPreferenceController.setTimestampLabel();
+
+        verify(mBatteryChartPreferenceController.mBatteryChartView)
+                .setLatestTimestamp(1619247636826L);
+    }
+
+    @Test
+    public void testSetTimestampLabel_withoutValidTimestamp_setExpectedTimestampData() {
+        mBatteryChartPreferenceController = createController();
+        mBatteryChartPreferenceController.mBatteryChartView =
+                spy(new BatteryChartViewV2(mContext));
+        mBatteryChartPreferenceController.mBatteryHistoryKeys = new long[]{0L};
+
+        mBatteryChartPreferenceController.setTimestampLabel();
+
+        verify(mBatteryChartPreferenceController.mBatteryChartView)
+                .setLatestTimestamp(anyLong());
+    }
+
+    @Test
+    public void testOnSaveInstanceState_restoreSelectedIndexAndExpandState() {
+        final int expectedIndex = 1;
+        final boolean isExpanded = true;
+        final Bundle bundle = new Bundle();
+        mBatteryChartPreferenceController.mTrapezoidIndex = expectedIndex;
+        mBatteryChartPreferenceController.mIsExpanded = isExpanded;
+        mBatteryChartPreferenceController.onSaveInstanceState(bundle);
+        // Replaces the original controller with other values.
+        mBatteryChartPreferenceController.mTrapezoidIndex = -1;
+        mBatteryChartPreferenceController.mIsExpanded = false;
+
+        mBatteryChartPreferenceController.onCreate(bundle);
+        mBatteryChartPreferenceController.setBatteryHistoryMap(
+                createBatteryHistoryMap());
+
+        assertThat(mBatteryChartPreferenceController.mTrapezoidIndex)
+                .isEqualTo(expectedIndex);
+        assertThat(mBatteryChartPreferenceController.mIsExpanded).isTrue();
+    }
+
+    @Test
+    public void testIsValidToShowSummary_returnExpectedResult() {
+        assertThat(mBatteryChartPreferenceController
+                .isValidToShowSummary("com.google.android.apps.scone"))
+                .isTrue();
+
+        // Verifies the item which is defined in the array list.
+        assertThat(mBatteryChartPreferenceController
+                .isValidToShowSummary("com.android.googlequicksearchbox"))
+                .isFalse();
+    }
+
+    @Test
+    public void testIsValidToShowEntry_returnExpectedResult() {
+        assertThat(mBatteryChartPreferenceController
+                .isValidToShowEntry("com.google.android.apps.scone"))
+                .isTrue();
+
+        // Verifies the items which are defined in the array list.
+        assertThat(mBatteryChartPreferenceController
+                .isValidToShowEntry("com.android.gms.persistent"))
+                .isFalse();
+    }
+
+    private static Map<Long, Map<String, BatteryHistEntry>> createBatteryHistoryMap() {
+        final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
+        for (int index = 0; index < DESIRED_HISTORY_SIZE; index++) {
+            final ContentValues values = new ContentValues();
+            values.put("batteryLevel", Integer.valueOf(100 - index));
+            final BatteryHistEntry entry = new BatteryHistEntry(values);
+            final Map<String, BatteryHistEntry> entryMap = new HashMap<>();
+            entryMap.put("fake_entry_key" + index, entry);
+            batteryHistoryMap.put(Long.valueOf(index + 1), entryMap);
+        }
+        return batteryHistoryMap;
+    }
+
+    private BatteryDiffEntry createBatteryDiffEntry(
+            long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
+        return new BatteryDiffEntry(
+                mContext, foregroundUsageTimeInMs, backgroundUsageTimeInMs,
+                /*consumePower=*/ 0, mBatteryHistEntry);
+    }
+
+    private void setUpBatteryHistoryKeys() {
+        mBatteryChartPreferenceController.mBatteryHistoryKeys =
+                new long[]{1619196786769L, 0L, 1619247636826L};
+        ConvertUtils.utcToLocalTimeHour(
+                mContext, /*timestamp=*/ 0, /*is24HourFormat=*/ false);
+    }
+
+    private BatteryChartPreferenceControllerV2 createController() {
+        final BatteryChartPreferenceControllerV2 controller =
+                new BatteryChartPreferenceControllerV2(
+                        mContext, "app_list", /*lifecycle=*/ null,
+                        mSettingsActivity, mFragment);
+        controller.mPrefContext = mContext;
+        return controller;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewV2Test.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewV2Test.java
new file mode 100644
index 0000000..111019f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewV2Test.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2022 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.ArgumentMatchers.anyInt;
+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.accessibilityservice.AccessibilityServiceInfo;
+import android.content.Context;
+import android.os.LocaleList;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+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.ArrayList;
+import java.util.Arrays;
+import java.util.Locale;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryChartViewV2Test {
+
+    private Context mContext;
+    private BatteryChartViewV2 mBatteryChartView;
+    private FakeFeatureFactory mFeatureFactory;
+    private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
+
+    @Mock
+    private AccessibilityServiceInfo mMockAccessibilityServiceInfo;
+    @Mock
+    private AccessibilityManager mMockAccessibilityManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider;
+        mContext = spy(RuntimeEnvironment.application);
+        mContext.getResources().getConfiguration().setLocales(
+                new LocaleList(new Locale("en_US")));
+        mBatteryChartView = new BatteryChartViewV2(mContext);
+        doReturn(mMockAccessibilityManager).when(mContext)
+                .getSystemService(AccessibilityManager.class);
+        doReturn("TalkBackService").when(mMockAccessibilityServiceInfo).getId();
+        doReturn(Arrays.asList(mMockAccessibilityServiceInfo))
+                .when(mMockAccessibilityManager)
+                .getEnabledAccessibilityServiceList(anyInt());
+    }
+
+    @Test
+    public void testIsAccessibilityEnabled_disable_returnFalse() {
+        doReturn(false).when(mMockAccessibilityManager).isEnabled();
+        assertThat(BatteryChartViewV2.isAccessibilityEnabled(mContext)).isFalse();
+    }
+
+    @Test
+    public void testIsAccessibilityEnabled_emptyInfo_returnFalse() {
+        doReturn(true).when(mMockAccessibilityManager).isEnabled();
+        doReturn(new ArrayList<AccessibilityServiceInfo>())
+                .when(mMockAccessibilityManager)
+                .getEnabledAccessibilityServiceList(anyInt());
+
+        assertThat(BatteryChartViewV2.isAccessibilityEnabled(mContext)).isFalse();
+    }
+
+    @Test
+    public void testIsAccessibilityEnabled_validServiceId_returnTrue() {
+        doReturn(true).when(mMockAccessibilityManager).isEnabled();
+        assertThat(BatteryChartViewV2.isAccessibilityEnabled(mContext)).isTrue();
+    }
+
+    @Test
+    public void testSetSelectedIndex_invokesCallback() {
+        final int[] selectedIndex = new int[1];
+        final int expectedIndex = 2;
+        mBatteryChartView.mSelectedIndex = 1;
+        mBatteryChartView.setOnSelectListener(
+                trapezoidIndex -> {
+                    selectedIndex[0] = trapezoidIndex;
+                });
+
+        mBatteryChartView.setSelectedIndex(expectedIndex);
+
+        assertThat(mBatteryChartView.mSelectedIndex)
+                .isEqualTo(expectedIndex);
+        assertThat(selectedIndex[0]).isEqualTo(expectedIndex);
+    }
+
+    @Test
+    public void testSetSelectedIndex_sameIndex_notInvokesCallback() {
+        final int[] selectedIndex = new int[1];
+        final int expectedIndex = 1;
+        mBatteryChartView.mSelectedIndex = expectedIndex;
+        mBatteryChartView.setOnSelectListener(
+                trapezoidIndex -> {
+                    selectedIndex[0] = trapezoidIndex;
+                });
+
+        mBatteryChartView.setSelectedIndex(expectedIndex);
+
+        assertThat(selectedIndex[0]).isNotEqualTo(expectedIndex);
+    }
+
+    @Test
+    public void testClickable_isChartGraphSlotsEnabledIsFalse_notClickable() {
+        mBatteryChartView.setClickableForce(true);
+        when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
+                .thenReturn(false);
+
+        mBatteryChartView.onAttachedToWindow();
+        assertThat(mBatteryChartView.isClickable()).isFalse();
+        assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
+    }
+
+    @Test
+    public void testClickable_accessibilityIsDisabled_clickable() {
+        mBatteryChartView.setClickableForce(true);
+        when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
+                .thenReturn(true);
+        doReturn(false).when(mMockAccessibilityManager).isEnabled();
+
+        mBatteryChartView.onAttachedToWindow();
+        assertThat(mBatteryChartView.isClickable()).isTrue();
+        assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
+    }
+
+    @Test
+    public void testClickable_accessibilityIsEnabledWithoutValidId_clickable() {
+        mBatteryChartView.setClickableForce(true);
+        when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
+                .thenReturn(true);
+        doReturn(true).when(mMockAccessibilityManager).isEnabled();
+        doReturn(new ArrayList<AccessibilityServiceInfo>())
+                .when(mMockAccessibilityManager)
+                .getEnabledAccessibilityServiceList(anyInt());
+
+        mBatteryChartView.onAttachedToWindow();
+        assertThat(mBatteryChartView.isClickable()).isTrue();
+        assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
+    }
+
+    @Test
+    public void testClickable_accessibilityIsEnabledWithValidId_notClickable() {
+        mBatteryChartView.setClickableForce(true);
+        when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
+                .thenReturn(true);
+        doReturn(true).when(mMockAccessibilityManager).isEnabled();
+
+        mBatteryChartView.onAttachedToWindow();
+        assertThat(mBatteryChartView.isClickable()).isFalse();
+        assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
+    }
+
+    @Test
+    public void testClickable_restoreFromNonClickableState() {
+        final int[] levels = new int[13];
+        for (int index = 0; index < levels.length; index++) {
+            levels[index] = index + 1;
+        }
+        mBatteryChartView.setTrapezoidCount(12);
+        mBatteryChartView.setLevels(levels);
+        mBatteryChartView.setClickableForce(true);
+        when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
+                .thenReturn(true);
+        doReturn(true).when(mMockAccessibilityManager).isEnabled();
+        mBatteryChartView.onAttachedToWindow();
+        // Ensures the testing environment is correct.
+        assertThat(mBatteryChartView.isClickable()).isFalse();
+        // Turns off accessibility service.
+        doReturn(false).when(mMockAccessibilityManager).isEnabled();
+
+        mBatteryChartView.onAttachedToWindow();
+
+        assertThat(mBatteryChartView.isClickable()).isTrue();
+    }
+
+    @Test
+    public void testOnAttachedToWindow_addAccessibilityStateChangeListener() {
+        mBatteryChartView.onAttachedToWindow();
+        verify(mMockAccessibilityManager)
+                .addAccessibilityStateChangeListener(mBatteryChartView);
+    }
+
+    @Test
+    public void testOnDetachedFromWindow_removeAccessibilityStateChangeListener() {
+        mBatteryChartView.onAttachedToWindow();
+        mBatteryChartView.mHandler.postDelayed(
+                mBatteryChartView.mUpdateClickableStateRun, 1000);
+
+        mBatteryChartView.onDetachedFromWindow();
+
+        verify(mMockAccessibilityManager)
+                .removeAccessibilityStateChangeListener(mBatteryChartView);
+        assertThat(mBatteryChartView.mHandler.hasCallbacks(
+                mBatteryChartView.mUpdateClickableStateRun))
+                .isFalse();
+    }
+
+    @Test
+    public void testOnAccessibilityStateChanged_postUpdateStateRunnable() {
+        mBatteryChartView.mHandler = spy(mBatteryChartView.mHandler);
+        mBatteryChartView.onAccessibilityStateChanged(/*enabled=*/ true);
+
+        verify(mBatteryChartView.mHandler)
+                .removeCallbacks(mBatteryChartView.mUpdateClickableStateRun);
+        verify(mBatteryChartView.mHandler)
+                .postDelayed(mBatteryChartView.mUpdateClickableStateRun, 500L);
+    }
+}
