1 /*
2  * Copyright (C) 2022 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 com.android.systemui.log.table
18 
19 import com.android.systemui.dagger.SysUISingleton
20 import com.android.systemui.dagger.qualifiers.Application
21 import com.android.systemui.dagger.qualifiers.Background
22 import com.android.systemui.dump.DumpManager
23 import com.android.systemui.log.LogBufferHelper.Companion.adjustMaxSize
24 import com.android.systemui.log.LogcatEchoTracker
25 import com.android.systemui.util.time.SystemClock
26 import javax.inject.Inject
27 import kotlinx.coroutines.CoroutineDispatcher
28 import kotlinx.coroutines.CoroutineScope
29 
30 @SysUISingleton
31 class TableLogBufferFactory
32 @Inject
33 constructor(
34     private val dumpManager: DumpManager,
35     private val systemClock: SystemClock,
36     private val logcatEchoTracker: LogcatEchoTracker,
37     @Background private val bgDispatcher: CoroutineDispatcher,
38     @Application private val coroutineScope: CoroutineScope,
39 ) {
40     private val existingBuffers = mutableMapOf<String, TableLogBuffer>()
41 
42     /**
43      * Creates a new [TableLogBuffer]. This method should only be called from static contexts, where
44      * it is guaranteed only to be created one time. See [getOrCreate] for a cache-aware method of
45      * obtaining a buffer.
46      *
47      * @param name a unique table name
48      * @param maxSize the buffer max size. See [adjustMaxSize]
49      * @return a new [TableLogBuffer] registered with [DumpManager]
50      */
createnull51     fun create(
52         name: String,
53         maxSize: Int,
54     ): TableLogBuffer {
55         val tableBuffer =
56             TableLogBuffer(
57                 adjustMaxSize(maxSize),
58                 name,
59                 systemClock,
60                 logcatEchoTracker,
61                 bgDispatcher,
62                 coroutineScope,
63             )
64         dumpManager.registerTableLogBuffer(name, tableBuffer)
65         return tableBuffer
66     }
67 
68     /**
69      * Log buffers are retained indefinitely by [DumpManager], so that they can be represented in
70      * bugreports. Because of this, many of them are created statically in the Dagger graph.
71      *
72      * In the case where you have to create a logbuffer with a name only known at runtime, this
73      * method can be used to lazily create a table log buffer which is then cached for reuse.
74      *
75      * @return a [TableLogBuffer] suitable for reuse
76      */
getOrCreatenull77     fun getOrCreate(
78         name: String,
79         maxSize: Int,
80     ): TableLogBuffer =
81         existingBuffers.getOrElse(name) {
82             val buffer = create(name, maxSize)
83             existingBuffers[name] = buffer
84             buffer
85         }
86 }
87