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.statusbar.notification.row.NotificationRowContentBinder.InflationFlag 25 import dagger.assisted.Assisted 26 import dagger.assisted.AssistedFactory 27 import dagger.assisted.AssistedInject 28 29 /** 30 * Implementation of [NotifLayoutInflaterFactory]. This class uses a set of 31 * [NotifRemoteViewsFactory] objects to create replacement views for Notification RemoteViews. 32 */ 33 class NotifLayoutInflaterFactory 34 @AssistedInject 35 constructor( 36 @Assisted private val row: ExpandableNotificationRow, 37 @Assisted @InflationFlag val layoutType: Int, 38 private val notifRemoteViewsFactoryContainer: NotifRemoteViewsFactoryContainer 39 ) : LayoutInflater.Factory2 { 40 onCreateViewnull41 override fun onCreateView( 42 parent: View?, 43 name: String, 44 context: Context, 45 attrs: AttributeSet 46 ): View? { 47 var handledFactory: NotifRemoteViewsFactory? = null 48 var result: View? = null 49 for (layoutFactory in notifRemoteViewsFactoryContainer.factories) { 50 layoutFactory.instantiate(row, layoutType, parent, name, context, attrs)?.run { 51 check(handledFactory == null) { 52 "$layoutFactory tries to produce name:$name with type:$layoutType. " + 53 "However, $handledFactory produced view for $name before." 54 } 55 handledFactory = layoutFactory 56 result = this 57 } 58 } 59 logOnCreateView(name, result, handledFactory) 60 return result 61 } 62 onCreateViewnull63 override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? = 64 onCreateView(null, name, context, attrs) 65 66 private fun logOnCreateView( 67 name: String, 68 replacedView: View?, 69 factory: NotifRemoteViewsFactory? 70 ) { 71 if (SPEW && replacedView != null && factory != null) { 72 Log.d(TAG, "$factory produced $replacedView for name:$name with type:$layoutType") 73 } 74 } 75 76 private companion object { 77 private const val TAG = "NotifLayoutInflaterFac" 78 private val SPEW = Log.isLoggable(TAG, Log.VERBOSE) 79 } 80 81 @AssistedFactory 82 interface Provider { providenull83 fun provide( 84 row: ExpandableNotificationRow, 85 @InflationFlag layoutType: Int 86 ): NotifLayoutInflaterFactory 87 } 88 } 89