diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java b/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java index 58e9d03ef5c..772660a69d3 100644 --- a/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java +++ b/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java @@ -16,6 +16,8 @@ package com.android.settings.fuelgauge.batterytip; +import static android.database.sqlite.SQLiteDatabase.CONFLICT_IGNORE; + import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns .ANOMALY_STATE; import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns @@ -64,12 +66,15 @@ public class BatteryDatabaseManager { /** * Insert an anomaly log to database. * + * @param uid the uid of the app * @param packageName the package name of the app * @param type the type of the anomaly * @param anomalyState the state of the anomaly * @param timestampMs the time when it is happened + * @return {@code true} if insert operation succeed */ - public synchronized void insertAnomaly(int uid, String packageName, int type, int anomalyState, + public synchronized boolean insertAnomaly(int uid, String packageName, int type, + int anomalyState, long timestampMs) { try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) { ContentValues values = new ContentValues(); @@ -78,7 +83,7 @@ public class BatteryDatabaseManager { values.put(ANOMALY_TYPE, type); values.put(ANOMALY_STATE, anomalyState); values.put(TIME_STAMP_MS, timestampMs); - db.insert(TABLE_ANOMALY, null, values); + return db.insertWithOnConflict(TABLE_ANOMALY, null, values, CONFLICT_IGNORE) != -1; } } diff --git a/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java b/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java index 5d68c76e641..a24a17ae070 100644 --- a/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java +++ b/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java @@ -21,6 +21,8 @@ import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static com.google.common.truth.Truth.assertThat; + import android.app.Instrumentation; import android.content.Context; import android.content.Intent; @@ -33,6 +35,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.List; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @@ -41,6 +44,8 @@ public class RestrictAppTest { private static final String BATTERY_INTENT = "android.intent.action.POWER_USAGE_SUMMARY"; private static final String PACKAGE_SETTINGS = "com.android.settings"; private static final String PACKAGE_SYSTEM_UI = "com.android.systemui"; + private static final int ANOMALY_TYPE = + StatsManagerConfig.AnomalyType.EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF; private BatteryDatabaseManager mBatteryDatabaseManager; private PackageManager mPackageManager; @@ -58,7 +63,7 @@ public class RestrictAppTest { public void batterySettings_hasOneAnomaly_showAnomaly() throws PackageManager.NameNotFoundException { mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0), - PACKAGE_SETTINGS, 1, + PACKAGE_SETTINGS, ANOMALY_TYPE, AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis()); Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); @@ -70,10 +75,10 @@ public class RestrictAppTest { public void batterySettings_hasTwoAnomalies_showAnomalies() throws PackageManager.NameNotFoundException { mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0), - PACKAGE_SETTINGS, 1, + PACKAGE_SETTINGS, ANOMALY_TYPE, AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis()); mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SYSTEM_UI, 0), - PACKAGE_SYSTEM_UI, 1, + PACKAGE_SYSTEM_UI, ANOMALY_TYPE, AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis()); Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); @@ -95,4 +100,26 @@ public class RestrictAppTest { instrumentation.startActivitySync(new Intent(BATTERY_INTENT)); onView(withText("2 apps recently restricted")).check(matches(isDisplayed())); } + + @Test + public void insertDuplicateAnomalies_onlyInsertOnce() throws + PackageManager.NameNotFoundException { + final int uid = mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0); + final long now = System.currentTimeMillis(); + + // Insert same anomaly twice, it fails at the second time. + assertThat(mBatteryDatabaseManager.insertAnomaly(uid, PACKAGE_SETTINGS, ANOMALY_TYPE, + AnomalyDatabaseHelper.State.NEW, now)).isTrue(); + assertThat(mBatteryDatabaseManager.insertAnomaly(uid, PACKAGE_SETTINGS, ANOMALY_TYPE, + AnomalyDatabaseHelper.State.NEW, now)).isFalse(); + + // In database, only contains one row + List newAppInfos = mBatteryDatabaseManager.queryAllAnomalies(0, + AnomalyDatabaseHelper.State.NEW); + assertThat(newAppInfos).containsExactly(new AppInfo.Builder() + .setUid(uid) + .setPackageName(PACKAGE_SETTINGS) + .addAnomalyType(ANOMALY_TYPE) + .build()); + } }