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.systemui.mediaprojection.permission 18 19 import android.app.AlertDialog 20 import android.media.projection.MediaProjectionConfig 21 import android.testing.TestableLooper 22 import android.view.WindowManager 23 import android.widget.Spinner 24 import android.widget.TextView 25 import androidx.test.ext.junit.runners.AndroidJUnit4 26 import androidx.test.filters.SmallTest 27 import com.android.systemui.SysuiTestCase 28 import com.android.systemui.flags.FeatureFlagsClassic 29 import com.android.systemui.flags.Flags 30 import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger 31 import com.android.systemui.res.R 32 import com.android.systemui.statusbar.phone.AlertDialogWithDelegate 33 import com.android.systemui.statusbar.phone.SystemUIDialog 34 import com.android.systemui.util.mockito.mock 35 import junit.framework.Assert.assertEquals 36 import org.junit.After 37 import org.junit.Before 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 import org.mockito.Mockito.`when` as whenever 41 42 @SmallTest 43 @RunWith(AndroidJUnit4::class) 44 @TestableLooper.RunWithLooper(setAsMainLooper = true) 45 class MediaProjectionPermissionDialogDelegateTest : SysuiTestCase() { 46 47 private lateinit var dialog: AlertDialog 48 49 private val flags = mock<FeatureFlagsClassic>() 50 private val onStartRecordingClicked = mock<Runnable>() 51 private val mediaProjectionMetricsLogger = mock<MediaProjectionMetricsLogger>() 52 53 private val mediaProjectionConfig: MediaProjectionConfig = 54 MediaProjectionConfig.createConfigForDefaultDisplay() 55 private val appName: String = "testApp" 56 private val hostUid: Int = 12345 57 58 private val resIdSingleApp = R.string.screen_share_permission_dialog_option_single_app 59 private val resIdFullScreen = R.string.screen_share_permission_dialog_option_entire_screen 60 private val resIdSingleAppDisabled = 61 R.string.media_projection_entry_app_permission_dialog_single_app_disabled 62 63 @Before setUpnull64 fun setUp() { 65 whenever(flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING)).thenReturn(true) 66 } 67 68 @After teardownnull69 fun teardown() { 70 if (::dialog.isInitialized) { 71 dialog.dismiss() 72 } 73 } 74 75 @Test showDialog_forceShowPartialScreenShareFalsenull76 fun showDialog_forceShowPartialScreenShareFalse() { 77 // Set up dialog with MediaProjectionConfig.createConfigForDefaultDisplay() and 78 // overrideDisableSingleAppOption = false 79 val overrideDisableSingleAppOption = false 80 setUpAndShowDialog(overrideDisableSingleAppOption) 81 82 val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner) 83 val secondOptionText = 84 spinner.adapter 85 .getDropDownView(1, null, spinner) 86 .findViewById<TextView>(android.R.id.text2) 87 ?.text 88 89 // check that the first option is full screen and enabled 90 assertEquals(context.getString(resIdFullScreen), spinner.selectedItem) 91 92 // check that the second option is single app and disabled 93 assertEquals(context.getString(resIdSingleAppDisabled, appName), secondOptionText) 94 } 95 96 @Test showDialog_forceShowPartialScreenShareTruenull97 fun showDialog_forceShowPartialScreenShareTrue() { 98 // Set up dialog with MediaProjectionConfig.createConfigForDefaultDisplay() and 99 // overrideDisableSingleAppOption = true 100 val overrideDisableSingleAppOption = true 101 setUpAndShowDialog(overrideDisableSingleAppOption) 102 103 val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner) 104 val secondOptionText = 105 spinner.adapter 106 .getDropDownView(1, null, spinner) 107 .findViewById<TextView>(android.R.id.text1) 108 ?.text 109 110 // check that the first option is single app and enabled 111 assertEquals(context.getString(resIdSingleApp), spinner.selectedItem) 112 113 // check that the second option is full screen and enabled 114 assertEquals(context.getString(resIdFullScreen), secondOptionText) 115 } 116 setUpAndShowDialognull117 private fun setUpAndShowDialog(overrideDisableSingleAppOption: Boolean) { 118 val delegate = 119 MediaProjectionPermissionDialogDelegate( 120 context, 121 mediaProjectionConfig, 122 {}, 123 onStartRecordingClicked, 124 appName, 125 overrideDisableSingleAppOption, 126 hostUid, 127 mediaProjectionMetricsLogger 128 ) 129 130 dialog = AlertDialogWithDelegate(context, R.style.Theme_SystemUI_Dialog, delegate) 131 SystemUIDialog.applyFlags(dialog) 132 SystemUIDialog.setDialogSize(dialog) 133 134 dialog.window?.addSystemFlags( 135 WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS 136 ) 137 138 delegate.onCreate(dialog, savedInstanceState = null) 139 dialog.show() 140 } 141 } 142