xref: /aosp_15_r20/cts/tests/tests/security/CameraPermissionTestApp/src/CameraOpenerService.kt (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * 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.app.Service
20 import android.content.Intent
21 import android.graphics.SurfaceTexture
22 import android.opengl.EGL14
23 import android.opengl.EGLConfig
24 import android.opengl.EGLContext
25 import android.opengl.EGLDisplay
26 import android.opengl.EGLSurface
27 import android.opengl.GLES11Ext
28 import android.opengl.GLES30
29 import android.os.IBinder
30 import android.security.cts.camera.open.lib.IntentKeys
31 import android.util.Log
32 import android.view.Surface
33 import java.nio.IntBuffer
34 import java.util.concurrent.Executors
35 
36 class CameraOpenerService : Service() {
37 
38   private lateinit var keys: IntentKeys
39   private lateinit var cameraOpener: CameraOpener
40 
41   private lateinit var display: EGLDisplay
42   private lateinit var config: EGLConfig
43   private lateinit var context: EGLContext
44   private lateinit var placeholderSurface: EGLSurface
45 
46   private var cameraTexId: Int = -1
47   private var cameraSurface: Surface? = null
48   private var cameraSurfaceTexture: SurfaceTexture? = null
49 
50   private val renderExecutor = Executors.newSingleThreadExecutor()
51 
onCreatenull52   override fun onCreate() {
53     Log.v(TAG, "onCreate")
54     super.onCreate()
55     keys = IntentKeys(packageName)
56 
57     display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
58     checkEglError("eglGetDisplay")
59 
60     val version = intArrayOf(0, 0)
61     if (!EGL14.eglInitialize(display, version, 0, version, 1)) {
62       throw RuntimeException("Unable to initialize EGL14")
63     }
64     checkEglError("eglInitialize")
65 
66     val rgbaBits = 8
67     val configAttribList =
68         intArrayOf(
69             EGL14.EGL_RENDERABLE_TYPE,
70             EGL14.EGL_OPENGL_ES2_BIT,
71             EGL14.EGL_SURFACE_TYPE,
72             EGL14.EGL_PBUFFER_BIT or EGL14.EGL_WINDOW_BIT,
73             EGL14.EGL_RED_SIZE,
74             rgbaBits,
75             EGL14.EGL_GREEN_SIZE,
76             rgbaBits,
77             EGL14.EGL_BLUE_SIZE,
78             rgbaBits,
79             EGL14.EGL_ALPHA_SIZE,
80             rgbaBits,
81             EGL14.EGL_DEPTH_SIZE,
82             16,
83             EGL14.EGL_NONE,
84         )
85 
86     val configs = arrayOfNulls<EGLConfig>(1)
87     val numConfigs = intArrayOf(1)
88     EGL14.eglChooseConfig(display, configAttribList, 0, configs, 0, configs.size, numConfigs, 0)
89     config = configs[0]!!
90 
91     val requestedVersion = 2
92     val contextAttribList =
93         intArrayOf(EGL14.EGL_CONTEXT_CLIENT_VERSION, requestedVersion, EGL14.EGL_NONE)
94 
95     context = EGL14.eglCreateContext(display, config, EGL14.EGL_NO_CONTEXT, contextAttribList, 0)
96     if (context == EGL14.EGL_NO_CONTEXT) {
97       throw RuntimeException("Failed to create EGL context")
98     }
99 
100     val placeholderSurfaceAttribs =
101         intArrayOf(EGL14.EGL_WIDTH, 1, EGL14.EGL_HEIGHT, 1, EGL14.EGL_NONE)
102     placeholderSurface =
103         EGL14.eglCreatePbufferSurface(display, config, placeholderSurfaceAttribs, /*offset*/ 0)
104 
105     EGL14.eglMakeCurrent(display, placeholderSurface, placeholderSurface, context)
106 
107     cameraTexId = createTexture()
108     cameraSurfaceTexture = SurfaceTexture(cameraTexId)
109     cameraSurface = Surface(cameraSurfaceTexture)
110 
111     cameraOpener =
112         CameraOpener(
113             context = this, keys, textureView = null, surfaceTexture = cameraSurfaceTexture)
114   }
115 
onDestroynull116   override fun onDestroy() {
117     Log.v(TAG, "onDestroy")
118     super.onDestroy()
119     cameraOpener.release()
120 
121     EGL14.eglMakeCurrent(display, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT)
122     EGL14.eglDestroySurface(display, placeholderSurface)
123     placeholderSurface = EGL14.EGL_NO_SURFACE
124     EGL14.eglDestroyContext(display, context)
125     context = EGL14.EGL_NO_CONTEXT
126     EGL14.eglReleaseThread()
127     EGL14.eglTerminate(display)
128     display = EGL14.EGL_NO_DISPLAY
129   }
130 
onBindnull131   override fun onBind(intent: Intent): IBinder {
132     Log.v(TAG, "onBind")
133     return cameraOpener.aidlInterface
134   }
135 
checkEglErrornull136   private fun checkEglError(op: String) {
137     val eglError = EGL14.eglGetError()
138     if (eglError != EGL14.EGL_SUCCESS) {
139       val msg = op + ": eglError 0x" + Integer.toHexString(eglError)
140       throw IllegalStateException(msg)
141     }
142   }
143 
checkGlErrornull144   private fun checkGlError(op: String) {
145     val error = GLES30.glGetError()
146     if (error != GLES30.GL_NO_ERROR) {
147       val msg = op + ": glError " + glErrorStr(error)
148       throw IllegalStateException(msg)
149     }
150   }
151 
glErrorStrnull152   private fun glErrorStr(error: Int) =
153       when (error) {
154         GLES30.GL_INVALID_ENUM -> "GL_INVALID_ENUM"
155         GLES30.GL_INVALID_VALUE -> "GL_INVALID_VALUE"
156         GLES30.GL_INVALID_OPERATION -> "GL_INVALID_OPERATION"
157         GLES30.GL_OUT_OF_MEMORY -> "GL_OUT_OF_MEMORY"
158         else -> "0x" + Integer.toHexString(error)
159       }
160 
createTexturenull161   private fun createTexture(): Int {
162     val buffer = IntBuffer.allocate(1)
163     GLES30.glGenTextures(1, buffer)
164     checkGlError("glGenTextures")
165     val texId = buffer.get(0)
166     val target = GLES11Ext.GL_TEXTURE_EXTERNAL_OES
167     GLES30.glBindTexture(target, /* texture= */ texId)
168     checkGlError("glBindTexture")
169 
170     GLES30.glTexParameteri(target, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR)
171     GLES30.glTexParameteri(target, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR)
172     GLES30.glTexParameteri(target, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE)
173     GLES30.glTexParameteri(target, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE)
174     return texId
175   }
176 
177   private companion object {
178     private val TAG = CameraOpenerService::class.java.simpleName
179   }
180 }
181