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 package com.android.systemui.mediaprojection.permission 17 18 import android.app.AlertDialog 19 import android.content.Context 20 import android.media.projection.MediaProjectionConfig 21 import android.os.Bundle 22 import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger 23 import com.android.systemui.res.R 24 import java.util.function.Consumer 25 26 /** Dialog to select screen recording options */ 27 class MediaProjectionPermissionDialogDelegate( 28 context: Context, 29 mediaProjectionConfig: MediaProjectionConfig?, 30 private val onStartRecordingClicked: Consumer<MediaProjectionPermissionDialogDelegate>, 31 private val onCancelClicked: Runnable, 32 private val appName: String?, 33 private val forceShowPartialScreenshare: Boolean, 34 hostUid: Int, 35 mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, 36 ) : 37 BaseMediaProjectionPermissionDialogDelegate<AlertDialog>( 38 createOptionList(context, appName, mediaProjectionConfig, forceShowPartialScreenshare), 39 appName, 40 hostUid, 41 mediaProjectionMetricsLogger 42 ) { onCreatenull43 override fun onCreate(dialog: AlertDialog, savedInstanceState: Bundle?) { 44 super.onCreate(dialog, savedInstanceState) 45 // TODO(b/270018943): Handle the case of System sharing (not recording nor casting) 46 if (appName == null) { 47 setDialogTitle(R.string.media_projection_entry_cast_permission_dialog_title) 48 setStartButtonText(R.string.media_projection_entry_cast_permission_dialog_continue) 49 } else { 50 setDialogTitle(R.string.media_projection_entry_app_permission_dialog_title) 51 setStartButtonText(R.string.media_projection_entry_app_permission_dialog_continue) 52 } 53 setStartButtonOnClickListener { 54 // Note that it is important to run this callback before dismissing, so that the 55 // callback can disable the dialog exit animation if it wants to. 56 onStartRecordingClicked.accept(this) 57 dialog.dismiss() 58 } 59 setCancelButtonOnClickListener { 60 onCancelClicked.run() 61 dialog.dismiss() 62 } 63 } 64 65 companion object { createOptionListnull66 private fun createOptionList( 67 context: Context, 68 appName: String?, 69 mediaProjectionConfig: MediaProjectionConfig?, 70 overrideDisableSingleAppOption: Boolean = false, 71 ): List<ScreenShareOption> { 72 val singleAppWarningText = 73 if (appName == null) { 74 R.string.media_projection_entry_cast_permission_dialog_warning_single_app 75 } else { 76 R.string.media_projection_entry_app_permission_dialog_warning_single_app 77 } 78 val entireScreenWarningText = 79 if (appName == null) { 80 R.string.media_projection_entry_cast_permission_dialog_warning_entire_screen 81 } else { 82 R.string.media_projection_entry_app_permission_dialog_warning_entire_screen 83 } 84 85 // The single app option should only be disabled if there is an app name provided, 86 // the client has setup a MediaProjection with 87 // MediaProjectionConfig#createConfigForDefaultDisplay, AND it hasn't been overridden by 88 // the OVERRIDE_DISABLE_SINGLE_APP_OPTION per-app override. 89 val singleAppOptionDisabled = 90 appName != null && 91 !overrideDisableSingleAppOption && 92 mediaProjectionConfig?.regionToCapture == 93 MediaProjectionConfig.CAPTURE_REGION_FIXED_DISPLAY 94 95 val singleAppDisabledText = 96 if (singleAppOptionDisabled) { 97 context.getString( 98 R.string.media_projection_entry_app_permission_dialog_single_app_disabled, 99 appName 100 ) 101 } else { 102 null 103 } 104 val options = 105 listOf( 106 ScreenShareOption( 107 mode = SINGLE_APP, 108 spinnerText = R.string.screen_share_permission_dialog_option_single_app, 109 warningText = singleAppWarningText, 110 spinnerDisabledText = singleAppDisabledText, 111 ), 112 ScreenShareOption( 113 mode = ENTIRE_SCREEN, 114 spinnerText = R.string.screen_share_permission_dialog_option_entire_screen, 115 warningText = entireScreenWarningText 116 ) 117 ) 118 return if (singleAppOptionDisabled) { 119 // Make sure "Entire screen" is the first option when "Single App" is disabled. 120 options.reversed() 121 } else { 122 options 123 } 124 } 125 } 126 } 127