diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java index 4eaa1545259..817d367ca11 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java @@ -80,6 +80,6 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { } mFetchBatteryUsageData = true; - BatteryUsageDataLoader.enqueueWork(context); + BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ true); } } diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java index 5680414bd8d..4827f8fe151 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java @@ -40,9 +40,8 @@ import java.time.Duration; public class BatteryUsageContentProvider extends ContentProvider { private static final String TAG = "BatteryUsageContentProvider"; - // TODO: Updates the duration to a more reasonable value for since-last-full-charge. @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - public static final Duration QUERY_DURATION_HOURS = Duration.ofHours(28); + public static final Duration QUERY_DURATION_HOURS = Duration.ofDays(6); @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) public static final String QUERY_KEY_TIMESTAMP = "timestamp"; @@ -141,7 +140,7 @@ public class BatteryUsageContentProvider extends ContentProvider { final long timestamp = mClock.millis(); Cursor cursor = null; try { - cursor = mBatteryStateDao.getCursorAfter(firstTimestamp); + cursor = mBatteryStateDao.getCursorSinceLastFullCharge(firstTimestamp); } catch (RuntimeException e) { Log.e(TAG, "query() from:" + uri + " error:" + e); } diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java index c944eca7efc..3cb5465fb41 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java @@ -37,15 +37,15 @@ public final class BatteryUsageDataLoader { private BatteryUsageDataLoader() { } - static void enqueueWork(Context context) { + static void enqueueWork(final Context context, final boolean isFullChargeStart) { AsyncTask.execute(() -> { Log.d(TAG, "loadUsageDataSafely() in the AsyncTask"); - loadUsageDataSafely(context.getApplicationContext()); + loadUsageDataSafely(context.getApplicationContext(), isFullChargeStart); }); } @VisibleForTesting - static void loadUsageData(Context context) { + static void loadUsageData(final Context context, final boolean isFullChargeStart) { final long start = System.currentTimeMillis(); final BatteryUsageStats batteryUsageStats = DataProcessor.getBatteryUsageStats(context); final List batteryEntryList = @@ -60,13 +60,14 @@ public final class BatteryUsageDataLoader { // Uploads the BatteryEntry data into SettingsIntelligence. DatabaseUtils.sendBatteryEntryData( - context, batteryEntryList, batteryUsageStats); + context, batteryEntryList, batteryUsageStats, isFullChargeStart); DataProcessor.closeBatteryUsageStats(batteryUsageStats); } - private static void loadUsageDataSafely(Context context) { + private static void loadUsageDataSafely( + final Context context, final boolean isFullChargeStart) { try { - loadUsageData(context); + loadUsageData(context, isFullChargeStart); } catch (RuntimeException e) { Log.e(TAG, "loadUsageData:" + e); } diff --git a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java index 7f3dc31f844..ec6e812b521 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java @@ -92,7 +92,8 @@ public final class ConvertUtils { final int batteryStatus, final int batteryHealth, final long bootTimestamp, - final long timestamp) { + final long timestamp, + final boolean isFullChargeStart) { final ContentValues values = new ContentValues(); if (entry != null && batteryUsageStats != null) { values.put(BatteryHistEntry.KEY_UID, Long.valueOf(entry.getUid())); @@ -106,6 +107,8 @@ public final class ConvertUtils { values.put(BatteryHistEntry.KEY_PACKAGE_NAME, FAKE_PACKAGE_NAME); } values.put(BatteryHistEntry.KEY_TIMESTAMP, Long.valueOf(timestamp)); + values.put(BatteryHistEntry.KEY_IS_FULL_CHARGE_CYCLE_START, + Boolean.valueOf(isFullChargeStart)); final BatteryInformation batteryInformation = constructBatteryInformation( entry, @@ -163,7 +166,8 @@ public final class ConvertUtils { /*batteryStatus=*/ 0, /*batteryHealth=*/ 0, /*bootTimestamp=*/ 0, - /*timestamp=*/ 0)); + /*timestamp=*/ 0, + /*isFullChargeStart=*/ false)); } /** Converts UTC timestamp to human readable local time string. */ diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java index 7efd15229bd..4b468011766 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java @@ -19,7 +19,6 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; @@ -37,7 +36,6 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase; -import com.android.settingslib.fuelgauge.BatteryStatus; import java.time.Clock; import java.time.Duration; @@ -50,8 +48,6 @@ import java.util.Map; /** A utility class to operate battery usage database. */ public final class DatabaseUtils { private static final String TAG = "DatabaseUtils"; - private static final String PREF_FILE_NAME = "battery_module_preference"; - private static final String PREF_FULL_CHARGE_TIMESTAMP_KEY = "last_full_charge_timestamp_key"; /** Key for query parameter timestamp used in BATTERY_CONTENT_URI **/ private static final String QUERY_KEY_TIMESTAMP = "timestamp"; /** Clear memory threshold for device booting phase. **/ @@ -89,8 +85,8 @@ public final class DatabaseUtils { public static Map> getHistoryMapSinceLastFullCharge( Context context, Calendar calendar) { final long startTime = System.currentTimeMillis(); - final long lastFullChargeTimestamp = - getStartTimestampForLastFullCharge(context, calendar); + final long sixDaysAgoTimestamp = getTimestampSixDaysAgo(calendar); + Log.d(TAG, "sixDayAgoTimestamp: " + sixDaysAgoTimestamp); // Builds the content uri everytime to avoid cache. final Uri batteryStateUri = new Uri.Builder() @@ -98,7 +94,7 @@ public final class DatabaseUtils { .authority(AUTHORITY) .appendPath(BATTERY_STATE_TABLE) .appendQueryParameter( - QUERY_KEY_TIMESTAMP, Long.toString(lastFullChargeTimestamp)) + QUERY_KEY_TIMESTAMP, Long.toString(sixDaysAgoTimestamp)) .build(); final Map> resultMap = @@ -142,9 +138,10 @@ public final class DatabaseUtils { } static List sendBatteryEntryData( - Context context, - List batteryEntryList, - BatteryUsageStats batteryUsageStats) { + final Context context, + final List batteryEntryList, + final BatteryUsageStats batteryUsageStats, + final boolean isFullChargeStart) { final long startTime = System.currentTimeMillis(); final Intent intent = BatteryUtils.getBatteryIntent(context); if (intent == null) { @@ -186,7 +183,8 @@ public final class DatabaseUtils { batteryStatus, batteryHealth, snapshotBootTimestamp, - snapshotTimestamp))); + snapshotTimestamp, + isFullChargeStart))); } int size = 1; @@ -197,6 +195,8 @@ public final class DatabaseUtils { valuesList.toArray(valuesArray); try { size = resolver.bulkInsert(BATTERY_CONTENT_URI, valuesArray); + Log.d(TAG, "insert() data into database with isFullChargeStart:" + + isFullChargeStart); } catch (Exception e) { Log.e(TAG, "bulkInsert() data into database error:\n" + e); } @@ -210,15 +210,18 @@ public final class DatabaseUtils { batteryStatus, batteryHealth, snapshotBootTimestamp, - snapshotTimestamp); + snapshotTimestamp, + isFullChargeStart); try { resolver.insert(BATTERY_CONTENT_URI, contentValues); + Log.d(TAG, "insert() data into database with isFullChargeStart:" + + isFullChargeStart); + } catch (Exception e) { Log.e(TAG, "insert() data into database error:\n" + e); } valuesList.add(contentValues); } - saveLastFullChargeTimestampPref(context, batteryStatus, batteryLevel, snapshotTimestamp); resolver.notifyChange(BATTERY_CONTENT_URI, /*observer=*/ null); Log.d(TAG, String.format("sendBatteryEntryData() size=%d in %d/ms", size, (System.currentTimeMillis() - startTime))); @@ -226,42 +229,6 @@ public final class DatabaseUtils { return valuesList; } - @VisibleForTesting - static void saveLastFullChargeTimestampPref( - Context context, int batteryStatus, int batteryLevel, long timestamp) { - // Updates the SharedPreference only when timestamp is valid and phone is full charge. - if (!BatteryStatus.isCharged(batteryStatus, batteryLevel)) { - return; - } - - final boolean success = - getSharedPreferences(context) - .edit() - .putLong(PREF_FULL_CHARGE_TIMESTAMP_KEY, timestamp) - .commit(); - if (!success) { - Log.w(TAG, "saveLastFullChargeTimestampPref() fail: value=" + timestamp); - } - } - - @VisibleForTesting - static long getLastFullChargeTimestampPref(Context context) { - return getSharedPreferences(context).getLong(PREF_FULL_CHARGE_TIMESTAMP_KEY, 0); - } - - /** - * Returns the start timestamp for "since last full charge" battery usage chart. - * If the last full charge happens within the last 7 days, returns the timestamp of last full - * charge. Otherwise, returns the timestamp for 00:00 6 days before the calendar date. - */ - @VisibleForTesting - static long getStartTimestampForLastFullCharge( - Context context, Calendar calendar) { - final long lastFullChargeTimestamp = getLastFullChargeTimestampPref(context); - final long sixDayAgoTimestamp = getTimestampSixDaysAgo(calendar); - return Math.max(lastFullChargeTimestamp, sixDayAgoTimestamp); - } - private static Map> loadHistoryMapFromContentProvider( Context context, Uri batteryStateUri) { final boolean isWorkProfileUser = isWorkProfile(context); @@ -313,13 +280,6 @@ public final class DatabaseUtils { }, CLEAR_MEMORY_DELAYED_MS); } - private static SharedPreferences getSharedPreferences(Context context) { - return context - .getApplicationContext() // ensures we bind it with application - .createDeviceProtectedStorageContext() - .getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE); - } - /** Returns the timestamp for 00:00 6 days before the calendar date. */ private static long getTimestampSixDaysAgo(Calendar calendar) { Calendar startCalendar = diff --git a/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java index d2345ab4f6d..fddf01bce3c 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java +++ b/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiver.java @@ -39,7 +39,7 @@ public final class PeriodicJobReceiver extends BroadcastReceiver { Log.w(TAG, "do not refresh job for work profile action=" + action); return; } - BatteryUsageDataLoader.enqueueWork(context); + BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ false); Log.d(TAG, "refresh periodic job from action=" + action); PeriodicJobManager.getInstance(context).refreshJob(); DatabaseUtils.clearExpiredDataIfNeeded(context); diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java index b1afa6b6e9a..936d5e053c7 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java +++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java @@ -41,9 +41,11 @@ public interface BatteryStateDao { @Query("SELECT * FROM BatteryState WHERE timestamp > :timestamp ORDER BY timestamp DESC") List getAllAfter(long timestamp); - /** Gets the {@link Cursor} of all recorded data from a specific timestamp. */ - @Query("SELECT * FROM BatteryState WHERE timestamp >= :timestamp ORDER BY timestamp DESC") - Cursor getCursorAfter(long timestamp); + /** Gets the {@link Cursor} of all recorded data since last full charge within 7 days. */ + @Query("SELECT * FROM BatteryState WHERE timestamp >= :timestampSixDaysAgo AND timestamp >= " + + "(SELECT MAX(timestamp) FROM BatteryState WHERE isFullChargeCycleStart = 1)" + + " ORDER BY timestamp ASC") + Cursor getCursorSinceLastFullCharge(long timestampSixDaysAgo); /** Get the count of distinct timestamp after a specific timestamp. */ @Query("SELECT COUNT(DISTINCT timestamp) FROM BatteryState WHERE timestamp > :timestamp") diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryHistEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryHistEntryTest.java index d7a5503f1c4..21dc79b8861 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryHistEntryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryHistEntryTest.java @@ -71,7 +71,8 @@ public final class BatteryHistEntryTest { /*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL, /*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD, /*bootTimestamp=*/ 101L, - /*timestamp=*/ 10001L); + /*timestamp=*/ 10001L, + /*isFullChargeStart=*/ false); assertBatteryHistEntry( new BatteryHistEntry(values), diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java index 361c5960081..4b596a6ae22 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java @@ -49,6 +49,9 @@ import java.util.concurrent.TimeUnit; @RunWith(RobolectricTestRunner.class) public final class BatteryUsageContentProviderTest { private static final Uri VALID_BATTERY_STATE_CONTENT_URI = DatabaseUtils.BATTERY_CONTENT_URI; + private static final String PACKAGE_NAME1 = "com.android.settings1"; + private static final String PACKAGE_NAME2 = "com.android.settings2"; + private static final String PACKAGE_NAME3 = "com.android.settings3"; private Context mContext; private BatteryUsageContentProvider mProvider; @@ -118,31 +121,60 @@ public final class BatteryUsageContentProviderTest { public void query_batteryState_returnsExpectedResult() throws Exception { mProvider.onCreate(); final Duration currentTime = Duration.ofHours(52); - final long expiredTimeCutoff = currentTime.toMillis() - - BatteryUsageContentProvider.QUERY_DURATION_HOURS.toMillis(); - testQueryBatteryState(currentTime, expiredTimeCutoff, /*hasQueryTimestamp=*/ false); + final long expiredTimeCutoff = currentTime.toMillis() - 3; + + final Cursor cursor = insertBatteryState(currentTime, Long.toString(expiredTimeCutoff)); + + // Verifies the result not include expired data. + assertThat(cursor.getCount()).isEqualTo(3); + final int packageNameIndex = cursor.getColumnIndex("packageName"); + // Verifies the first data package name. + cursor.moveToFirst(); + final String actualPackageName1 = cursor.getString(packageNameIndex); + assertThat(actualPackageName1).isEqualTo(PACKAGE_NAME1); + // Verifies the second data package name. + cursor.moveToNext(); + final String actualPackageName2 = cursor.getString(packageNameIndex); + assertThat(actualPackageName2).isEqualTo(PACKAGE_NAME2); + // Verifies the third data package name. + cursor.moveToNext(); + final String actualPackageName3 = cursor.getString(packageNameIndex); + assertThat(actualPackageName3).isEqualTo(PACKAGE_NAME3); + cursor.close(); + // Verifies the broadcast intent. + TimeUnit.SECONDS.sleep(1); + final List intents = Shadows.shadowOf((Application) mContext).getBroadcastIntents(); + assertThat(intents).hasSize(1); + assertThat(intents.get(0).getAction()).isEqualTo( + BootBroadcastReceiver.ACTION_PERIODIC_JOB_RECHECK); } @Test public void query_batteryStateTimestamp_returnsExpectedResult() throws Exception { mProvider.onCreate(); final Duration currentTime = Duration.ofHours(52); - final long expiredTimeCutoff = currentTime.toMillis() - Duration.ofHours(10).toMillis(); - testQueryBatteryState(currentTime, expiredTimeCutoff, /*hasQueryTimestamp=*/ true); - } + final long expiredTimeCutoff = currentTime.toMillis() - 1; - @Test - public void query_incorrectParameterFormat_returnsExpectedResult() throws Exception { - mProvider.onCreate(); - final Duration currentTime = Duration.ofHours(52); - final long expiredTimeCutoff = - currentTime.toMillis() - - BatteryUsageContentProvider.QUERY_DURATION_HOURS.toMillis(); - testQueryBatteryState( - currentTime, - expiredTimeCutoff, - /*hasQueryTimestamp=*/ false, - /*customParameter=*/ "invalid number format"); + final Cursor cursor = insertBatteryState(currentTime, Long.toString(expiredTimeCutoff)); + + // Verifies the result not include expired data. + assertThat(cursor.getCount()).isEqualTo(2); + final int packageNameIndex = cursor.getColumnIndex("packageName"); + // Verifies the first data package name. + cursor.moveToFirst(); + final String actualPackageName1 = cursor.getString(packageNameIndex); + assertThat(actualPackageName1).isEqualTo(PACKAGE_NAME2); + // Verifies the third data package name. + cursor.moveToNext(); + final String actualPackageName2 = cursor.getString(packageNameIndex); + assertThat(actualPackageName2).isEqualTo(PACKAGE_NAME3); + cursor.close(); + // Verifies the broadcast intent. + TimeUnit.SECONDS.sleep(1); + final List intents = Shadows.shadowOf((Application) mContext).getBroadcastIntents(); + assertThat(intents).hasSize(1); + assertThat(intents.get(0).getAction()).isEqualTo( + BootBroadcastReceiver.ACTION_PERIODIC_JOB_RECHECK); } @Test @@ -247,54 +279,32 @@ public final class BatteryUsageContentProviderTest { /*strings=*/ null)); } - private void testQueryBatteryState( - Duration currentTime, long expiredTimeCutoff, boolean hasQueryTimestamp) - throws Exception { - testQueryBatteryState(currentTime, expiredTimeCutoff, hasQueryTimestamp, null); - } - - private void testQueryBatteryState( + private Cursor insertBatteryState( Duration currentTime, - long expiredTimeCutoff, - boolean hasQueryTimestamp, - String customParameter) + String queryTimestamp) throws Exception { mProvider.onCreate(); final FakeClock fakeClock = new FakeClock(); fakeClock.setCurrentTime(currentTime); mProvider.setClock(fakeClock); - // Inserts some expired testing data. - BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, expiredTimeCutoff - 1, "com.android.sysui1"); - BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, expiredTimeCutoff - 2, "com.android.sysui2"); - BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, expiredTimeCutoff - 3, "com.android.sysui3"); + final long currentTimestamp = currentTime.toMillis(); // Inserts some valid testing data. - final String packageName1 = "com.android.settings1"; - final String packageName2 = "com.android.settings2"; - final String packageName3 = "com.android.settings3"; BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, currentTime.toMillis(), packageName1); + mContext, currentTimestamp - 2, PACKAGE_NAME1, + /*isFullChargeStart=*/ true); BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, expiredTimeCutoff + 2, packageName2); + mContext, currentTimestamp - 1, PACKAGE_NAME2); BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, expiredTimeCutoff, packageName3); + mContext, currentTimestamp, PACKAGE_NAME3); - final Uri.Builder builder = + final Uri batteryStateQueryContentUri = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(DatabaseUtils.AUTHORITY) - .appendPath(DatabaseUtils.BATTERY_STATE_TABLE); - if (customParameter != null) { - builder.appendQueryParameter( - BatteryUsageContentProvider.QUERY_KEY_TIMESTAMP, customParameter); - } else if (hasQueryTimestamp) { - builder.appendQueryParameter( - BatteryUsageContentProvider.QUERY_KEY_TIMESTAMP, - Long.toString(expiredTimeCutoff)); - } - final Uri batteryStateQueryContentUri = builder.build(); + .appendPath(DatabaseUtils.BATTERY_STATE_TABLE) + .appendQueryParameter( + BatteryUsageContentProvider.QUERY_KEY_TIMESTAMP, queryTimestamp) + .build(); final Cursor cursor = mProvider.query( @@ -304,27 +314,6 @@ public final class BatteryUsageContentProviderTest { /*strings1=*/ null, /*s1=*/ null); - // Verifies the result not include expired data. - assertThat(cursor.getCount()).isEqualTo(3); - final int packageNameIndex = cursor.getColumnIndex("packageName"); - // Verifies the first data package name. - cursor.moveToFirst(); - final String actualPackageName1 = cursor.getString(packageNameIndex); - assertThat(actualPackageName1).isEqualTo(packageName1); - // Verifies the second data package name. - cursor.moveToNext(); - final String actualPackageName2 = cursor.getString(packageNameIndex); - assertThat(actualPackageName2).isEqualTo(packageName2); - // Verifies the third data package name. - cursor.moveToNext(); - final String actualPackageName3 = cursor.getString(packageNameIndex); - assertThat(actualPackageName3).isEqualTo(packageName3); - cursor.close(); - // Verifies the broadcast intent. - TimeUnit.SECONDS.sleep(1); - final List intents = Shadows.shadowOf((Application) mContext).getBroadcastIntents(); - assertThat(intents).hasSize(1); - assertThat(intents.get(0).getAction()).isEqualTo( - BootBroadcastReceiver.ACTION_PERIODIC_JOB_RECHECK); + return cursor; } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java index 9c0604d9f13..9aeff794907 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java @@ -82,7 +82,7 @@ public final class BatteryUsageDataLoaderTest { .thenReturn(mBatteryUsageStats); BatteryUsageDataLoader.sFakeBatteryEntryListSupplier = () -> batteryEntryList; - BatteryUsageDataLoader.loadUsageData(mContext); + BatteryUsageDataLoader.loadUsageData(mContext, /*isFullChargeStart=*/ false); final int queryFlags = mStatsQueryCaptor.getValue().getFlags(); assertThat(queryFlags @@ -97,7 +97,7 @@ public final class BatteryUsageDataLoaderTest { .thenReturn(mBatteryUsageStats); BatteryUsageDataLoader.sFakeBatteryEntryListSupplier = () -> null; - BatteryUsageDataLoader.loadUsageData(mContext); + BatteryUsageDataLoader.loadUsageData(mContext, /*isFullChargeStart=*/ false); verify(mMockContentResolver).insert(any(), any()); } @@ -106,9 +106,9 @@ public final class BatteryUsageDataLoaderTest { public void loadUsageData_emptyBatteryEntryList_insertFakeDataIntoProvider() { when(mBatteryStatsManager.getBatteryUsageStats(mStatsQueryCaptor.capture())) .thenReturn(mBatteryUsageStats); - BatteryUsageDataLoader.sFakeBatteryEntryListSupplier = () -> new ArrayList(); + BatteryUsageDataLoader.sFakeBatteryEntryListSupplier = () -> new ArrayList<>(); - BatteryUsageDataLoader.loadUsageData(mContext); + BatteryUsageDataLoader.loadUsageData(mContext, /*isFullChargeStart=*/ false); verify(mMockContentResolver).insert(any(), any()); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java index dd8c536be5e..9ea8ced3b13 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java @@ -95,7 +95,8 @@ public final class ConvertUtilsTest { /*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL, /*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD, /*bootTimestamp=*/ 101L, - /*timestamp=*/ 10001L); + /*timestamp=*/ 10001L, + /*isFullChargeStart=*/ true); final BatteryInformation batteryInformation = ConvertUtils.getBatteryInformation( values, BatteryHistEntry.KEY_BATTERY_INFORMATION); @@ -109,6 +110,7 @@ public final class ConvertUtilsTest { assertThat(values.getAsLong(BatteryHistEntry.KEY_TIMESTAMP)).isEqualTo(10001L); assertThat(values.getAsInteger(BatteryHistEntry.KEY_CONSUMER_TYPE)) .isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY); + assertThat(values.getAsBoolean(BatteryHistEntry.KEY_IS_FULL_CHARGE_CYCLE_START)).isTrue(); assertThat(batteryInformation.getAppLabel()).isEqualTo("Settings"); assertThat(batteryInformation.getIsHidden()).isTrue(); assertThat(batteryInformation.getBootTimestamp()).isEqualTo(101L); @@ -136,7 +138,8 @@ public final class ConvertUtilsTest { /*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL, /*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD, /*bootTimestamp=*/ 101L, - /*timestamp=*/ 10001L); + /*timestamp=*/ 10001L, + /*isFullChargeStart=*/ false); final BatteryInformation batteryInformation = ConvertUtils.getBatteryInformation( @@ -144,6 +147,7 @@ public final class ConvertUtilsTest { final DeviceBatteryState deviceBatteryState = batteryInformation.getDeviceBatteryState(); assertThat(batteryInformation.getBootTimestamp()).isEqualTo(101L); assertThat(batteryInformation.getZoneId()).isEqualTo(TimeZone.getDefault().getID()); + assertThat(values.getAsBoolean(BatteryHistEntry.KEY_IS_FULL_CHARGE_CYCLE_START)).isFalse(); assertThat(deviceBatteryState.getBatteryLevel()).isEqualTo(12); assertThat(deviceBatteryState.getBatteryStatus()) .isEqualTo(BatteryManager.BATTERY_STATUS_FULL); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java index d140ec11619..0c662678c38 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java @@ -46,7 +46,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import java.util.ArrayList; -import java.util.Calendar; import java.util.List; import java.util.Map; @@ -99,7 +98,8 @@ public final class DatabaseUtilsTest { doReturn(null).when(mContext).registerReceiver(any(), any()); assertThat( DatabaseUtils.sendBatteryEntryData( - mContext, /*batteryEntryList=*/ null, mBatteryUsageStats)) + mContext, /*batteryEntryList=*/ null, mBatteryUsageStats, + /*isFullChargeStart=*/ false)) .isNull(); } @@ -118,7 +118,8 @@ public final class DatabaseUtilsTest { final List valuesList = DatabaseUtils.sendBatteryEntryData( - mContext, batteryEntryList, mBatteryUsageStats); + mContext, batteryEntryList, mBatteryUsageStats, + /*isFullChargeStart=*/ false); assertThat(valuesList).hasSize(2); // Verifies the ContentValues content. @@ -141,7 +142,8 @@ public final class DatabaseUtilsTest { DatabaseUtils.sendBatteryEntryData( mContext, new ArrayList<>(), - mBatteryUsageStats); + mBatteryUsageStats, + /*isFullChargeStart=*/ false); assertThat(valuesList).hasSize(1); verifyFakeContentValues(valuesList.get(0)); @@ -159,7 +161,8 @@ public final class DatabaseUtilsTest { DatabaseUtils.sendBatteryEntryData( mContext, /*batteryEntryList=*/ null, - mBatteryUsageStats); + mBatteryUsageStats, + /*isFullChargeStart=*/ false); assertThat(valuesList).hasSize(1); verifyFakeContentValues(valuesList.get(0)); @@ -177,7 +180,8 @@ public final class DatabaseUtilsTest { DatabaseUtils.sendBatteryEntryData( mContext, /*batteryEntryList=*/ null, - /*batteryUsageStats=*/ null); + /*batteryUsageStats=*/ null, + /*isFullChargeStart=*/ false); assertThat(valuesList).hasSize(1); verifyFakeContentValues(valuesList.get(0)); @@ -258,88 +262,6 @@ public final class DatabaseUtilsTest { assertThat(batteryHistMap).isEmpty(); } - @Test - public void saveLastFullChargeTimestampPref_notFullCharge_returnsFalse() { - DatabaseUtils.saveLastFullChargeTimestampPref( - mContext, - BatteryManager.BATTERY_STATUS_UNKNOWN, - /* level */ 10, - /* timestamp */ 1); - assertThat(DatabaseUtils.getLastFullChargeTimestampPref(mContext)).isEqualTo(0); - } - - @Test - public void saveLastFullChargeTimestampPref_fullStatus_returnsTrue() { - long expectedTimestamp = 1; - DatabaseUtils.saveLastFullChargeTimestampPref( - mContext, - BatteryManager.BATTERY_STATUS_FULL, - /* level */ 10, - /* timestamp */ expectedTimestamp); - assertThat(DatabaseUtils.getLastFullChargeTimestampPref(mContext)) - .isEqualTo(expectedTimestamp); - } - - @Test - public void saveLastFullChargeTimestampPref_level100_returnsTrue() { - long expectedTimestamp = 1; - DatabaseUtils.saveLastFullChargeTimestampPref( - mContext, - BatteryManager.BATTERY_STATUS_UNKNOWN, - /* level */ 100, - /* timestamp */ expectedTimestamp); - assertThat(DatabaseUtils.getLastFullChargeTimestampPref(mContext)) - .isEqualTo(expectedTimestamp); - } - - @Test - public void getStartTimestampForLastFullCharge_noTimestampPreference_returnsSixDaysAgo() { - Calendar currentCalendar = Calendar.getInstance(); - currentCalendar.set(2022, 6, 5, 6, 30, 50); // 2022-07-05 06:30:50 - Calendar expectedCalendar = Calendar.getInstance(); - expectedCalendar.set(2022, 5, 29, 0, 0, 0); // 2022-06-29 00:00:00 - expectedCalendar.set(Calendar.MILLISECOND, 0); - - assertThat(DatabaseUtils.getStartTimestampForLastFullCharge(mContext, currentCalendar)) - .isEqualTo(expectedCalendar.getTimeInMillis()); - } - - @Test - public void getStartTimestampForLastFullCharge_lastFullChargeEarlier_returnsSixDaysAgo() { - Calendar lastFullCalendar = Calendar.getInstance(); - lastFullCalendar.set(2021, 11, 25, 6, 30, 50); // 2021-12-25 06:30:50 - DatabaseUtils.saveLastFullChargeTimestampPref( - mContext, - BatteryManager.BATTERY_STATUS_UNKNOWN, - /* level */ 100, - /* timestamp */ lastFullCalendar.getTimeInMillis()); - Calendar currentCalendar = Calendar.getInstance(); - currentCalendar.set(2022, 0, 2, 6, 30, 50); // 2022-01-02 06:30:50 - Calendar expectedCalendar = Calendar.getInstance(); - expectedCalendar.set(2021, 11, 27, 0, 0, 0); // 2021-12-27 00:00:00 - expectedCalendar.set(Calendar.MILLISECOND, 0); - - assertThat(DatabaseUtils.getStartTimestampForLastFullCharge(mContext, currentCalendar)) - .isEqualTo(expectedCalendar.getTimeInMillis()); - } - - @Test - public void getStartTimestampForLastFullCharge_lastFullChargeLater_returnsLastFullCharge() { - Calendar lastFullCalendar = Calendar.getInstance(); - lastFullCalendar.set(2022, 6, 1, 6, 30, 50); // 2022-07-01 06:30:50 - long expectedTimestamp = lastFullCalendar.getTimeInMillis(); - DatabaseUtils.saveLastFullChargeTimestampPref( - mContext, - BatteryManager.BATTERY_STATUS_UNKNOWN, - /* level */ 100, - /* timestamp */ expectedTimestamp); - Calendar currentCalendar = Calendar.getInstance(); - currentCalendar.set(2022, 6, 5, 6, 30, 50); // 2022-07-05 06:30:50 - - assertThat(DatabaseUtils.getStartTimestampForLastFullCharge(mContext, currentCalendar)) - .isEqualTo(expectedTimestamp); - } - private static void verifyContentValues(double consumedPower, ContentValues values) { final BatteryInformation batteryInformation = ConvertUtils.getBatteryInformation( diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java index 5a2276376f8..33735b31e9f 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java @@ -53,10 +53,13 @@ public final class BatteryStateDaoTest { mContext = ApplicationProvider.getApplicationContext(); mDatabase = BatteryTestUtils.setUpBatteryStateDatabase(mContext); mBatteryStateDao = mDatabase.batteryStateDao(); - BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP3, PACKAGE_NAME3); - BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP2, PACKAGE_NAME2); BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, TIMESTAMP1, PACKAGE_NAME1, /*multiple=*/ true); + mContext, TIMESTAMP3, PACKAGE_NAME3); + BatteryTestUtils.insertDataToBatteryStateDatabase( + mContext, TIMESTAMP2, PACKAGE_NAME2); + BatteryTestUtils.insertDataToBatteryStateDatabase( + mContext, TIMESTAMP1, PACKAGE_NAME1, /*multiple=*/ true, + /*isFullChargeStart=*/ true); } @After @@ -75,16 +78,26 @@ public final class BatteryStateDaoTest { } @Test - public void batteryStateDao_getCursorAfter() throws Exception { - final Cursor cursor = mBatteryStateDao.getCursorAfter(TIMESTAMP2); - assertThat(cursor.getCount()).isEqualTo(2); - assertThat(cursor.getColumnCount()).isEqualTo(CURSOR_COLUMN_SIZE); + public void batteryStateDao_getCursorSinceLastFullCharge() throws Exception { + final Cursor cursor1 = mBatteryStateDao.getCursorSinceLastFullCharge(TIMESTAMP1); + assertThat(cursor1.getCount()).isEqualTo(3); + assertThat(cursor1.getColumnCount()).isEqualTo(CURSOR_COLUMN_SIZE); // Verifies the queried first battery state. - cursor.moveToFirst(); - assertThat(cursor.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3); + cursor1.moveToFirst(); + assertThat(cursor1.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME1); // Verifies the queried second battery state. - cursor.moveToNext(); - assertThat(cursor.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME2); + cursor1.moveToNext(); + assertThat(cursor1.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME2); + // Verifies the queried third battery state. + cursor1.moveToNext(); + assertThat(cursor1.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3); + + final Cursor cursor2 = mBatteryStateDao.getCursorSinceLastFullCharge(TIMESTAMP3); + assertThat(cursor2.getCount()).isEqualTo(1); + assertThat(cursor2.getColumnCount()).isEqualTo(CURSOR_COLUMN_SIZE); + // Verifies the queried first battery state. + cursor2.moveToFirst(); + assertThat(cursor2.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3); } @Test diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java index 9023cc55f40..ffb3197ed4c 100644 --- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java @@ -72,12 +72,21 @@ public class BatteryTestUtils { /** Inserts a fake data into the database for testing. */ public static void insertDataToBatteryStateDatabase( Context context, long timestamp, String packageName) { - insertDataToBatteryStateDatabase(context, timestamp, packageName, /*multiple=*/ false); + insertDataToBatteryStateDatabase( + context, timestamp, packageName, /*multiple=*/ false, /*isFullChargeStart=*/ false); } /** Inserts a fake data into the database for testing. */ public static void insertDataToBatteryStateDatabase( - Context context, long timestamp, String packageName, boolean multiple) { + Context context, long timestamp, String packageName, boolean isFullChargeStart) { + insertDataToBatteryStateDatabase( + context, timestamp, packageName, /*multiple=*/ false, isFullChargeStart); + } + + /** Inserts a fake data into the database for testing. */ + public static void insertDataToBatteryStateDatabase( + Context context, long timestamp, String packageName, boolean multiple, + boolean isFullChargeStart) { DeviceBatteryState deviceBatteryState = DeviceBatteryState .newBuilder() @@ -113,7 +122,7 @@ public class BatteryTestUtils { packageName, timestamp, /*consumerType=*/ 2, - /*isFullChargeCycleStart=*/ false, + isFullChargeStart, ConvertUtils.convertBatteryInformationToString(batteryInformation), ""); BatteryStateDao dao =