• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.systemui.statusbar.notification.row
18 
19 import android.content.Context
20 import android.util.AttributeSet
21 import android.util.Log
22 import android.view.LayoutInflater
23 import android.view.View
24 import com.android.systemui.Dumpable
25 import com.android.systemui.dump.DumpManager
26 import com.android.systemui.statusbar.notification.row.NotificationRowModule.NOTIF_REMOTEVIEWS_FACTORIES
27 import com.android.systemui.util.asIndenting
28 import com.android.systemui.util.withIncreasedIndent
29 import java.io.PrintWriter
30 import javax.inject.Inject
31 import javax.inject.Named
32 
33 /**
34  * Implementation of [NotifLayoutInflaterFactory]. This class uses a set of
35  * [NotifRemoteViewsFactory] objects to create replacement views for Notification RemoteViews.
36  */
37 open class NotifLayoutInflaterFactory
38 @Inject
39 constructor(
40     dumpManager: DumpManager,
41     @Named(NOTIF_REMOTEVIEWS_FACTORIES)
42     private val remoteViewsFactories: Set<@JvmSuppressWildcards NotifRemoteViewsFactory>
43 ) : LayoutInflater.Factory2, Dumpable {
44     init {
45         dumpManager.registerNormalDumpable(TAG, this)
46     }
47 
onCreateViewnull48     override fun onCreateView(
49         parent: View?,
50         name: String,
51         context: Context,
52         attrs: AttributeSet
53     ): View? {
54         var view: View? = null
55         var handledFactory: NotifRemoteViewsFactory? = null
56         for (layoutFactory in remoteViewsFactories) {
57             view = layoutFactory.instantiate(parent, name, context, attrs)
58             if (view != null) {
59                 check(handledFactory == null) {
60                     "${layoutFactory.javaClass.name} tries to produce view. However, " +
61                         "${handledFactory?.javaClass?.name} produced view for $name before."
62                 }
63                 handledFactory = layoutFactory
64             }
65         }
66         logOnCreateView(name, view, handledFactory)
67         return view
68     }
69 
onCreateViewnull70     override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? =
71         onCreateView(null, name, context, attrs)
72 
73     override fun dump(pw: PrintWriter, args: Array<out String>) {
74         val indentingPW = pw.asIndenting()
75 
76         indentingPW.appendLine("$TAG ReplacementFactories:")
77         indentingPW.withIncreasedIndent {
78             remoteViewsFactories.forEach { indentingPW.appendLine(it.javaClass.simpleName) }
79         }
80     }
81 
logOnCreateViewnull82     private fun logOnCreateView(
83         name: String,
84         replacedView: View?,
85         factory: NotifRemoteViewsFactory?
86     ) {
87         if (SPEW && replacedView != null && factory != null) {
88             Log.d(TAG, "$factory produced view for $name: $replacedView")
89         }
90     }
91 
92     private companion object {
93         private const val TAG = "NotifLayoutInflaterFac"
94         private val SPEW = Log.isLoggable(TAG, Log.VERBOSE)
95     }
96 }
97