1 /* <lambda>null2 * Copyright (C) 2024 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 android.security.cts.camera.open 18 19 import android.content.BroadcastReceiver 20 import android.content.ComponentName 21 import android.content.Context 22 import android.content.Intent 23 import android.content.IntentFilter 24 import android.os.Bundle 25 import android.os.Process 26 import android.security.cts.camera.open.lib.IntentKeys 27 import android.util.Log 28 import android.view.TextureView 29 import android.view.ViewGroup 30 import android.view.ViewGroup.LayoutParams.MATCH_PARENT 31 import androidx.activity.result.ActivityResult 32 import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult 33 import androidx.appcompat.app.AppCompatActivity 34 import androidx.lifecycle.lifecycleScope 35 import kotlinx.coroutines.launch 36 37 class OpenCameraActivity : AppCompatActivity() { 38 private val cameraProxyAppKeys = IntentKeys(CAMERA_PROXY_APP_PACKAGE_NAME) 39 private lateinit var keys: IntentKeys 40 private lateinit var broadcastReceiver: BroadcastReceiver 41 private lateinit var textureView: TextureView 42 private lateinit var cameraOpener: CameraOpener 43 private val startForResult = 44 registerForActivityResult(StartActivityForResult()) { activityResult: ActivityResult -> 45 setResult(activityResult.resultCode, activityResult.data) 46 finish() 47 } 48 49 override fun onCreate(savedInstanceState: Bundle?) { 50 super.onCreate(savedInstanceState) 51 Log.v(TAG, "onCreate") 52 53 textureView = TextureView(this) 54 textureView.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT) 55 setContentView(textureView) 56 57 keys = IntentKeys(packageName) 58 cameraOpener = CameraOpener(context = this, keys, textureView, surfaceTexture = null) 59 60 val shouldStream = intent.getBooleanExtra(keys.shouldStream, false) 61 val shouldRepeat = intent.getBooleanExtra(keys.shouldRepeat, false) 62 if (intent.getBooleanExtra(keys.shouldOpenCamera1, false)) { 63 openCamera1AndFinish(shouldStream, shouldRepeat) 64 } else if (intent.getBooleanExtra(keys.shouldOpenCamera2, false)) { 65 openCamera2AndFinish(shouldStream, shouldRepeat) 66 } else if (intent.getBooleanExtra(keys.shouldOpenCameraNdk, false)) { 67 openCameraNdkAndFinish(shouldStream, shouldRepeat) 68 } 69 } 70 71 override fun onResume() { 72 super.onResume() 73 Log.v(TAG, "onResume") 74 75 broadcastReceiver = 76 object : BroadcastReceiver() { 77 override fun onReceive(context: Context, intent: Intent) { 78 Log.v(TAG, "onReceive") 79 when (intent.action) { 80 keys.finish -> { 81 Log.v(TAG, "onReceive: finish") 82 setResult(RESULT_OK) 83 finish() 84 } 85 86 keys.openCamera1ByProxy -> { 87 Log.v(TAG, "onReceive: openCamera1ByProxy") 88 openCamera1ByProxy( 89 intent.getBooleanExtra(keys.shouldStream, false), 90 intent.getBooleanExtra(keys.shouldRepeat, false)) 91 } 92 93 keys.openCamera2ByProxy -> { 94 Log.v(TAG, "onReceive: openCamera2ByProxy") 95 openCamera2ByProxy( 96 intent.getBooleanExtra(keys.shouldStream, false), 97 intent.getBooleanExtra(keys.shouldRepeat, false)) 98 } 99 100 keys.openCameraNdkByProxy -> { 101 Log.v(TAG, "onReceive: openCameraNdkByProxy") 102 openCameraNdkByProxy( 103 intent.getBooleanExtra(keys.shouldStream, false), 104 intent.getBooleanExtra(keys.shouldRepeat, false)) 105 } 106 107 keys.stopRepeating -> { 108 Log.v(TAG, "onReceive: stopRepeating") 109 cameraOpener.onStopRepeating() 110 } 111 } 112 } 113 } 114 115 val filter = 116 IntentFilter().apply { 117 addAction(keys.finish) 118 addAction(keys.openCamera1ByProxy) 119 addAction(keys.openCamera2ByProxy) 120 addAction(keys.openCameraNdkByProxy) 121 addAction(keys.stopRepeating) 122 } 123 registerReceiver(broadcastReceiver, filter, Context.RECEIVER_EXPORTED) 124 125 val onResumeIntent = Intent(keys.onResume).apply { putExtra(keys.pid, Process.myPid()) } 126 onResumeIntent.setPackage("android.security.cts") 127 sendBroadcast(onResumeIntent) 128 } 129 130 override fun onPause() { 131 super.onPause() 132 Log.v(TAG, "onPause") 133 unregisterReceiver(broadcastReceiver) 134 } 135 136 override fun onDestroy() { 137 super.onDestroy() 138 Log.v(TAG, "onDestroy") 139 cameraOpener.release() 140 } 141 142 private fun openCamera1AndFinish(shouldStream: Boolean, shouldRepeat: Boolean) { 143 lifecycleScope.launch { 144 setResult(RESULT_OK, cameraOpener.openCamera1Async(shouldStream, shouldRepeat)) 145 finish() 146 } 147 } 148 149 private fun openCamera2AndFinish(shouldStream: Boolean, shouldRepeat: Boolean) { 150 lifecycleScope.launch { 151 val result = cameraOpener.openCamera2Async(shouldStream, shouldRepeat) 152 Log.v(TAG, "finishing activity: ${result.getExtras().toString()}") 153 setResult(RESULT_OK, result) 154 finish() 155 } 156 } 157 158 private fun openCameraNdkAndFinish(shouldStream: Boolean, shouldRepeat: Boolean) { 159 lifecycleScope.launch { 160 val result = cameraOpener.openCameraNdkAsync(shouldStream, shouldRepeat) 161 Log.v(TAG, "finishing activity: ${result.getExtras().toString()}") 162 setResult(RESULT_OK, result) 163 finish() 164 } 165 } 166 167 private fun openCameraByProxy( 168 openCameraKey: String, 169 shouldStream: Boolean, 170 shouldRepeat: Boolean 171 ) { 172 startForResult.launch( 173 Intent().apply { 174 component = ComponentName(CAMERA_PROXY_APP_PACKAGE_NAME, CAMERA_PROXY_ACTIVITY) 175 putExtra(openCameraKey, true) 176 putExtra(cameraProxyAppKeys.shouldStream, shouldStream) 177 putExtra(cameraProxyAppKeys.shouldRepeat, shouldRepeat) 178 }) 179 } 180 181 private fun openCamera1ByProxy(shouldStream: Boolean, shouldRepeat: Boolean) = 182 openCameraByProxy(cameraProxyAppKeys.shouldOpenCamera1, shouldStream, shouldRepeat) 183 184 private fun openCamera2ByProxy(shouldStream: Boolean, shouldRepeat: Boolean) = 185 openCameraByProxy(cameraProxyAppKeys.shouldOpenCamera2, shouldStream, shouldRepeat) 186 187 private fun openCameraNdkByProxy(shouldStream: Boolean, shouldRepeat: Boolean) = 188 openCameraByProxy(cameraProxyAppKeys.shouldOpenCameraNdk, shouldStream, shouldRepeat) 189 190 private companion object { 191 val TAG = OpenCameraActivity::class.java.simpleName 192 193 const val CAMERA_PROXY_APP_PACKAGE_NAME = "android.security.cts.camera.proxy" 194 const val CAMERA_PROXY_ACTIVITY = "$CAMERA_PROXY_APP_PACKAGE_NAME.CameraProxyActivity" 195 } 196 } 197