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.permissioncontroller.privacysources 18 19 import android.app.PendingIntent 20 import android.content.Context 21 import android.content.Intent 22 import android.os.Build 23 import android.os.UserHandle 24 import android.provider.Settings 25 import android.safetycenter.SafetyCenterManager 26 import android.safetycenter.SafetyEvent 27 import android.safetycenter.SafetySourceData 28 import android.safetycenter.SafetySourceStatus 29 import androidx.annotation.RequiresApi 30 import com.android.permissioncontroller.R 31 import com.android.permissioncontroller.permission.utils.Utils 32 import com.android.permissioncontroller.privacysources.SafetyCenterReceiver.RefreshEvent 33 import com.android.settingslib.utils.WorkPolicyUtils 34 35 /** 36 * Work Policy Info for managed devices to show the settings managed by their Organisation's IT 37 * Admin. It is a Privacy Source, and it receives broadcasts from SafetyCenter using 38 * SafetyCenterReceiver.kt 39 * 40 * safetyCenterEnabledChanged and rescanAndPushSafetyCenterData methods checks if the device is 41 * managed and shows the Work Policy Info by pushing the data in SafetyCenter 42 */ 43 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 44 class WorkPolicyInfo(private val workPolicyUtils: WorkPolicyUtils) : PrivacySource { 45 46 companion object { 47 const val WORK_POLICY_INFO_SOURCE_ID = "AndroidWorkPolicyInfo" 48 const val WORK_POLICY_TITLE = "SafetyCenter.WORK_POLICY_TITLE" 49 const val WORK_POLICY_SUMMARY = "SafetyCenter.WORK_POLICY_SUMMARY" createnull50 fun create(context: Context): WorkPolicyInfo { 51 val workPolicyUtils = WorkPolicyUtils(context) 52 return WorkPolicyInfo(workPolicyUtils) 53 } 54 } 55 56 override val shouldProcessProfileRequest: Boolean = false 57 safetyCenterEnabledChangednull58 override fun safetyCenterEnabledChanged(context: Context, enabled: Boolean) { 59 val intent = Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO) 60 val refreshEvent: RefreshEvent = RefreshEvent.UNKNOWN 61 if (enabled) { 62 rescanAndPushSafetyCenterData(context, intent, refreshEvent) 63 } 64 } 65 rescanAndPushSafetyCenterDatanull66 override fun rescanAndPushSafetyCenterData( 67 context: Context, 68 intent: Intent, 69 refreshEvent: RefreshEvent 70 ) { 71 val safetyCenterManager: SafetyCenterManager = 72 Utils.getSystemServiceSafe(context, SafetyCenterManager::class.java) 73 val safetyEvent: SafetyEvent = createSafetyEventForWorkPolicy(refreshEvent, intent) 74 val safetySourceData: SafetySourceData? = createSafetySourceDataForWorkPolicy(context) 75 76 safetyCenterManager.setSafetySourceData( 77 WORK_POLICY_INFO_SOURCE_ID, 78 safetySourceData, 79 safetyEvent 80 ) 81 } 82 createSafetySourceDataForWorkPolicynull83 private fun createSafetySourceDataForWorkPolicy(context: Context): SafetySourceData? { 84 val deviceOwnerIntent = workPolicyUtils.workPolicyInfoIntentDO 85 val profileOwnerIntent = workPolicyUtils.workPolicyInfoIntentPO 86 val pendingIntent = 87 when { 88 deviceOwnerIntent != null -> { 89 PendingIntent.getActivity( 90 context, 91 0, 92 deviceOwnerIntent, 93 PendingIntent.FLAG_IMMUTABLE 94 ) 95 } 96 profileOwnerIntent != null -> { 97 val managedProfileContext = 98 context.createPackageContextAsUser( 99 context.packageName, 100 0, 101 UserHandle.of(workPolicyUtils.managedProfileUserId) 102 ) 103 PendingIntent.getActivity( 104 managedProfileContext, 105 0, 106 profileOwnerIntent, 107 PendingIntent.FLAG_IMMUTABLE 108 ) 109 } 110 else -> null 111 } 112 ?: return null 113 114 val safetySourceStatus: SafetySourceStatus = 115 SafetySourceStatus.Builder( 116 Utils.getEnterpriseString( 117 context, 118 WORK_POLICY_TITLE, 119 R.string.work_policy_title 120 ), 121 Utils.getEnterpriseString( 122 context, 123 WORK_POLICY_SUMMARY, 124 R.string.work_policy_summary 125 ), 126 SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED 127 ) 128 .setPendingIntent(pendingIntent) 129 .build() 130 131 return SafetySourceData.Builder().setStatus(safetySourceStatus).build() 132 } 133 createSafetyEventForWorkPolicynull134 private fun createSafetyEventForWorkPolicy( 135 refreshEvent: RefreshEvent, 136 intent: Intent 137 ): SafetyEvent { 138 return when (refreshEvent) { 139 RefreshEvent.EVENT_REFRESH_REQUESTED -> { 140 val refreshBroadcastId = 141 intent.getStringExtra( 142 SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID 143 ) 144 SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED) 145 .setRefreshBroadcastId(refreshBroadcastId) 146 .build() 147 } 148 RefreshEvent.EVENT_DEVICE_REBOOTED -> { 149 SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build() 150 } 151 RefreshEvent.UNKNOWN -> { 152 SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build() 153 } 154 } 155 } 156 } 157