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 
17 package com.android.healthconnect.controller.safetycenter
18 
19 import android.content.BroadcastReceiver
20 import android.content.ComponentName
21 import android.content.Context
22 import android.content.Intent
23 import android.content.Intent.ACTION_BOOT_COMPLETED
24 import android.content.pm.PackageManager
25 import android.os.UserManager
26 import android.safetycenter.SafetyCenterManager
27 import android.safetycenter.SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES
28 import android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS
29 import android.safetycenter.SafetyEvent
30 import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
31 import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
32 import com.android.healthconnect.controller.safetycenter.HealthConnectSafetySource.Companion.HEALTH_CONNECT_SOURCE_ID
33 import com.android.healthconnect.controller.utils.DeviceInfoUtils
34 import dagger.hilt.android.AndroidEntryPoint
35 import javax.inject.Inject
36 
37 @AndroidEntryPoint(BroadcastReceiver::class)
38 class SafetySourceBroadcastReceiver : Hilt_SafetySourceBroadcastReceiver() {
39 
40     @Inject lateinit var safetySource: HealthConnectSafetySource
41     @Inject lateinit var safetyCenterManagerWrapper: SafetyCenterManagerWrapper
42     @Inject lateinit var deviceInfoUtils: DeviceInfoUtils
43 
onReceivenull44     override fun onReceive(context: Context, intent: Intent) {
45         super.onReceive(context, intent)
46         tryEnableLegacySettingsEntryPoint(context)
47         if (!safetyCenterManagerWrapper.isEnabled(context)) {
48             return
49         }
50         // (b/320250695) HC doesn't support user profiles
51         if ((context.getSystemService(Context.USER_SERVICE) as UserManager).isProfile) {
52             return
53         }
54         when (intent.action) {
55             ACTION_BOOT_COMPLETED -> refreshAllSafetySources(context)
56             ACTION_REFRESH_SAFETY_SOURCES -> {
57                 val sourceIdsExtra = intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS)
58                 val refreshBroadcastId =
59                     intent.getStringExtra(
60                         SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID)
61                 if (sourceIdsExtra != null &&
62                     sourceIdsExtra.isNotEmpty() &&
63                     refreshBroadcastId != null) {
64                     val safetyEvent =
65                         SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
66                             .setRefreshBroadcastId(refreshBroadcastId)
67                             .build()
68                     refreshSafetySources(context, sourceIdsExtra.toList(), safetyEvent)
69                 }
70                 return
71             }
72             else -> return
73         }
74     }
75 
tryEnableLegacySettingsEntryPointnull76     private fun tryEnableLegacySettingsEntryPoint(context: Context) {
77         val legacySettingsEntryPointComponent =
78             ComponentName(context.packageName, LEGACY_SETTINGS_ACTIVITY_ALIAS)
79 
80         val componentState =
81             if (shouldEnableLegacySettingsEntryPoint(context)) {
82                 PackageManager.COMPONENT_ENABLED_STATE_ENABLED
83             } else {
84                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED
85             }
86 
87         context.packageManager.setComponentEnabledSetting(
88             legacySettingsEntryPointComponent, componentState, 0)
89     }
90 
shouldEnableLegacySettingsEntryPointnull91     private fun shouldEnableLegacySettingsEntryPoint(context: Context): Boolean {
92         return !safetyCenterManagerWrapper.isEnabled(context) &&
93             deviceInfoUtils.isHealthConnectAvailable(context)
94     }
95 
refreshSafetySourcesnull96     private fun refreshSafetySources(
97         context: Context,
98         sourceIds: List<String>,
99         safetyEvent: SafetyEvent
100     ) {
101         if (HEALTH_CONNECT_SOURCE_ID in sourceIds) {
102             safetySource.setSafetySourceData(context, safetyEvent)
103         }
104     }
105 
refreshAllSafetySourcesnull106     private fun refreshAllSafetySources(context: Context) {
107         safetySource.setSafetySourceData(
108             context, SafetyEvent.Builder(SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build())
109     }
110 
111     companion object {
112         private const val LEGACY_SETTINGS_ACTIVITY_ALIAS =
113             "com.android.healthconnect.controller.LegacySettingsEntryPoint"
114     }
115 }
116