diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 935c1a4..a3a6fcf 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2973,6 +2973,14 @@
             android:authorities="${applicationId}.battery.usage.provider"
             android:permission="com.android.settings.BATTERY_DATA"/>
 
+        <receiver android:name=".fuelgauge.batteryusage.BatteryUsageBroadcastReceiver"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.settings.battery.action.FETCH_BATTERY_USAGE_DATA"/>
+                <action android:name="com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA"/>
+            </intent-filter>
+        </receiver>
+
         <activity
             android:name="Settings$BatterySaverSettingsActivity"
             android:label="@string/battery_saver"
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
new file mode 100644
index 0000000..5d8757d
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
@@ -0,0 +1,62 @@
+/*
+ * 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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+/** A {@link BatteryUsageBroadcastReceiver} for battery usage data requesting. */
+public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver {
+    private static final String TAG = "BatteryUsageBroadcastReceiver";
+    /** An intent action to request Settings to fetch usage data. */
+    public static final String ACTION_FETCH_BATTERY_USAGE_DATA =
+            "com.android.settings.battery.action.FETCH_BATTERY_USAGE_DATA";
+    /** An intent action to request Settings to clear cache data. */
+    public static final String ACTION_CLEAR_BATTERY_CACHE_DATA =
+            "com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA";
+
+    @VisibleForTesting
+    static boolean sIsDebugMode = Build.TYPE.equals("userdebug");
+
+    @VisibleForTesting
+    boolean mFetchBatteryUsageData = false;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent == null || intent.getAction() == null) {
+            return;
+        }
+        Log.d(TAG, "onReceive:" + intent.getAction());
+        switch (intent.getAction()) {
+            case ACTION_FETCH_BATTERY_USAGE_DATA:
+                mFetchBatteryUsageData = true;
+                BatteryUsageDataLoader.enqueueWork(context);
+                break;
+            case ACTION_CLEAR_BATTERY_CACHE_DATA:
+                if (sIsDebugMode) {
+                    BatteryDiffEntry.clearCache();
+                    BatteryEntry.clearUidCache();
+                }
+                break;
+        }
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java
new file mode 100644
index 0000000..dc9c8b7
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java
@@ -0,0 +1,78 @@
+/*
+ * 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.content.Context;
+import android.os.AsyncTask;
+import android.os.BatteryUsageStats;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.util.List;
+
+/** Load battery usage data in the background. */
+public final class BatteryUsageDataLoader {
+    private static final String TAG = "BatteryUsageDataLoader";
+
+    @VisibleForTesting
+    static BatteryAppListPreferenceController sController;
+
+    private BatteryUsageDataLoader() {
+    }
+
+    static void enqueueWork(Context context) {
+        AsyncTask.execute(() -> {
+            Log.d(TAG, "loadUsageDataSafely() in the AsyncTask");
+            loadUsageDataSafely(context.getApplicationContext());
+        });
+    }
+
+    @VisibleForTesting
+    static void loadUsageData(Context context) {
+        // Checks whether the battery content provider is available.
+        if (!DatabaseUtils.isContentProviderEnabled(context)) {
+            Log.w(TAG, "battery usage content provider is disabled!");
+            return;
+        }
+        final long start = System.currentTimeMillis();
+        final BatteryUsageStats batteryUsageStats = DataProcessor.getBatteryUsageStats(context);
+        final List<BatteryEntry> batteryEntryList =
+                DataProcessor.generateBatteryEntryListFromBatteryUsageStats(
+                        context,
+                        batteryUsageStats,
+                        sController);
+        if (batteryEntryList == null || batteryEntryList.isEmpty()) {
+            Log.w(TAG, "getBatteryEntryList() returns null or empty content");
+        }
+        final long elapsedTime = System.currentTimeMillis() - start;
+        Log.d(TAG, String.format("getBatteryUsageStats() in %d/ms", elapsedTime));
+
+        // Uploads the BatteryEntry data into SettingsIntelligence.
+        DatabaseUtils.sendBatteryEntryData(
+                context, batteryEntryList, batteryUsageStats);
+        DataProcessor.closeBatteryUsageStats(batteryUsageStats);
+    }
+
+    private static void loadUsageDataSafely(Context context) {
+        try {
+            loadUsageData(context);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "loadUsageData:" + e);
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java
new file mode 100644
index 0000000..c7e8322
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiverTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryUsageBroadcastReceiverTest {
+
+    private Context mContext;
+    private BatteryUsageBroadcastReceiver mBatteryUsageBroadcastReceiver;
+    @Mock
+    private PackageManager mPackageManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mBatteryUsageBroadcastReceiver = new BatteryUsageBroadcastReceiver();
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+    }
+
+    @Test
+    public void onReceive_fetchUsageDataIntent_startService() {
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        mBatteryUsageBroadcastReceiver.onReceive(mContext,
+                new Intent(BatteryUsageBroadcastReceiver.ACTION_FETCH_BATTERY_USAGE_DATA));
+
+        assertThat(mBatteryUsageBroadcastReceiver.mFetchBatteryUsageData).isTrue();
+    }
+
+    @Test
+    public void onReceive_invalidIntent_notStartService() {
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        mBatteryUsageBroadcastReceiver.onReceive(mContext, new Intent("invalid intent"));
+
+        assertThat(mBatteryUsageBroadcastReceiver.mFetchBatteryUsageData).isFalse();
+    }
+
+    @Test
+    public void onReceive_clearCacheIntentInDebugMode_clearBatteryCacheData() {
+        BatteryUsageBroadcastReceiver.sIsDebugMode = true;
+        // Insert testing data first.
+        BatteryDiffEntry.sValidForRestriction.put(
+                /*packageName*/ "com.android.testing_package", Boolean.valueOf(true));
+        assertThat(BatteryDiffEntry.sValidForRestriction).isNotEmpty();
+
+        mBatteryUsageBroadcastReceiver.onReceive(mContext,
+                new Intent(BatteryUsageBroadcastReceiver.ACTION_CLEAR_BATTERY_CACHE_DATA));
+
+        assertThat(BatteryDiffEntry.sValidForRestriction).isEmpty();
+    }
+
+    @Test
+    public void onReceive_clearCacheIntentInNotDebugMode_notClearBatteryCacheData() {
+        BatteryUsageBroadcastReceiver.sIsDebugMode = false;
+        // Insert testing data first.
+        BatteryDiffEntry.sValidForRestriction.put(
+                /*packageName*/ "com.android.testing_package", Boolean.valueOf(true));
+        assertThat(BatteryDiffEntry.sValidForRestriction).isNotEmpty();
+
+        mBatteryUsageBroadcastReceiver.onReceive(mContext,
+                new Intent(BatteryUsageBroadcastReceiver.ACTION_CLEAR_BATTERY_CACHE_DATA));
+
+        assertThat(BatteryDiffEntry.sValidForRestriction).isNotEmpty();
+    }
+
+    private void setProviderSetting(int value) {
+        when(mPackageManager.getComponentEnabledSetting(
+                new ComponentName(
+                        DatabaseUtils.SETTINGS_PACKAGE_PATH,
+                        DatabaseUtils.BATTERY_PROVIDER_CLASS_PATH)))
+                .thenReturn(value);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java
new file mode 100644
index 0000000..4124e34
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryUsageDataLoaderTest {
+
+    private Context mContext;
+    @Mock
+    private ContentResolver mMockContentResolver;
+    @Mock
+    private BatteryStatsManager mBatteryStatsManager;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
+    @Mock
+    private BatteryAppListPreferenceController mMockBatteryAppListController;
+    @Mock
+    private BatteryEntry mMockBatteryEntry;
+    @Captor
+    private ArgumentCaptor<BatteryUsageStatsQuery> mStatsQueryCaptor;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        BatteryUsageDataLoader.sController = mMockBatteryAppListController;
+        doReturn(mContext).when(mContext).getApplicationContext();
+        doReturn(mBatteryStatsManager).when(mContext).getSystemService(
+                Context.BATTERY_STATS_SERVICE);
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        doReturn(mMockContentResolver).when(mContext).getContentResolver();
+        doReturn(new Intent()).when(mContext).registerReceiver(any(), any());
+    }
+
+    @Test
+    public void loadUsageData_loadUsageDataWithHistory() {
+        final List<BatteryEntry> batteryEntryList = new ArrayList<>();
+        batteryEntryList.add(mMockBatteryEntry);
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mBatteryStatsManager.getBatteryUsageStats(mStatsQueryCaptor.capture()))
+                .thenReturn(mBatteryUsageStats);
+        when(mMockBatteryAppListController.getBatteryEntryList(mBatteryUsageStats, true))
+                .thenReturn(batteryEntryList);
+
+        BatteryUsageDataLoader.loadUsageData(mContext);
+
+        final int queryFlags = mStatsQueryCaptor.getValue().getFlags();
+        assertThat(queryFlags
+                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY)
+                .isNotEqualTo(0);
+        verify(mMockBatteryAppListController)
+                .getBatteryEntryList(mBatteryUsageStats, /*showAllApps=*/ true);
+        verify(mMockContentResolver).insert(any(), any());
+    }
+
+    @Test
+    public void loadUsageData_nullBatteryUsageStats_notLoadBatteryEntryData() {
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mBatteryStatsManager.getBatteryUsageStats(mStatsQueryCaptor.capture()))
+                .thenReturn(null);
+
+        BatteryUsageDataLoader.loadUsageData(mContext);
+
+        final int queryFlags = mStatsQueryCaptor.getValue().getFlags();
+        assertThat(queryFlags
+                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY)
+                .isNotEqualTo(0);
+        verify(mMockBatteryAppListController, never())
+                .getBatteryEntryList(mBatteryUsageStats, /*showAllApps=*/ true);
+        verify(mMockContentResolver).insert(any(), any());
+    }
+
+    @Test
+    public void loadUsageData_nullBatteryEntryList_insertFakeDataIntoProvider() {
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mBatteryStatsManager.getBatteryUsageStats(mStatsQueryCaptor.capture()))
+                .thenReturn(mBatteryUsageStats);
+        when(mMockBatteryAppListController.getBatteryEntryList(mBatteryUsageStats, true))
+                .thenReturn(null);
+
+        BatteryUsageDataLoader.loadUsageData(mContext);
+
+        verify(mMockContentResolver).insert(any(), any());
+    }
+
+    @Test
+    public void loadUsageData_emptyBatteryEntryList_insertFakeDataIntoProvider() {
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mBatteryStatsManager.getBatteryUsageStats(mStatsQueryCaptor.capture()))
+                .thenReturn(mBatteryUsageStats);
+        when(mMockBatteryAppListController.getBatteryEntryList(mBatteryUsageStats, true))
+                .thenReturn(new ArrayList<BatteryEntry>());
+
+        BatteryUsageDataLoader.loadUsageData(mContext);
+
+        verify(mMockContentResolver).insert(any(), any());
+    }
+
+    @Test
+    public void loadUsageData_providerIsDisabled_notLoadHistory() {
+        setProviderSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
+        when(mBatteryStatsManager.getBatteryUsageStats(mStatsQueryCaptor.capture()))
+                .thenReturn(mBatteryUsageStats);
+
+        BatteryUsageDataLoader.loadUsageData(mContext);
+
+        verify(mBatteryStatsManager, never()).getBatteryUsageStats(
+                mStatsQueryCaptor.capture());
+    }
+
+    private void setProviderSetting(int value) {
+        when(mPackageManager.getComponentEnabledSetting(
+                new ComponentName(
+                        DatabaseUtils.SETTINGS_PACKAGE_PATH,
+                        DatabaseUtils.BATTERY_PROVIDER_CLASS_PATH)))
+                .thenReturn(value);
+    }
+}
