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.logging.RecentAccessElement 29 import java.time.Instant 30 import java.time.LocalTime 31 import java.time.ZoneId 32 import java.time.format.DateTimeFormatter 33 34 /** Custom preference for displaying Recent access apps, including dash lines for timeline views. */ 35 class RecentAccessPreference 36 constructor( 37 context: Context, 38 private val recentAccessApp: RecentAccessEntry, 39 private val showCategories: Boolean 40 ) : HealthPreference(context), ComparablePreference { 41 42 private lateinit var appIcon: ImageView 43 private lateinit var appTitle: TextView 44 private lateinit var dataTypesWritten: TextView 45 private lateinit var dataTypesRead: TextView 46 private lateinit var accessTime: TextView 47 private val separator: String = context.getString(R.string.data_type_separator) 48 49 private val appName = recentAccessApp.metadata.appName 50 private val writtenText: String = 51 context.getString( 52 R.string.write_data_access_label, <lambda>null53 recentAccessApp.dataTypesWritten.sorted().joinToString(separator) { 54 context.getString(it) 55 }) 56 private val readText: String = 57 context.getString( 58 R.string.read_data_access_label, <lambda>null59 recentAccessApp.dataTypesRead.sorted().joinToString(separator) { 60 context.getString(it) 61 }) 62 private val formattedTime = formatTime(recentAccessApp.instantTime) 63 // Used to compare this preference to other RecentAccessPreferences 64 val comparableTitle = "${formattedTime}_${appName}_${writtenText}_${readText}" 65 66 init { 67 layoutResource = R.layout.widget_recent_access_timeline 68 isSelectable = true 69 this.logName = RecentAccessElement.RECENT_ACCESS_ENTRY_BUTTON 70 } 71 onBindViewHoldernull72 override fun onBindViewHolder(holder: PreferenceViewHolder) { 73 super.onBindViewHolder(holder) 74 75 appIcon = holder.findViewById(R.id.recent_access_app_icon) as ImageView 76 appIcon.setImageDrawable(recentAccessApp.metadata.icon) 77 78 appTitle = holder.findViewById(R.id.title) as TextView 79 appTitle.text = appName 80 81 dataTypesWritten = holder.findViewById(R.id.data_types_written) as TextView 82 dataTypesRead = holder.findViewById(R.id.data_types_read) as TextView 83 84 if (showCategories) { 85 if (recentAccessApp.dataTypesWritten.isNotEmpty()) { 86 dataTypesWritten.text = writtenText 87 dataTypesWritten.isVisible = true 88 } 89 90 if (recentAccessApp.dataTypesRead.isNotEmpty()) { 91 dataTypesRead.text = readText 92 dataTypesRead.isVisible = true 93 } 94 } 95 96 accessTime = holder.findViewById(R.id.time) as TextView 97 accessTime.text = formattedTime 98 } 99 isSameItemnull100 override fun isSameItem(preference: Preference): Boolean { 101 return preference is RecentAccessPreference && this == preference 102 } 103 hasSameContentsnull104 override fun hasSameContents(preference: Preference): Boolean { 105 return preference is RecentAccessPreference && 106 this.recentAccessApp == preference.recentAccessApp 107 } 108 formatTimenull109 private fun formatTime(instant: Instant): String { 110 val localTime: LocalTime = instant.atZone(ZoneId.systemDefault()).toLocalTime() 111 return localTime.format(DateTimeFormatter.ofPattern("HH:mm")) 112 } 113 } 114