diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index eb69f6e..27ecf53 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3031,6 +3031,11 @@
             android:authorities="${applicationId}.battery.usage.provider"
             android:permission="com.android.settings.BATTERY_DATA"/>
 
+        <provider
+            android:name=".fuelgauge.batteryusage.bugreport.BugReportContentProvider"
+            android:exported="false"
+            android:authorities="${applicationId}.battery.usage.bugreport"/>
+
         <receiver android:name=".fuelgauge.batteryusage.BatteryUsageBroadcastReceiver"
                   android:exported="true">
             <intent-filter>
diff --git a/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java b/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java
new file mode 100644
index 0000000..f2cdbbd
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java
@@ -0,0 +1,88 @@
+/*
+ * 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.bugreport;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+import com.android.settings.fuelgauge.batteryusage.DatabaseUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/** Provides debug information in the bugreports when device is dumpping. */
+public final class BugReportContentProvider extends ContentProvider {
+    private static final String TAG = "BugReportContentProvider";
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        final Context context = getContext();
+        if (context == null) {
+            Log.w(TAG, "failed to dump BatteryUsage state: null context");
+            return;
+        }
+        if (DatabaseUtils.isWorkProfile(context)) {
+            Log.w(TAG, "ignore battery usage states dump in the work profile");
+            return;
+        }
+        writer.println("dump BatteryUsage states:");
+        LogUtils.dumpUsageDatabaseHist(context, writer);
+    }
+
+    @Override
+    public Cursor query(
+            Uri uri,
+            String[] projection,
+            String selection,
+            String[] selectionArgs,
+            String sortOrder) {
+        throw new UnsupportedOperationException("unsupported!");
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new UnsupportedOperationException("unsupported!");
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException("unsupported!");
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("unsupported!");
+    }
+
+    @Override
+    public int update(
+            Uri uri,
+            ContentValues values,
+            String selection,
+            String[] selectionArgs) {
+        throw new UnsupportedOperationException("unsupported!");
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java b/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java
new file mode 100644
index 0000000..327957d
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java
@@ -0,0 +1,72 @@
+/*
+ * 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.bugreport;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
+
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.time.Clock;
+import java.time.Duration;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+/** A utility class to aggregate and provide required log data. */
+public final class LogUtils {
+    private static final String TAG = "LogUtils";
+    private static final Duration DUMP_TIME_OFFSET = Duration.ofHours(24);
+    private static final Duration DUMP_TIME_OFFSET_FOR_ENTRY = Duration.ofHours(4);
+
+    @SuppressWarnings("JavaUtilDate")
+    static void dumpUsageDatabaseHist(Context context, PrintWriter writer) {
+        final BatteryStateDao dao =
+                BatteryStateDatabase
+                        .getInstance(context.getApplicationContext())
+                        .batteryStateDao();
+        final long timeOffset =
+                Clock.systemUTC().millis() - DUMP_TIME_OFFSET.toMillis();
+        // Gets all distinct timestamps.
+        final List<Long> timestamps = dao.getDistinctTimestamps(timeOffset);
+        final int distinctCount = timestamps.size();
+        writer.println("\n\tDatabaseHistory:");
+        writer.println("distinct timestamp count:" + distinctCount);
+        Log.w(TAG, "distinct timestamp count:" + distinctCount);
+        if (distinctCount == 0) {
+            return;
+        }
+        // Dumps all distinct timestamps.
+        final SimpleDateFormat formatter =
+                new SimpleDateFormat("MMM dd, HH:mm:ss", Locale.US);
+        timestamps.forEach(timestamp -> {
+            final String formattedTimestamp = formatter.format(new Date(timestamp));
+            writer.println("\t" + formattedTimestamp);
+            Log.w(TAG, "\t" + formattedTimestamp);
+        });
+
+        final List<BatteryState> stateList = dao.getAllAfter(
+                Clock.systemUTC().millis() - DUMP_TIME_OFFSET_FOR_ENTRY.toMillis());
+        stateList.stream().forEach(state -> writer.println(state));
+    }
+
+    private LogUtils() {}
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProviderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProviderTest.java
new file mode 100644
index 0000000..87e253f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProviderTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.bugreport;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.testutils.BatteryTestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/** Tests of {@link BugReportContentProvider}. */
+@RunWith(RobolectricTestRunner.class)
+public final class BugReportContentProviderTest {
+    private static final String PACKAGE_NAME1 = "com.android.settings";
+    private static final String PACKAGE_NAME2 = "com.android.systemui";
+
+    private Context mContext;
+    private PrintWriter mPrintWriter;
+    private StringWriter mStringWriter;
+    private BugReportContentProvider mBugReportContentProvider;
+
+    @Before
+    public void setUp() {
+        mStringWriter = new StringWriter();
+        mPrintWriter = new PrintWriter(mStringWriter);
+        mContext = ApplicationProvider.getApplicationContext();
+        mBugReportContentProvider = new BugReportContentProvider();
+        mBugReportContentProvider.attachInfo(mContext, /*info=*/ null);
+        // Inserts fake data into database for testing.
+        BatteryTestUtils.setUpBatteryStateDatabase(mContext);
+        BatteryTestUtils.insertDataToBatteryStateDatabase(
+                mContext, System.currentTimeMillis(), PACKAGE_NAME1);
+        BatteryTestUtils.insertDataToBatteryStateDatabase(
+                mContext, System.currentTimeMillis(), PACKAGE_NAME2);
+    }
+
+    @Test
+    public void dump_nullContext_notDumpsBatteryUsageData() {
+        mBugReportContentProvider = new BugReportContentProvider();
+        mBugReportContentProvider.attachInfo(/*context=*/ null, /*info=*/ null);
+
+        mBugReportContentProvider.dump(FileDescriptor.out, mPrintWriter, new String[] {});
+
+        assertThat(mStringWriter.toString()).isEmpty();
+    }
+
+    @Test
+    public void dump_inWorkProfileMode_notDumpsBatteryUsageData() {
+        BatteryTestUtils.setWorkProfile(mContext);
+        mBugReportContentProvider.dump(FileDescriptor.out, mPrintWriter, new String[] {});
+        assertThat(mStringWriter.toString()).isEmpty();
+    }
+
+    @Test
+    public void dump_dumpsBatteryUsageHistory() {
+        mBugReportContentProvider.dump(FileDescriptor.out, mPrintWriter, new String[] {});
+
+        String dumpContent = mStringWriter.toString();
+        assertThat(dumpContent).contains("DatabaseHistory");
+        assertThat(dumpContent).contains(PACKAGE_NAME1);
+        assertThat(dumpContent).contains(PACKAGE_NAME2);
+        assertThat(dumpContent).contains("distinct timestamp count:2");
+    }
+}
