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 package com.android.healthconnect.controller.shared.preference
17 
18 import android.content.Context
19 import android.view.View
20 import android.view.View.OnClickListener
21 import android.widget.Button
22 import android.widget.ImageView
23 import android.widget.TextView
24 import androidx.preference.Preference
25 import androidx.preference.PreferenceViewHolder
26 import com.android.healthconnect.controller.R
27 import com.android.healthconnect.controller.utils.logging.ElementName
28 import com.android.healthconnect.controller.utils.logging.ErrorPageElement
29 import com.android.healthconnect.controller.utils.logging.HealthConnectLogger
30 import com.android.healthconnect.controller.utils.logging.HealthConnectLoggerEntryPoint
31 import dagger.hilt.android.EntryPointAccessors
32 
33 /** Preference for displaying a banner with optional action and dismiss buttons. */
34 class BannerPreference constructor(context: Context, private val logName: ElementName) :
35     Preference(context) {
36 
37     private var logger: HealthConnectLogger
38 
39     private lateinit var bannerIcon: ImageView
40     private lateinit var bannerTitle: TextView
41     private lateinit var bannerMessage: TextView
42     private lateinit var bannerPrimaryButton: Button
43     private lateinit var bannerSecondaryButton: Button
44 
45     private var dismissButton: ImageView? = null
46 
47     private var buttonPrimaryText: String? = null
48     private var buttonPrimaryAction: OnClickListener? = null
49     private var buttonPrimaryVisibility = View.VISIBLE
50     private var buttonPrimaryLogName: ElementName = ErrorPageElement.UNKNOWN_ELEMENT
51 
52     private var buttonSecondaryText: String? = null
53     private var buttonSecondaryAction: OnClickListener? = null
54     private var buttonSecondaryVisibility = View.VISIBLE
55     private var buttonSecondaryLogName: ElementName = ErrorPageElement.UNKNOWN_ELEMENT
56 
57     private var isDismissable = false
58     private var dismissAction: OnClickListener? = null
59     private var dismissActionLogName: ElementName = ErrorPageElement.UNKNOWN_ELEMENT
60 
61     init {
62         layoutResource = R.layout.widget_banner_preference
63         isSelectable = false
64 
65         val hiltEntryPoint =
66             EntryPointAccessors.fromApplication(
67                 context.applicationContext, HealthConnectLoggerEntryPoint::class.java)
68         logger = hiltEntryPoint.logger()
69     }
70 
setPrimaryButtonnull71     fun setPrimaryButton(buttonText: String, logName: ElementName) {
72         this.buttonPrimaryText = buttonText
73         this.buttonPrimaryLogName = logName
74     }
75 
setPrimaryButtonOnClickListenernull76     fun setPrimaryButtonOnClickListener(onClickListener: OnClickListener?) {
77         logger.logInteraction(buttonPrimaryLogName)
78         this.buttonPrimaryAction = onClickListener
79     }
80 
setPrimaryButtonVisibilitynull81     fun setPrimaryButtonVisibility(visibility: Int) {
82         this.buttonPrimaryVisibility = visibility
83     }
84 
setSecondaryButtonnull85     fun setSecondaryButton(buttonText: String, logName: ElementName) {
86         this.buttonSecondaryText = buttonText
87         this.buttonSecondaryLogName = logName
88     }
89 
setSecondaryButtonOnClickListenernull90     fun setSecondaryButtonOnClickListener(onClickListener: OnClickListener?) {
91         logger.logInteraction(buttonSecondaryLogName)
92         this.buttonSecondaryAction = onClickListener
93     }
94 
setSecondaryButtonVisibilitynull95     fun setSecondaryButtonVisibility(visibility: Int) {
96         this.buttonSecondaryVisibility = visibility
97     }
98 
setIsDismissablenull99     fun setIsDismissable(isDismissable: Boolean) {
100         this.isDismissable = isDismissable
101     }
102 
setDismissActionnull103     fun setDismissAction(logName: ElementName, onClickListener: OnClickListener?) {
104         dismissActionLogName = logName
105         logger.logInteraction(dismissActionLogName)
106         this.dismissAction = onClickListener
107     }
108 
onBindViewHoldernull109     override fun onBindViewHolder(holder: PreferenceViewHolder) {
110         super.onBindViewHolder(holder)
111         bannerIcon = holder.findViewById(R.id.banner_icon) as ImageView
112         bannerTitle = holder.findViewById(R.id.banner_title) as TextView
113         bannerMessage = holder.findViewById(R.id.banner_message) as TextView
114         bannerPrimaryButton = holder.findViewById(R.id.banner_primary_button) as Button
115         bannerSecondaryButton = holder.findViewById(R.id.banner_secondary_button) as Button
116 
117         bannerTitle.text = title
118         bannerMessage.text = summary
119         bannerIcon.background = icon
120 
121         // set button text and visibility
122         buttonPrimaryText?.let {
123             bannerPrimaryButton.text = it
124             bannerPrimaryButton.visibility = View.VISIBLE
125             bannerPrimaryButton.setOnClickListener(buttonPrimaryAction)
126         }
127 
128         buttonSecondaryText?.let {
129             bannerSecondaryButton.text = it
130             bannerSecondaryButton.visibility = View.VISIBLE
131             bannerSecondaryButton.setOnClickListener(buttonSecondaryAction)
132         }
133 
134         bannerPrimaryButton.visibility = buttonPrimaryVisibility
135         bannerSecondaryButton.visibility = buttonSecondaryVisibility
136 
137         if (buttonPrimaryVisibility == View.VISIBLE) {
138             logger.logImpression(buttonPrimaryLogName)
139         }
140 
141         if (buttonSecondaryVisibility == View.VISIBLE) {
142             logger.logImpression(buttonSecondaryLogName)
143         }
144 
145         if (isDismissable) {
146             dismissButton = holder.findViewById(R.id.dismiss_button) as ImageView
147             dismissButton?.visibility = View.VISIBLE
148             logger.logImpression(dismissActionLogName)
149             dismissButton?.setOnClickListener(dismissAction)
150         }
151     }
152 
onAttachednull153     override fun onAttached() {
154         super.onAttached()
155         logger.logImpression(logName)
156     }
157 }
158