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, safetySourceData, safetyEvent) 78 } 79 createSafetySourceDataForWorkPolicynull80 private fun createSafetySourceDataForWorkPolicy(context: Context): SafetySourceData? { 81 val deviceOwnerIntent = workPolicyUtils.workPolicyInfoIntentDO 82 val profileOwnerIntent = workPolicyUtils.workPolicyInfoIntentPO 83 val pendingIntent = 84 when { 85 deviceOwnerIntent != null -> { 86 PendingIntent.getActivity( 87 context, 0, deviceOwnerIntent, PendingIntent.FLAG_IMMUTABLE) 88 } 89 profileOwnerIntent != null -> { 90 val managedProfileContext = 91 context.createPackageContextAsUser( 92 context.packageName, 93 0, 94 UserHandle.of(workPolicyUtils.managedProfileUserId)) 95 PendingIntent.getActivity( 96 managedProfileContext, 0, profileOwnerIntent, PendingIntent.FLAG_IMMUTABLE) 97 } 98 else -> null 99 } 100 ?: return null 101 102 val safetySourceStatus: SafetySourceStatus = 103 SafetySourceStatus.Builder( 104 Utils.getEnterpriseString( 105 context, WORK_POLICY_TITLE, R.string.work_policy_title), 106 Utils.getEnterpriseString( 107 context, WORK_POLICY_SUMMARY, R.string.work_policy_summary), 108 SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED) 109 .setPendingIntent(pendingIntent) 110 .build() 111 112 return SafetySourceData.Builder().setStatus(safetySourceStatus).build() 113 } 114 createSafetyEventForWorkPolicynull115 private fun createSafetyEventForWorkPolicy( 116 refreshEvent: RefreshEvent, 117 intent: Intent 118 ): SafetyEvent { 119 return when (refreshEvent) { 120 RefreshEvent.EVENT_REFRESH_REQUESTED -> { 121 val refreshBroadcastId = 122 intent.getStringExtra( 123 SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID) 124 SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED) 125 .setRefreshBroadcastId(refreshBroadcastId) 126 .build() 127 } 128 RefreshEvent.EVENT_DEVICE_REBOOTED -> { 129 SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build() 130 } 131 RefreshEvent.UNKNOWN -> { 132 SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build() 133 } 134 } 135 } 136 } 137