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 package com.android.healthconnect.controller.autodelete 17 18 import android.content.Context 19 import android.icu.text.MessageFormat 20 import android.os.Bundle 21 import android.view.LayoutInflater 22 import android.view.View 23 import android.view.ViewGroup 24 import android.widget.LinearLayout 25 import android.widget.RadioButton 26 import android.widget.RadioGroup 27 import androidx.core.os.bundleOf 28 import androidx.core.view.children 29 import androidx.fragment.app.FragmentManager 30 import androidx.preference.Preference 31 import androidx.preference.PreferenceViewHolder 32 import com.android.healthconnect.controller.R 33 import com.android.healthconnect.controller.utils.logging.AutoDeleteElement 34 import com.android.healthconnect.controller.utils.logging.ErrorPageElement 35 import com.android.healthconnect.controller.utils.logging.HealthConnectLogger 36 37 /** 38 * Custom preference for displaying a custom dialog where the user can confirm the auto-delete range 39 * update. 40 */ 41 class AutoDeleteRangePickerPreference 42 constructor( 43 context: Context, 44 private val childFragmentManager: FragmentManager, 45 private var autoDeleteRange: AutoDeleteRange, 46 private val logger: HealthConnectLogger 47 ) : Preference(context), RadioGroup.OnCheckedChangeListener { 48 49 companion object { 50 const val SET_TO_NEVER_EVENT = "SET_TO_NEVER_EVENT" 51 const val AUTO_DELETE_RANGE_PICKER_PREFERENCE_KEY = "auto_delete_range_picker" 52 } 53 54 init { 55 key = AUTO_DELETE_RANGE_PICKER_PREFERENCE_KEY 56 } 57 onBindViewHoldernull58 override fun onBindViewHolder(holder: PreferenceViewHolder) { 59 super.onBindViewHolder(holder) 60 61 val widgetFrame: ViewGroup = holder.findViewById(android.R.id.widget_frame) as ViewGroup 62 val widgetFrameParent: LinearLayout = widgetFrame.parent as LinearLayout 63 64 val iconFrame: LinearLayout? = holder.findViewById(android.R.id.icon_frame) as LinearLayout? 65 widgetFrameParent.removeView(iconFrame) 66 67 var autoDeleteWidget: ViewGroup? = 68 holder.findViewById(R.id.auto_delete_range_picker_layout) as ViewGroup? 69 if (autoDeleteWidget == null) { 70 val inflater: LayoutInflater = context.getSystemService(LayoutInflater::class.java) 71 autoDeleteWidget = 72 inflater.inflate(R.layout.widget_auto_delete_range_picker, widgetFrameParent, false) 73 as ViewGroup? 74 widgetFrameParent.addView(autoDeleteWidget, 0) 75 widgetFrameParent.isFocusable = false 76 widgetFrameParent.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO 77 } 78 79 val radioGroup: RadioGroup = holder.findViewById(R.id.radio_group_time_range) as RadioGroup 80 setRadioButtonTexts(radioGroup) 81 82 setRadioButtonLogging(radioGroup) 83 84 radioGroup.setOnCheckedChangeListener(null) 85 setCheckedRadioButton(radioGroup, autoDeleteRange) 86 radioGroup.setOnCheckedChangeListener(this) 87 } 88 setRadioButtonLoggingnull89 private fun setRadioButtonLogging(radioGroup: RadioGroup) { 90 radioGroup.children.forEach { 91 val element = 92 when (it.id) { 93 R.id.radio_button_3_months -> AutoDeleteElement.AUTO_DELETE_3_MONTHS_BUTTON 94 R.id.radio_button_18_months -> AutoDeleteElement.AUTO_DELETE_18_MONTHS_BUTTON 95 R.id.radio_button_never -> AutoDeleteElement.AUTO_DELETE_NEVER_BUTTON 96 else -> ErrorPageElement.UNKNOWN_ELEMENT 97 } 98 99 it.setOnClickListener { logger.logInteraction(element) } 100 101 logger.logImpression(element) 102 } 103 } 104 setRadioButtonTextsnull105 private fun setRadioButtonTexts(radioGroup: RadioGroup) { 106 val radioButton3Months: RadioButton = radioGroup.findViewById(R.id.radio_button_3_months) 107 var count = AutoDeleteRange.AUTO_DELETE_RANGE_THREE_MONTHS.numberOfMonths 108 radioButton3Months.text = 109 MessageFormat.format( 110 context.getString(R.string.range_after_x_months), mapOf("count" to count)) 111 112 val radioButton18Months: RadioButton = radioGroup.findViewById(R.id.radio_button_18_months) 113 count = AutoDeleteRange.AUTO_DELETE_RANGE_EIGHTEEN_MONTHS.numberOfMonths 114 radioButton18Months.text = 115 MessageFormat.format( 116 context.getString(R.string.range_after_x_months), mapOf("count" to count)) 117 } 118 setCheckedRadioButtonnull119 private fun setCheckedRadioButton(radioGroup: RadioGroup, autoDeleteRange: AutoDeleteRange) { 120 when (autoDeleteRange) { 121 AutoDeleteRange.AUTO_DELETE_RANGE_NEVER -> radioGroup.check(R.id.radio_button_never) 122 AutoDeleteRange.AUTO_DELETE_RANGE_THREE_MONTHS -> 123 radioGroup.check(R.id.radio_button_3_months) 124 AutoDeleteRange.AUTO_DELETE_RANGE_EIGHTEEN_MONTHS -> 125 radioGroup.check(R.id.radio_button_18_months) 126 } 127 } 128 setToNeverOrAskConfirmationnull129 private fun setToNeverOrAskConfirmation(chosenId: Int) { 130 if (chosenId == R.id.radio_button_never) { 131 childFragmentManager.setFragmentResult(SET_TO_NEVER_EVENT, Bundle()) 132 return 133 } 134 val newAutoDeleteRange: AutoDeleteRange = 135 if (chosenId == R.id.radio_button_3_months) 136 AutoDeleteRange.AUTO_DELETE_RANGE_THREE_MONTHS 137 else AutoDeleteRange.AUTO_DELETE_RANGE_EIGHTEEN_MONTHS 138 childFragmentManager.setFragmentResult( 139 AutoDeleteConfirmationDialogFragment.AUTO_DELETE_CONFIRMATION_DIALOG_EVENT, 140 bundleOf( 141 AutoDeleteConfirmationDialogFragment.NEW_AUTO_DELETE_RANGE_BUNDLE to 142 newAutoDeleteRange, 143 AutoDeleteConfirmationDialogFragment.OLD_AUTO_DELETE_RANGE_BUNDLE to 144 autoDeleteRange)) 145 } 146 onCheckedChangednull147 override fun onCheckedChanged(radioGroup: RadioGroup, checkedId: Int) { 148 setToNeverOrAskConfirmation(checkedId) 149 } 150 updateAutoDeleteRangenull151 fun updateAutoDeleteRange(newAutoDeleteRange: AutoDeleteRange) { 152 autoDeleteRange = newAutoDeleteRange 153 notifyChanged() 154 } 155 } 156