1 /*
2  * Copyright (C) 2024 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.app.viewcapture
18 
19 import android.content.Context
20 import android.os.Process
21 import android.tracing.Flags
22 import android.util.Log
23 import android.view.WindowManager
24 
25 /**
26  * Factory to create polymorphic instances of ViewCapture according to build configurations and
27  * flags.
28  */
29 object ViewCaptureFactory {
30     private val TAG = ViewCaptureFactory::class.java.simpleName
<lambda>null31     private val instance: ViewCapture by lazy { createInstance() }
32     private lateinit var appContext: Context
33 
createInstancenull34     private fun createInstance(): ViewCapture {
35         return when {
36             !android.os.Build.IS_DEBUGGABLE -> {
37                 Log.i(TAG, "instantiating ${NoOpViewCapture::class.java.simpleName}")
38                 NoOpViewCapture()
39             }
40             !Flags.perfettoViewCaptureTracing() -> {
41                 Log.i(TAG, "instantiating ${SettingsAwareViewCapture::class.java.simpleName}")
42                 SettingsAwareViewCapture(
43                     appContext,
44                     ViewCapture.createAndStartNewLooperExecutor(
45                         "SAViewCapture",
46                         Process.THREAD_PRIORITY_FOREGROUND,
47                     ),
48                 )
49             }
50             else -> {
51                 Log.i(TAG, "instantiating ${PerfettoViewCapture::class.java.simpleName}")
52                 PerfettoViewCapture(
53                     appContext,
54                     ViewCapture.createAndStartNewLooperExecutor(
55                         "PerfettoViewCapture",
56                         Process.THREAD_PRIORITY_FOREGROUND,
57                     ),
58                 )
59             }
60         }
61     }
62 
63     /** Returns an instance of [ViewCapture]. */
64     @JvmStatic
getInstancenull65     fun getInstance(context: Context): ViewCapture {
66         if (!this::appContext.isInitialized) {
67             synchronized(this) { appContext = context.applicationContext }
68         }
69         return instance
70     }
71 
72     /** Returns an instance of [ViewCaptureAwareWindowManager]. */
73     @JvmStatic
getViewCaptureAwareWindowManagerInstancenull74     fun getViewCaptureAwareWindowManagerInstance(
75         context: Context,
76         isViewCaptureTracingEnabled: Boolean,
77     ): ViewCaptureAwareWindowManager {
78         val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
79         val lazyViewCapture = lazy { getInstance(context) }
80         return ViewCaptureAwareWindowManager(
81             windowManager,
82             lazyViewCapture,
83             isViewCaptureTracingEnabled,
84         )
85     }
86 }
87