1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.tools.traces.events 18 19 import android.tools.Timestamp 20 21 /** 22 * An Event from the [EventLog] representing a window focus change or request. 23 * 24 * @param timestamp The wall clock time in nanoseconds when the entry was written. 25 * @param window The window that is the target of the focus event. 26 * @param type The type of focus event this is. 27 * @param reason The reason for the focus event. 28 * @param processId The process ID which wrote the log entry 29 * @param uid The UID which wrote the log entry, special UIDs are strings instead of numbers (e.g. 30 * root) 31 * @param threadId The thread which wrote the log entry 32 * @param tag The type tag code of the entry 33 */ 34 class FocusEvent( 35 timestamp: Timestamp, 36 val window: String, 37 val type: Type, 38 val reason: String, 39 processId: Int, 40 uid: String, 41 threadId: Int 42 ) : Event(timestamp, processId, uid, threadId, INPUT_FOCUS_TAG) { 43 enum class Type { 44 GAINED, 45 LOST, 46 REQUESTED 47 } 48 toStringnull49 override fun toString(): String { 50 return "$timestamp: Focus ${type.name} $window Reason=$reason" 51 } 52 hasFocusnull53 fun hasFocus(): Boolean { 54 return this.type == Type.GAINED 55 } 56 57 companion object { fromnull58 fun from( 59 timestamp: Timestamp, 60 processId: Int, 61 uid: String, 62 threadId: Int, 63 data: Collection<String> 64 ) = 65 FocusEvent( 66 timestamp, 67 getWindowFromData(data.first()), 68 getFocusFromData(data.first()), 69 data.drop(1).first().removePrefix("reason="), 70 processId, 71 uid, 72 threadId 73 ) 74 75 private fun getWindowFromData(data: String): String { 76 var expectedWhiteSpace = 2 77 return data.dropWhile { !it.isWhitespace() || --expectedWhiteSpace > 0 }.drop(1) 78 } 79 getFocusFromDatanull80 private fun getFocusFromData(data: String): Type { 81 return when { 82 data.contains(" entering ") -> Type.GAINED 83 data.contains(" leaving ") -> Type.LOST 84 else -> Type.REQUESTED 85 } 86 } 87 88 const val INPUT_FOCUS_TAG = "input_focus" 89 } 90 } 91