Merge "Clear cache data to recalculate usage slot after receiving timezone change intent." into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
28323b908f
@@ -455,6 +455,21 @@ public final class DatabaseUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Clears generated cache data in the battery usage database. */
|
||||||
|
public static void clearEvenHourCacheData(Context context) {
|
||||||
|
AsyncTask.execute(
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
final BatteryStateDatabase database =
|
||||||
|
BatteryStateDatabase.getInstance(context.getApplicationContext());
|
||||||
|
database.batteryEventDao().clearEvenHourEvent();
|
||||||
|
database.batteryUsageSlotDao().clearAll();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(TAG, "clearEvenHourCacheData() failed", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/** Clears all out-of-date data in the battery usage database. */
|
/** Clears all out-of-date data in the battery usage database. */
|
||||||
public static void clearExpiredDataIfNeeded(Context context) {
|
public static void clearExpiredDataIfNeeded(Context context) {
|
||||||
AsyncTask.execute(
|
AsyncTask.execute(
|
||||||
@@ -923,14 +938,12 @@ public final class DatabaseUtils {
|
|||||||
final String logInfo =
|
final String logInfo =
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ENGLISH,
|
Locale.ENGLISH,
|
||||||
"clear database for new time zone = %s",
|
"clear database cache for new time zone = %s",
|
||||||
TimeZone.getDefault().toString());
|
TimeZone.getDefault().toString());
|
||||||
BatteryUsageLogUtils.writeLog(context, Action.TIMEZONE_UPDATED, logInfo);
|
BatteryUsageLogUtils.writeLog(context, Action.TIMEZONE_UPDATED, logInfo);
|
||||||
Log.d(TAG, logInfo);
|
Log.d(TAG, logInfo);
|
||||||
DatabaseUtils.clearAll(context);
|
DatabaseUtils.clearEvenHourCacheData(context);
|
||||||
PeriodicJobManager.getInstance(context).refreshJob(/* fromBoot= */ false);
|
PeriodicJobManager.getInstance(context).refreshJob(/* fromBoot= */ false);
|
||||||
// Take a snapshot of battery usage data immediately
|
|
||||||
BatteryUsageDataLoader.enqueueWork(context, /* isFullChargeStart= */ true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long loadLongFromContentProvider(
|
private static long loadLongFromContentProvider(
|
||||||
|
@@ -20,12 +20,14 @@ import androidx.room.Dao
|
|||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import com.android.settings.fuelgauge.batteryusage.BatteryEventType
|
||||||
|
|
||||||
/** Data access object for accessing [BatteryEventEntity] in the database. */
|
/** Data access object for accessing [BatteryEventEntity] in the database. */
|
||||||
@Dao
|
@Dao
|
||||||
interface BatteryEventDao {
|
interface BatteryEventDao {
|
||||||
/** Inserts a [BatteryEventEntity] data into the database. */
|
/** Inserts a [BatteryEventEntity] data into the database. */
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(event: BatteryEventEntity)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun insert(event: BatteryEventEntity)
|
||||||
|
|
||||||
/** Gets all recorded data. */
|
/** Gets all recorded data. */
|
||||||
@Query("SELECT * FROM BatteryEventEntity ORDER BY timestamp DESC")
|
@Query("SELECT * FROM BatteryEventEntity ORDER BY timestamp DESC")
|
||||||
@@ -68,6 +70,14 @@ interface BatteryEventDao {
|
|||||||
@Query("DELETE FROM BatteryEventEntity WHERE timestamp >= :timestamp")
|
@Query("DELETE FROM BatteryEventEntity WHERE timestamp >= :timestamp")
|
||||||
fun clearAllAfter(timestamp: Long)
|
fun clearAllAfter(timestamp: Long)
|
||||||
|
|
||||||
|
/** Deletes even_hour event data in the database. */
|
||||||
|
@Query(
|
||||||
|
"DELETE FROM BatteryEventEntity " +
|
||||||
|
"WHERE batteryEventType = 4" // BatteryEventType.EVEN_HOUR = 4
|
||||||
|
)
|
||||||
|
fun clearEvenHourEvent()
|
||||||
|
|
||||||
/** Clears all recorded data in the database. */
|
/** Clears all recorded data in the database. */
|
||||||
@Query("DELETE FROM BatteryEventEntity") fun clearAll()
|
@Query("DELETE FROM BatteryEventEntity")
|
||||||
|
fun clearAll()
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,7 @@ import android.os.UserManager;
|
|||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryEventDao;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
|
||||||
import com.android.settings.testutils.BatteryTestUtils;
|
import com.android.settings.testutils.BatteryTestUtils;
|
||||||
@@ -56,7 +57,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public final class BootBroadcastReceiverTest {
|
public final class BootBroadcastReceiverTest {
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private BatteryStateDao mDao;
|
private BatteryStateDao mBatteryStateDao;
|
||||||
|
private BatteryEventDao mBatteryEventDao;
|
||||||
private BootBroadcastReceiver mReceiver;
|
private BootBroadcastReceiver mReceiver;
|
||||||
private ShadowAlarmManager mShadowAlarmManager;
|
private ShadowAlarmManager mShadowAlarmManager;
|
||||||
private PeriodicJobManager mPeriodicJobManager;
|
private PeriodicJobManager mPeriodicJobManager;
|
||||||
@@ -76,8 +78,10 @@ public final class BootBroadcastReceiverTest {
|
|||||||
|
|
||||||
// Inserts fake data into database for testing.
|
// Inserts fake data into database for testing.
|
||||||
final BatteryStateDatabase database = BatteryTestUtils.setUpBatteryStateDatabase(mContext);
|
final BatteryStateDatabase database = BatteryTestUtils.setUpBatteryStateDatabase(mContext);
|
||||||
mDao = database.batteryStateDao();
|
mBatteryStateDao = database.batteryStateDao();
|
||||||
mDao.clearAll();
|
mBatteryStateDao.clearAll();
|
||||||
|
mBatteryEventDao = database.batteryEventDao();
|
||||||
|
mBatteryEventDao.clearAll();
|
||||||
clearSharedPreferences();
|
clearSharedPreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,36 +155,32 @@ public final class BootBroadcastReceiverTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onReceive_withTimeChangedIntentSetEarlierTime_refreshesJob()
|
public void onReceive_withTimeChangedIntentSetEarlierTime_refreshesJob()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
BatteryTestUtils.insertDataToBatteryStateTable(
|
insertDataToTable(Clock.systemUTC().millis() + 60000);
|
||||||
mContext, Clock.systemUTC().millis() + 60000, "com.android.systemui");
|
|
||||||
assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
|
|
||||||
|
|
||||||
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIME_CHANGED));
|
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIME_CHANGED));
|
||||||
|
|
||||||
TimeUnit.MILLISECONDS.sleep(1000);
|
TimeUnit.MILLISECONDS.sleep(1000);
|
||||||
assertThat(mDao.getAllAfter(0)).isEmpty();
|
assertThat(mBatteryStateDao.getAllAfter(0)).isEmpty();
|
||||||
|
assertThat(mBatteryEventDao.getAllAfterForLog(0)).isEmpty();
|
||||||
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
|
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onReceive_withTimeChangedIntentSetLaterTime_clearNoDataAndRefreshesJob()
|
public void onReceive_withTimeChangedIntentSetLaterTime_clearNoDataAndRefreshesJob()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
BatteryTestUtils.insertDataToBatteryStateTable(
|
insertDataToTable(Clock.systemUTC().millis() - 60000);
|
||||||
mContext, Clock.systemUTC().millis() - 60000, "com.android.systemui");
|
|
||||||
assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
|
|
||||||
|
|
||||||
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIME_CHANGED));
|
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIME_CHANGED));
|
||||||
|
|
||||||
TimeUnit.MILLISECONDS.sleep(1000);
|
TimeUnit.MILLISECONDS.sleep(1000);
|
||||||
assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
|
assertThat(mBatteryStateDao.getAllAfter(0)).hasSize(1);
|
||||||
|
assertThat(mBatteryEventDao.getAllAfterForLog(0)).hasSize(1);
|
||||||
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
|
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onReceive_withTimeFormatChangedIntent_skipRefreshJob() throws InterruptedException {
|
public void onReceive_withTimeFormatChangedIntent_skipRefreshJob() throws InterruptedException {
|
||||||
BatteryTestUtils.insertDataToBatteryStateTable(
|
insertDataToTable(Clock.systemUTC().millis() + 60000);
|
||||||
mContext, Clock.systemUTC().millis() + 60000, "com.android.systemui");
|
|
||||||
assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
|
|
||||||
|
|
||||||
mReceiver.onReceive(
|
mReceiver.onReceive(
|
||||||
mContext,
|
mContext,
|
||||||
@@ -190,21 +190,24 @@ public final class BootBroadcastReceiverTest {
|
|||||||
Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR));
|
Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR));
|
||||||
|
|
||||||
TimeUnit.MILLISECONDS.sleep(1000);
|
TimeUnit.MILLISECONDS.sleep(1000);
|
||||||
assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
|
assertThat(mBatteryStateDao.getAllAfter(0)).hasSize(1);
|
||||||
|
assertThat(mBatteryEventDao.getAllAfterForLog(0)).hasSize(1);
|
||||||
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNull();
|
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onReceive_withTimeZoneChangedIntent_clearAllDataAndRefreshesJob()
|
public void onReceive_withTimeZoneChangedIntent_clearCacheDataAndRefreshesJob()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
BatteryTestUtils.insertDataToBatteryStateTable(
|
insertDataToTable(Clock.systemUTC().millis());
|
||||||
mContext, Clock.systemUTC().millis(), "com.android.systemui");
|
|
||||||
assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
|
assertThat(mBatteryStateDao.getAllAfter(0)).hasSize(1);
|
||||||
|
|
||||||
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIMEZONE_CHANGED));
|
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIMEZONE_CHANGED));
|
||||||
|
|
||||||
TimeUnit.MILLISECONDS.sleep(1000);
|
TimeUnit.MILLISECONDS.sleep(1000);
|
||||||
assertThat(mDao.getAllAfter(0)).isEmpty();
|
// Only clear cache data.
|
||||||
|
assertThat(mBatteryStateDao.getAllAfter(0)).hasSize(1);
|
||||||
|
assertThat(mBatteryEventDao.getAllAfterForLog(0)).isEmpty();
|
||||||
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
|
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,4 +224,13 @@ public final class BootBroadcastReceiverTest {
|
|||||||
private void clearSharedPreferences() {
|
private void clearSharedPreferences() {
|
||||||
DatabaseUtils.getSharedPreferences(mContext).edit().clear().apply();
|
DatabaseUtils.getSharedPreferences(mContext).edit().clear().apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void insertDataToTable(long recordTimeMs) {
|
||||||
|
BatteryTestUtils.insertDataToBatteryStateTable(
|
||||||
|
mContext, recordTimeMs, "com.android.systemui");
|
||||||
|
BatteryTestUtils.insertDataToBatteryEventTable(
|
||||||
|
mContext, recordTimeMs, BatteryEventType.EVEN_HOUR.getNumber(), 50);
|
||||||
|
assertThat(mBatteryStateDao.getAllAfter(0)).hasSize(1);
|
||||||
|
assertThat(mBatteryEventDao.getAllAfterForLog(0)).hasSize(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -175,4 +175,31 @@ public final class BatteryEventDaoTest {
|
|||||||
mBatteryEventDao.clearAll();
|
mBatteryEventDao.clearAll();
|
||||||
assertThat(mBatteryEventDao.getAll()).isEmpty();
|
assertThat(mBatteryEventDao.getAll()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearEvenHourEvent_normalFlow_expectedBehavior() {
|
||||||
|
mBatteryEventDao.insert(
|
||||||
|
BatteryEventEntity.newBuilder()
|
||||||
|
.setTimestamp(100L)
|
||||||
|
.setBatteryEventType(1)
|
||||||
|
.setBatteryLevel(66)
|
||||||
|
.build());
|
||||||
|
mBatteryEventDao.insert(
|
||||||
|
BatteryEventEntity.newBuilder()
|
||||||
|
.setTimestamp(200L)
|
||||||
|
.setBatteryEventType(4)
|
||||||
|
.setBatteryLevel(88)
|
||||||
|
.build());
|
||||||
|
assertThat(mBatteryEventDao.getAll()).hasSize(2);
|
||||||
|
|
||||||
|
mBatteryEventDao.clearEvenHourEvent();
|
||||||
|
|
||||||
|
final List<BatteryEventEntity> events = mBatteryEventDao.getAll();
|
||||||
|
assertThat(events).hasSize(1);
|
||||||
|
assertThat(events.get(0).timestamp).isEqualTo(100L);
|
||||||
|
assertThat(events.get(0).batteryEventType).isEqualTo(1);
|
||||||
|
assertThat(events.get(0).batteryLevel).isEqualTo(66);
|
||||||
|
mBatteryEventDao.clearAll();
|
||||||
|
assertThat(mBatteryEventDao.getAll()).isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,8 @@ import com.android.settings.fuelgauge.batteryusage.WarningBannerInfo;
|
|||||||
import com.android.settings.fuelgauge.batteryusage.WarningItemInfo;
|
import com.android.settings.fuelgauge.batteryusage.WarningItemInfo;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao;
|
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
|
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
|
||||||
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryEventDao;
|
||||||
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
|
||||||
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
|
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
|
||||||
@@ -184,6 +186,15 @@ public class BatteryTestUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Inserts a fake data into the database for testing. */
|
||||||
|
public static void insertDataToBatteryEventTable(
|
||||||
|
Context context, long timestamp, int batteryEventType, int batteryLevel) {
|
||||||
|
final BatteryEventEntity entity =
|
||||||
|
new BatteryEventEntity(timestamp, batteryEventType, batteryLevel);
|
||||||
|
BatteryEventDao dao = BatteryStateDatabase.getInstance(context).batteryEventDao();
|
||||||
|
dao.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets customized battery changed intent. */
|
/** Gets customized battery changed intent. */
|
||||||
public static Intent getCustomBatteryIntent(int plugged, int level, int scale, int status) {
|
public static Intent getCustomBatteryIntent(int plugged, int level, int scale, int status) {
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
|
Reference in New Issue
Block a user