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.bouncer.ui.binder
18 
19 import android.text.TextUtils
20 import android.util.PluralsMessageFormatter
21 import androidx.lifecycle.Lifecycle
22 import androidx.lifecycle.repeatOnLifecycle
23 import com.android.keyguard.BouncerKeyguardMessageArea
24 import com.android.keyguard.KeyguardMessageArea
25 import com.android.keyguard.KeyguardMessageAreaController
26 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
27 import com.android.systemui.bouncer.shared.model.Message
28 import com.android.systemui.bouncer.ui.BouncerMessageView
29 import com.android.systemui.flags.FeatureFlags
30 import com.android.systemui.flags.Flags
31 import com.android.systemui.lifecycle.repeatWhenAttached
32 import com.android.systemui.log.BouncerLogger
33 import kotlinx.coroutines.launch
34 
35 object BouncerMessageViewBinder {
36     @JvmStatic
37     fun bind(
38         view: BouncerMessageView,
39         interactor: BouncerMessageInteractor,
40         factory: KeyguardMessageAreaController.Factory,
41         bouncerLogger: BouncerLogger,
42         featureFlags: FeatureFlags
43     ) {
44         view.repeatWhenAttached {
45             if (!featureFlags.isEnabled(Flags.REVAMPED_BOUNCER_MESSAGES)) {
46                 view.primaryMessageView?.disable()
47                 view.secondaryMessageView?.disable()
48                 return@repeatWhenAttached
49             }
50             view.init(factory)
51             view.primaryMessage?.setIsVisible(true)
52             view.secondaryMessage?.setIsVisible(true)
53             repeatOnLifecycle(Lifecycle.State.STARTED) {
54                 bouncerLogger.startBouncerMessageInteractor()
55                 launch {
56                     interactor.bouncerMessage.collect {
57                         bouncerLogger.bouncerMessageUpdated(it)
58                         updateView(
59                             view.primaryMessage,
60                             view.primaryMessageView,
61                             message = it?.message,
62                             allowTruncation = true,
63                         )
64                         updateView(
65                             view.secondaryMessage,
66                             view.secondaryMessageView,
67                             message = it?.secondaryMessage,
68                             allowTruncation = false,
69                         )
70                         view.requestLayout()
71                     }
72                 }
73             }
74         }
75     }
76 
77     private fun updateView(
78         controller: KeyguardMessageAreaController<KeyguardMessageArea>?,
79         view: BouncerKeyguardMessageArea?,
80         message: Message?,
81         allowTruncation: Boolean = false,
82     ) {
83         if (view == null || controller == null) return
84         if (message?.message != null || message?.messageResId != null) {
85             controller.setIsVisible(true)
86             var newMessage = message.message ?: ""
87             if (message.messageResId != null && message.messageResId != 0) {
88                 newMessage = view.resources.getString(message.messageResId)
89                 if (message.formatterArgs != null) {
90                     newMessage =
91                         PluralsMessageFormatter.format(
92                             view.resources,
93                             message.formatterArgs,
94                             message.messageResId
95                         )
96                 }
97             }
98             controller.setMessage(newMessage, message.animate)
99         } else {
100             controller.setIsVisible(false)
101             controller.setMessage(0)
102         }
103         message?.colorState?.let { controller.setNextMessageColor(it) }
104         view.ellipsize =
105             if (allowTruncation) TextUtils.TruncateAt.END else TextUtils.TruncateAt.MARQUEE
106     }
107 }
108