1 /** <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * ``` 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * ``` 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package com.android.healthconnect.controller.deletion 17 18 import android.app.Dialog 19 import android.os.Bundle 20 import android.view.View 21 import android.widget.RadioGroup 22 import android.widget.TextView 23 import androidx.core.view.children 24 import androidx.fragment.app.DialogFragment 25 import androidx.fragment.app.activityViewModels 26 import androidx.fragment.app.setFragmentResult 27 import com.android.healthconnect.controller.R 28 import com.android.healthconnect.controller.deletion.DeletionConstants.TIME_RANGE_SELECTION_EVENT 29 import com.android.healthconnect.controller.shared.dialog.AlertDialogBuilder 30 import com.android.healthconnect.controller.utils.logging.DeletionDialogTimeRangeElement 31 import com.android.healthconnect.controller.utils.logging.ErrorPageElement 32 import com.android.healthconnect.controller.utils.logging.HealthConnectLogger 33 import dagger.hilt.android.AndroidEntryPoint 34 import java.time.Instant 35 import javax.inject.Inject 36 37 /** A {@link DialogFragment} for choosing the deletion time range. */ 38 @AndroidEntryPoint(DialogFragment::class) 39 class TimeRangeDialogFragment : Hilt_TimeRangeDialogFragment() { 40 41 private val viewModel: DeletionViewModel by activityViewModels() 42 @Inject lateinit var logger: HealthConnectLogger 43 44 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { 45 val view: View = layoutInflater.inflate(R.layout.dialog_message_time_range_picker, null) 46 val radioGroup: RadioGroup = view.findViewById(R.id.radio_group_time_range) 47 val messageView: TextView = view.findViewById(R.id.time_range_message) 48 messageView.text = buildMessage() 49 50 return AlertDialogBuilder(this) 51 .setLogName(DeletionDialogTimeRangeElement.DELETION_DIALOG_TIME_RANGE_CONTAINER) 52 .setTitle(R.string.time_range_title) 53 .setIcon(R.attr.deletionSettingsIcon) 54 .setView(view) 55 .setNegativeButton( 56 android.R.string.cancel, 57 DeletionDialogTimeRangeElement.DELETION_DIALOG_TIME_RANGE_CANCEL_BUTTON) { _, _ -> 58 } 59 .setPositiveButton( 60 R.string.time_range_next_button, 61 DeletionDialogTimeRangeElement.DELETION_DIALOG_TIME_RANGE_NEXT_BUTTON) { _, _ -> 62 val chosenRange = getChosenRange(radioGroup) 63 viewModel.setChosenRange(chosenRange) 64 viewModel.setEndTime(Instant.now()) 65 setFragmentResult(TIME_RANGE_SELECTION_EVENT, Bundle()) 66 } 67 .setAdditionalLogging { radioGroupLogging(radioGroup) } 68 .create() 69 } 70 71 private fun buildMessage(): String { 72 val deletionParameters = viewModel.deletionParameters.value ?: DeletionParameters() 73 val deletionType: DeletionType = deletionParameters.deletionType 74 75 return when (deletionType) { 76 is DeletionType.DeletionTypeAllData -> 77 resources.getString(R.string.time_range_message_all) 78 is DeletionType.DeletionTypeHealthPermissionTypeData, 79 is DeletionType.DeletionTypeHealthPermissionTypeFromApp -> { 80 val permissionTypeLabel = getString(deletionParameters.getPermissionTypeLabel()) 81 resources.getString(R.string.time_range_message_data_type, permissionTypeLabel) 82 } 83 is DeletionType.DeletionTypeCategoryData -> { 84 val categoryLabel = getString(deletionParameters.getCategoryLabel()) 85 resources.getString(R.string.time_range_message_category, categoryLabel) 86 } 87 is DeletionType.DeletionTypeAppData -> { 88 val appName = deletionParameters.getAppName() 89 resources.getString(R.string.time_range_message_app_data, appName) 90 } 91 else -> 92 throw UnsupportedOperationException( 93 "This Deletion type does not support configurable time range. DataTypeFromApp automatically" + 94 " deletes from all time.") 95 } 96 } 97 98 private fun getChosenRange(radioGroup: RadioGroup): ChosenRange { 99 return when (radioGroup.checkedRadioButtonId) { 100 R.id.radio_button_one_day -> ChosenRange.DELETE_RANGE_LAST_24_HOURS 101 R.id.radio_button_one_week -> ChosenRange.DELETE_RANGE_LAST_7_DAYS 102 R.id.radio_button_one_month -> ChosenRange.DELETE_RANGE_LAST_30_DAYS 103 else -> ChosenRange.DELETE_RANGE_ALL_DATA 104 } 105 } 106 107 private fun radioGroupLogging(radioGroup: RadioGroup) { 108 radioGroup.children.forEach { 109 val elementName = 110 when (it.id) { 111 R.id.radio_button_one_day -> 112 DeletionDialogTimeRangeElement 113 .DELETION_DIALOG_TIME_RANGE_LAST_24_HOURS_BUTTON 114 R.id.radio_button_one_week -> 115 DeletionDialogTimeRangeElement.DELETION_DIALOG_TIME_RANGE_LAST_7_DAYS_BUTTON 116 R.id.radio_button_one_month -> 117 DeletionDialogTimeRangeElement 118 .DELETION_DIALOG_TIME_RANGE_LAST_30_DAYS_BUTTON 119 R.id.radio_button_all -> 120 DeletionDialogTimeRangeElement.DELETION_DIALOG_TIME_RANGE_ALL_DATA_BUTTON 121 else -> ErrorPageElement.UNKNOWN_ELEMENT 122 } 123 it.setOnClickListener { logger.logInteraction(elementName) } 124 logger.logImpression(elementName) 125 } 126 } 127 128 companion object { 129 const val TAG = "TimeRangeDialogFragment" 130 } 131 } 132