summaryrefslogtreecommitdiff
path: root/src/com/android/launcher3/util/EventLogArray.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/util/EventLogArray.kt')
-rw-r--r--src/com/android/launcher3/util/EventLogArray.kt117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/com/android/launcher3/util/EventLogArray.kt b/src/com/android/launcher3/util/EventLogArray.kt
new file mode 100644
index 0000000000..a17d6509e3
--- /dev/null
+++ b/src/com/android/launcher3/util/EventLogArray.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023 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.launcher3.util
+
+import java.io.PrintWriter
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+
+/**
+ * A utility class to record and log events. Events are stored in a fixed size array and old logs
+ * are purged as new events come.
+ */
+class EventLogArray(private val name: String, size: Int) {
+
+ companion object {
+ private const val TYPE_ONE_OFF = 0
+ private const val TYPE_FLOAT = 1
+ private const val TYPE_INTEGER = 2
+ private const val TYPE_BOOL_TRUE = 3
+ private const val TYPE_BOOL_FALSE = 4
+ private fun isEntrySame(entry: EventEntry?, type: Int, event: String): Boolean {
+ return entry != null && entry.type == type && entry.event == event
+ }
+ }
+
+ private val logs: Array<EventEntry?>
+ private var nextIndex = 0
+
+ init {
+ logs = arrayOfNulls(size)
+ }
+
+ fun addLog(event: String) {
+ addLog(TYPE_ONE_OFF, event, 0f)
+ }
+
+ fun addLog(event: String, extras: Int) {
+ addLog(TYPE_INTEGER, event, extras.toFloat())
+ }
+
+ fun addLog(event: String, extras: Float) {
+ addLog(TYPE_FLOAT, event, extras)
+ }
+
+ fun addLog(event: String, extras: Boolean) {
+ addLog(if (extras) TYPE_BOOL_TRUE else TYPE_BOOL_FALSE, event, 0f)
+ }
+
+ private fun addLog(type: Int, event: String, extras: Float) {
+ // Merge the logs if it's a duplicate
+ val last = (nextIndex + logs.size - 1) % logs.size
+ val secondLast = (nextIndex + logs.size - 2) % logs.size
+ if (isEntrySame(logs[last], type, event) && isEntrySame(logs[secondLast], type, event)) {
+ logs[last]!!.update(type, event, extras)
+ logs[secondLast]!!.duplicateCount++
+ return
+ }
+ if (logs[nextIndex] == null) {
+ logs[nextIndex] = EventEntry()
+ }
+ logs[nextIndex]!!.update(type, event, extras)
+ nextIndex = (nextIndex + 1) % logs.size
+ }
+
+ fun dump(prefix: String, writer: PrintWriter) {
+ writer.println("$prefix$name event history:")
+ val sdf = SimpleDateFormat(" HH:mm:ss.SSSZ ", Locale.US)
+ val date = Date()
+ for (i in logs.indices) {
+ val log = logs[(nextIndex + logs.size - i - 1) % logs.size] ?: continue
+ date.time = log.time
+ val msg = StringBuilder(prefix).append(sdf.format(date)).append(log.event)
+ when (log.type) {
+ TYPE_BOOL_FALSE -> msg.append(": false")
+ TYPE_BOOL_TRUE -> msg.append(": true")
+ TYPE_FLOAT -> msg.append(": ").append(log.extras)
+ TYPE_INTEGER -> msg.append(": ").append(log.extras.toInt())
+ else -> {}
+ }
+ if (log.duplicateCount > 0) {
+ msg.append(" & ").append(log.duplicateCount).append(" similar events")
+ }
+ writer.println(msg)
+ }
+ }
+
+ /** A single event entry. */
+ private class EventEntry {
+ var type = 0
+ var event: String? = null
+ var extras = 0f
+ var time: Long = 0
+ var duplicateCount = 0
+ fun update(type: Int, event: String, extras: Float) {
+ this.type = type
+ this.event = event
+ this.extras = extras
+ time = System.currentTimeMillis()
+ duplicateCount = 0
+ }
+ }
+}