diff options
Diffstat (limited to 'src/com/android/launcher3/util/EventLogArray.kt')
-rw-r--r-- | src/com/android/launcher3/util/EventLogArray.kt | 117 |
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 + } + } +} |