Merge "Fix recording of battery history tags" into tm-dev
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3f87de2..b03a8cb 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -167,7 +167,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    static final int VERSION = 207;
+    static final int VERSION = 208;
 
     // The maximum number of names wakelocks we will keep track of
     // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -3981,8 +3981,7 @@
         if (idxObj != null) {
             idx = idxObj;
             if ((idx & TAG_FIRST_OCCURRENCE_FLAG) != 0) {
-                idx &= ~TAG_FIRST_OCCURRENCE_FLAG;
-                mHistoryTagPool.put(tag, idx);
+                mHistoryTagPool.put(tag, idx & ~TAG_FIRST_OCCURRENCE_FLAG);
             }
             return idx;
         } else if (mNextHistoryTagIdx < HISTORY_TAG_INDEX_LIMIT) {
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
index 2262c05..3858792 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
@@ -35,6 +35,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@SuppressWarnings("GuardedBy")
 public class BatteryStatsHistoryIteratorTest {
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
@@ -124,7 +125,10 @@
         // More than 32k strings
         final int eventCount = 0x7FFF + 100;
         for (int i = 0; i < eventCount; i++) {
-            mBatteryStats.noteAlarmStartLocked("a" + i, null, APP_UID, 3_000_000, 2_000_000);
+            // Names repeat in order to verify de-duping of identical history tags.
+            String name = "a" + (i % 10);
+            mBatteryStats.noteAlarmStartLocked(name, null, APP_UID, 3_000_000, 2_000_000);
+            mBatteryStats.noteAlarmFinishLocked(name, null, APP_UID, 3_500_000, 2_500_000);
         }
 
         final BatteryStatsHistoryIterator iterator =
@@ -149,10 +153,23 @@
         assertThat(item.time).isEqualTo(2_000_000);
 
         for (int i = 0; i < eventCount; i++) {
+            String name = "a" + (i % 10);
             assertThat(iterator.next(item)).isTrue();
+            // Skip a blank event inserted at the start of every buffer
+            if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) {
+                assertThat(iterator.next(item)).isTrue();
+            }
             assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM
                     | BatteryStats.HistoryItem.EVENT_FLAG_START);
-            assertThat(item.eventTag.string).isEqualTo("a" + i);
+            assertThat(item.eventTag.string).isEqualTo(name);
+
+            assertThat(iterator.next(item)).isTrue();
+            if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) {
+                assertThat(iterator.next(item)).isTrue();
+            }
+            assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM
+                    | BatteryStats.HistoryItem.EVENT_FLAG_FINISH);
+            assertThat(item.eventTag.string).isEqualTo(name);
         }
 
         assertThat(iterator.next(item)).isFalse();