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.screenrecord 17 18 import android.content.Context 19 import android.os.Bundle 20 import android.view.Gravity 21 import android.view.LayoutInflater 22 import android.view.View 23 import android.view.ViewGroup 24 import android.view.ViewStub 25 import android.view.WindowManager 26 import android.widget.AdapterView 27 import android.widget.ArrayAdapter 28 import android.widget.ImageView 29 import android.widget.Spinner 30 import android.widget.TextView 31 import androidx.annotation.ColorRes 32 import androidx.annotation.DrawableRes 33 import androidx.annotation.LayoutRes 34 import androidx.annotation.StringRes 35 import com.android.systemui.R 36 import com.android.systemui.statusbar.phone.SystemUIDialog 37 38 /** Base permission dialog for screen share and recording */ 39 open class BaseScreenSharePermissionDialog( 40 context: Context, 41 private val screenShareOptions: List<ScreenShareOption>, 42 private val appName: String?, 43 @DrawableRes private val dialogIconDrawable: Int? = null, 44 @ColorRes private val dialogIconTint: Int? = null 45 ) : SystemUIDialog(context), AdapterView.OnItemSelectedListener { 46 private lateinit var dialogTitle: TextView 47 private lateinit var startButton: TextView 48 private lateinit var cancelButton: TextView 49 private lateinit var warning: TextView 50 private lateinit var screenShareModeSpinner: Spinner 51 var selectedScreenShareOption: ScreenShareOption = screenShareOptions.first() 52 53 public override fun onCreate(savedInstanceState: Bundle?) { 54 super.onCreate(savedInstanceState) 55 window?.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS) 56 window?.setGravity(Gravity.CENTER) 57 setContentView(R.layout.screen_share_dialog) 58 dialogTitle = requireViewById(R.id.screen_share_dialog_title) 59 warning = requireViewById(R.id.text_warning) 60 startButton = requireViewById(android.R.id.button1) 61 cancelButton = requireViewById(android.R.id.button2) 62 updateIcon() 63 initScreenShareOptions() 64 createOptionsView(getOptionsViewLayoutId()) 65 } 66 67 private fun updateIcon() { 68 val icon = requireViewById<ImageView>(R.id.screen_share_dialog_icon) 69 if (dialogIconTint != null) { 70 icon.setColorFilter(context.getColor(dialogIconTint)) 71 } 72 if (dialogIconDrawable != null) { 73 icon.setImageDrawable(context.getDrawable(dialogIconDrawable)) 74 } 75 } 76 77 protected fun initScreenShareOptions() { 78 selectedScreenShareOption = screenShareOptions.first() 79 warning.text = warningText 80 initScreenShareSpinner() 81 } 82 83 private val warningText: String 84 get() = context.getString(selectedScreenShareOption.warningText, appName) 85 86 private fun initScreenShareSpinner() { 87 val adapter = OptionsAdapter(context.applicationContext, screenShareOptions) 88 screenShareModeSpinner = requireViewById(R.id.screen_share_mode_spinner) 89 screenShareModeSpinner.adapter = adapter 90 screenShareModeSpinner.onItemSelectedListener = this 91 } 92 93 override fun onItemSelected(adapterView: AdapterView<*>?, view: View, pos: Int, id: Long) { 94 selectedScreenShareOption = screenShareOptions[pos] 95 warning.text = warningText 96 } 97 98 override fun onNothingSelected(parent: AdapterView<*>?) {} 99 100 /** Protected methods for the text updates & functionality */ 101 protected fun setDialogTitle(@StringRes stringId: Int) { 102 val title = context.getString(stringId, appName) 103 dialogTitle.text = title 104 } 105 106 protected fun setStartButtonText(@StringRes stringId: Int) { 107 startButton.setText(stringId) 108 } 109 110 protected fun setStartButtonOnClickListener(listener: View.OnClickListener?) { 111 startButton.setOnClickListener(listener) 112 } 113 114 protected fun setCancelButtonOnClickListener(listener: View.OnClickListener?) { 115 cancelButton.setOnClickListener(listener) 116 } 117 118 // Create additional options that is shown under the share mode spinner 119 // Eg. the audio and tap toggles in SysUI Recorder 120 @LayoutRes protected open fun getOptionsViewLayoutId(): Int? = null 121 122 private fun createOptionsView(@LayoutRes layoutId: Int?) { 123 if (layoutId == null) return 124 val stub = findViewById<View>(R.id.options_stub) as ViewStub 125 stub.layoutResource = layoutId 126 stub.inflate() 127 } 128 } 129 130 private class OptionsAdapter( 131 context: Context, 132 private val options: List<ScreenShareOption>, 133 ) : 134 ArrayAdapter<String>( 135 context, 136 R.layout.screen_share_dialog_spinner_text, 137 options.map { context.getString(it.spinnerText) } 138 ) { 139 140 override fun isEnabled(position: Int): Boolean { 141 return options[position].spinnerDisabledText == null 142 } 143 144 override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { 145 val inflater = LayoutInflater.from(parent.context) 146 val view = inflater.inflate(R.layout.screen_share_dialog_spinner_item_text, parent, false) 147 val titleTextView = view.findViewById<TextView>(android.R.id.text1) 148 val errorTextView = view.findViewById<TextView>(android.R.id.text2) 149 titleTextView.text = getItem(position) 150 errorTextView.text = options[position].spinnerDisabledText 151 if (isEnabled(position)) { 152 errorTextView.visibility = View.GONE 153 titleTextView.isEnabled = true 154 } else { 155 errorTextView.visibility = View.VISIBLE 156 titleTextView.isEnabled = false 157 } 158 return view 159 } 160 } 161