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 18 package com.android.systemui.keyguard.data.quickaffordance 19 20 import android.app.StatusBarManager 21 import android.app.admin.DevicePolicyManager 22 import android.content.Context 23 import android.content.Intent 24 import com.android.systemui.ActivityIntentHelper 25 import com.android.systemui.R 26 import com.android.systemui.animation.Expandable 27 import com.android.systemui.camera.CameraIntents 28 import com.android.systemui.camera.CameraIntentsWrapper 29 import com.android.systemui.common.shared.model.ContentDescription 30 import com.android.systemui.common.shared.model.Icon 31 import com.android.systemui.dagger.SysUISingleton 32 import com.android.systemui.dagger.qualifiers.Application 33 import com.android.systemui.dagger.qualifiers.Background 34 import com.android.systemui.settings.UserTracker 35 import javax.inject.Inject 36 import kotlinx.coroutines.CoroutineDispatcher 37 import kotlinx.coroutines.flow.Flow 38 import kotlinx.coroutines.flow.flow 39 import kotlinx.coroutines.withContext 40 41 @SysUISingleton 42 class VideoCameraQuickAffordanceConfig 43 @Inject 44 constructor( 45 @Application private val context: Context, 46 private val cameraIntents: CameraIntentsWrapper, 47 private val activityIntentHelper: ActivityIntentHelper, 48 private val userTracker: UserTracker, 49 private val devicePolicyManager: DevicePolicyManager, 50 @Background private val backgroundDispatcher: CoroutineDispatcher, 51 ) : KeyguardQuickAffordanceConfig { 52 53 private val intent: Intent by lazy { 54 cameraIntents.getVideoCameraIntent().apply { 55 putExtra( 56 CameraIntents.EXTRA_LAUNCH_SOURCE, 57 StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE, 58 ) 59 } 60 } 61 62 override val key: String 63 get() = BuiltInKeyguardQuickAffordanceKeys.VIDEO_CAMERA 64 65 override fun pickerName(): String = context.getString(R.string.video_camera) 66 67 override val pickerIconResourceId: Int 68 get() = R.drawable.ic_videocam 69 70 override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> 71 get() = flow { 72 emit( 73 if (isLaunchable()) { 74 KeyguardQuickAffordanceConfig.LockScreenState.Visible( 75 icon = 76 Icon.Resource( 77 R.drawable.ic_videocam, 78 ContentDescription.Resource(R.string.video_camera) 79 ) 80 ) 81 } else { 82 KeyguardQuickAffordanceConfig.LockScreenState.Hidden 83 } 84 ) 85 } 86 87 override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState { 88 return if (isLaunchable()) { 89 super.getPickerScreenState() 90 } else { 91 KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice 92 } 93 } 94 95 override fun onTriggered( 96 expandable: Expandable? 97 ): KeyguardQuickAffordanceConfig.OnTriggeredResult { 98 return KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity( 99 intent = intent, 100 canShowWhileLocked = false, 101 ) 102 } 103 104 private suspend fun isLaunchable(): Boolean { 105 return activityIntentHelper.getTargetActivityInfo( 106 intent, 107 userTracker.userId, 108 true, 109 ) != null && 110 withContext(backgroundDispatcher) { 111 !devicePolicyManager.getCameraDisabled(null, userTracker.userId) 112 } 113 } 114 } 115