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 package com.google.jetpackcamera.core.camera
17 
18 import android.hardware.camera2.CameraCharacteristics
19 import android.os.Build
20 import android.os.Environment
21 import androidx.annotation.OptIn
22 import androidx.annotation.RequiresApi
23 import androidx.camera.camera2.interop.Camera2CameraInfo
24 import androidx.camera.camera2.interop.ExperimentalCamera2Interop
25 import androidx.camera.core.CameraInfo
26 import java.io.File
27 import java.io.FileOutputStream
28 import org.json.JSONArray
29 import org.json.JSONObject
30 
31 private const val TAG = "DebugCameraInfoUtil"
32 object DebugCameraInfoUtil {
33     @OptIn(ExperimentalCamera2Interop::class)
34     @RequiresApi(Build.VERSION_CODES.P)
35     fun getAllCamerasPropertiesJSONArray(cameraInfos: List<CameraInfo>): JSONArray {
36         val result = JSONArray()
37         for (cameraInfo in cameraInfos) {
38             var camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
39             val logicalCameraId = camera2CameraInfo.cameraId
40             val logicalCameraData = JSONObject()
41             logicalCameraData.put(
42                 "logical-$logicalCameraId",
43                 getCameraPropertiesJSONObject(camera2CameraInfo)
44             )
45             for (physicalCameraInfo in cameraInfo.physicalCameraInfos) {
46                 camera2CameraInfo = Camera2CameraInfo.from(physicalCameraInfo)
47                 val physicalCameraId = camera2CameraInfo.cameraId
48                 logicalCameraData.put(
49                     "physical-$physicalCameraId",
50                     getCameraPropertiesJSONObject(camera2CameraInfo)
51                 )
52             }
53             result.put(logicalCameraData)
54         }
55         return result
56     }
57 
58     @OptIn(ExperimentalCamera2Interop::class)
59     private fun getCameraPropertiesJSONObject(cameraInfo: Camera2CameraInfo): JSONObject {
60         val jsonObject = JSONObject()
61         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
62             cameraInfo.getCameraCharacteristic(CameraCharacteristics.LENS_POSE_ROTATION)
63                 ?.let {
64                     jsonObject.put(
65                         CameraCharacteristics.LENS_POSE_ROTATION.name,
66                         it.contentToString()
67                     )
68                 }
69             cameraInfo.getCameraCharacteristic(CameraCharacteristics.LENS_POSE_TRANSLATION)
70                 ?.let {
71                     jsonObject.put(
72                         CameraCharacteristics.LENS_POSE_TRANSLATION.name,
73                         it.contentToString()
74                     )
75                 }
76             cameraInfo.getCameraCharacteristic(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION)
77                 ?.let {
78                     jsonObject.put(
79                         CameraCharacteristics.LENS_INTRINSIC_CALIBRATION.name,
80                         it.contentToString()
81                     )
82                 }
83         }
84         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
85             cameraInfo.getCameraCharacteristic(CameraCharacteristics.LENS_DISTORTION)
86                 ?.let {
87                     jsonObject.put(
88                         CameraCharacteristics.LENS_DISTORTION.name,
89                         it.contentToString()
90                     )
91                 }
92         }
93         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
94             cameraInfo.getCameraCharacteristic(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE)
95                 ?.let { jsonObject.put(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE.name, it) }
96         }
97         cameraInfo.getCameraCharacteristic(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
98             ?.let {
99                 jsonObject.put(
100                     CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS.name,
101                     it.contentToString()
102                 )
103             }
104         cameraInfo.getCameraCharacteristic(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
105             ?.let {
106                 jsonObject.put(
107                     CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE.name,
108                     it
109                 )
110             }
111         cameraInfo.getCameraCharacteristic(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
112             ?.let {
113                 jsonObject.put(
114                     CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES.name,
115                     it.contentToString()
116                 )
117             }
118 
119         return jsonObject
120     }
121 
122     fun writeFileExternalStorage(file: File, textToWrite: String) {
123         // Checking the availability state of the External Storage.
124         val state = Environment.getExternalStorageState()
125         if (Environment.MEDIA_MOUNTED != state) {
126             // If it isn't mounted - we can't write into it.
127             return
128         }
129 
130         file.createNewFile()
131         FileOutputStream(file).use { outputStream ->
132             outputStream.write(textToWrite.toByteArray())
133         }
134     }
135 }
136