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