• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.healthconnect.controller.recentaccess
18 
19 import android.content.Context
20 import android.widget.ImageView
21 import android.widget.TextView
22 import androidx.core.view.isVisible
23 import androidx.preference.Preference
24 import androidx.preference.PreferenceViewHolder
25 import com.android.healthconnect.controller.R
26 import com.android.healthconnect.controller.permissions.connectedapps.ComparablePreference
27 import com.android.healthconnect.controller.shared.preference.HealthPreference
28 import com.android.healthconnect.controller.utils.TimeSource
29 import com.android.healthconnect.controller.utils.formatRecentAccessTime
30 import com.android.healthconnect.controller.utils.logging.RecentAccessElement
31 
32 /** Custom preference for displaying Recent access apps, including dash lines for timeline views. */
33 class RecentAccessPreference(
34     context: Context,
35     private val recentAccessEntry: RecentAccessEntry,
36     private val timeSource: TimeSource,
37     private val showCategories: Boolean,
38 ) : HealthPreference(context), ComparablePreference {
39 
<lambda>null40     private val separator: String by lazy { context.getString(R.string.separator) }
41 
42     init {
43         layoutResource = R.layout.widget_recent_access_timeline
44         isSelectable = true
45         this.logName = RecentAccessElement.RECENT_ACCESS_ENTRY_BUTTON
46     }
47 
onBindViewHoldernull48     override fun onBindViewHolder(holder: PreferenceViewHolder) {
49         super.onBindViewHolder(holder)
50 
51         val appIcon = holder.findViewById(R.id.recent_access_app_icon) as ImageView
52         appIcon.setImageDrawable(recentAccessEntry.metadata.icon)
53 
54         val appTitle = holder.findViewById(R.id.title) as TextView
55         appTitle.text = recentAccessEntry.metadata.appName
56 
57         val dataTypesWritten = holder.findViewById(R.id.data_types_written) as TextView
58         if (showCategories && recentAccessEntry.dataTypesWritten.isNotEmpty()) {
59             dataTypesWritten.text = getWrittenText()
60             dataTypesWritten.isVisible = true
61         } else {
62             dataTypesWritten.isVisible = false
63         }
64 
65         val dataTypesRead = holder.findViewById(R.id.data_types_read) as TextView
66         if (showCategories && recentAccessEntry.dataTypesRead.isNotEmpty()) {
67             dataTypesRead.text = getReadText()
68             dataTypesRead.isVisible = true
69         } else {
70             dataTypesRead.isVisible = false
71         }
72 
73         val accessTime = holder.findViewById(R.id.time) as TextView
74         val formattedTime =
75             formatRecentAccessTime(recentAccessEntry.instantTime, timeSource, context)
76         accessTime.text = formattedTime
77         accessTime.contentDescription =
78             context.getString(R.string.recent_access_time_content_descritption, formattedTime)
79     }
80 
isSameItemnull81     override fun isSameItem(preference: Preference): Boolean {
82         return preference is RecentAccessPreference && this == preference
83     }
84 
hasSameContentsnull85     override fun hasSameContents(preference: Preference): Boolean {
86         return preference is RecentAccessPreference &&
87             this.recentAccessEntry == preference.recentAccessEntry
88     }
89 
getWrittenTextnull90     private fun getWrittenText(): String {
91         val sortedDataTypes = sortWithHealthRecordsFirst(recentAccessEntry.dataTypesWritten)
92         return context.getString(
93             R.string.write_data_access_label,
94             sortedDataTypes.joinToString(separator),
95         )
96     }
97 
getReadTextnull98     private fun getReadText(): String {
99         val sortedDataTypes = sortWithHealthRecordsFirst(recentAccessEntry.dataTypesRead)
100         return context.getString(
101             R.string.read_data_access_label,
102             sortedDataTypes.joinToString(separator),
103         )
104     }
105 
sortWithHealthRecordsFirstnull106     private fun sortWithHealthRecordsFirst(dataTypes: MutableSet<Int>): List<String> {
107         val sortedList = dataTypes.map { context.getString(it) }.sorted().toMutableList()
108 
109         val healthRecordsString = context.getString(R.string.medical_permissions)
110         if (sortedList.contains(healthRecordsString)) {
111             sortedList.remove(healthRecordsString)
112             sortedList.add(0, healthRecordsString)
113         }
114 
115         return sortedList
116     }
117 }
118