xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/device3/aidl/AidlCamera3SharedDevice.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 #define LOG_TAG "AidlCamera3-SharedDevice"
17 #define ATRACE_TAG ATRACE_TAG_CAMERA
18 //#define LOG_NDEBUG 0
19 //#define LOG_NNDEBUG 0  // Per-frame verbose logging
20 
21 #ifdef LOG_NNDEBUG
22 #define ALOGVV(...) ALOGV(__VA_ARGS__)
23 #else
24 #define ALOGVV(...) ((void)0)
25 #endif
26 
27 // Convenience macro for transient errors
28 #define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
29             ##__VA_ARGS__)
30 
31 #define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
32             ##__VA_ARGS__)
33 
34 // Convenience macros for transitioning to the error state
35 #define SET_ERR(fmt, ...) setErrorState(   \
36     "%s: " fmt, __FUNCTION__,              \
37     ##__VA_ARGS__)
38 #define SET_ERR_L(fmt, ...) setErrorStateLocked( \
39     "%s: " fmt, __FUNCTION__,                    \
40     ##__VA_ARGS__)
41 #define DECODE_VALUE(decoder, type, var) \
42   do { \
43     if (decoder.get##type(var) != OK) { \
44       return NOT_ENOUGH_DATA; \
45     } \
46   } while (0)
47 
48 #include <utils/Log.h>
49 #include <utils/Trace.h>
50 #include <cstring>
51 #include "../../common/aidl/AidlProviderInfo.h"
52 #include "utils/SessionConfigurationUtils.h"
53 #include "AidlCamera3SharedDevice.h"
54 
55 using namespace android::camera3;
56 using namespace android::camera3::SessionConfigurationUtils;
57 
58 namespace android {
59 
60 // Metadata android.info.availableSharedOutputConfigurations has list of shared output
61 // configurations. Each output configuration has minimum of 11 entries of size long
62 // followed by the physical camera id if present.
63 // See android.info.availableSharedOutputConfigurations for details.
64 static const int SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES = 11;
65 std::map<std::string, sp<AidlCamera3SharedDevice>> AidlCamera3SharedDevice::sSharedDevices;
66 std::map<std::string, std::unordered_set<int>> AidlCamera3SharedDevice::sClientsUid;
getInstance(std::shared_ptr<CameraServiceProxyWrapper> & cameraServiceProxyWrapper,std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,const std::string & id,bool overrideForPerfClass,int rotationOverride,bool legacyClient)67 sp<AidlCamera3SharedDevice> AidlCamera3SharedDevice::getInstance(
68         std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
69         std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
70         const std::string& id, bool overrideForPerfClass, int rotationOverride,
71         bool legacyClient) {
72     if (sClientsUid[id].empty()) {
73         AidlCamera3SharedDevice* sharedDevice = new AidlCamera3SharedDevice(
74                 cameraServiceProxyWrapper, attributionAndPermissionUtils, id, overrideForPerfClass,
75                 rotationOverride, legacyClient);
76         sSharedDevices[id] = sharedDevice;
77     }
78     if (attributionAndPermissionUtils != nullptr) {
79         sClientsUid[id].insert(attributionAndPermissionUtils->getCallingUid());
80     }
81     return sSharedDevices[id];
82 }
83 
initialize(sp<CameraProviderManager> manager,const std::string & monitorTags)84 status_t AidlCamera3SharedDevice::initialize(sp<CameraProviderManager> manager,
85         const std::string& monitorTags) {
86     ATRACE_CALL();
87     status_t res = OK;
88 
89     if (mStatus == STATUS_UNINITIALIZED) {
90         res = AidlCamera3Device::initialize(manager, monitorTags);
91         if (res == OK) {
92             mSharedOutputConfigurations = getSharedOutputConfiguration();
93         }
94     }
95     return res;
96 }
97 
disconnectClient(int clientUid)98 status_t AidlCamera3SharedDevice::disconnectClient(int clientUid) {
99     if (sClientsUid[mId].erase(clientUid) == 0) {
100         ALOGW("%s: Camera %s: Client %d is not connected to shared device", __FUNCTION__,
101                 mId.c_str(), clientUid);
102     }
103     if (sClientsUid[mId].empty()) {
104         return Camera3Device::disconnect();
105     }
106     return OK;
107 }
108 
getSharedOutputConfiguration()109 std::vector<OutputConfiguration> AidlCamera3SharedDevice::getSharedOutputConfiguration() {
110     std::vector<OutputConfiguration> sharedConfigs;
111     uint8_t colorspace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED;
112     camera_metadata_entry sharedSessionColorSpace = mDeviceInfo.find(
113             ANDROID_SHARED_SESSION_COLOR_SPACE);
114     if (sharedSessionColorSpace.count > 0) {
115         colorspace = *sharedSessionColorSpace.data.u8;
116     }
117     camera_metadata_entry sharedSessionConfigs = mDeviceInfo.find(
118             ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS);
119     if (sharedSessionConfigs.count > 0) {
120         int numOfEntries = sharedSessionConfigs.count;
121         int i = 0;
122         uint8_t physicalCameraIdLen;
123         int surfaceType, width, height, format, mirrorMode, timestampBase, dataspace;
124         long usage, streamUseCase;
125         bool isReadOutTimestampEnabled;
126         while (numOfEntries >= SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES) {
127             surfaceType = (int)sharedSessionConfigs.data.i64[i];
128             width = (int)sharedSessionConfigs.data.i64[i+1];
129             height = (int)sharedSessionConfigs.data.i64[i+2];
130             format = (int)sharedSessionConfigs.data.i64[i+3];
131             mirrorMode = (int)sharedSessionConfigs.data.i64[i+4];
132             isReadOutTimestampEnabled = (sharedSessionConfigs.data.i64[i+5] != 0);
133             timestampBase = (int)sharedSessionConfigs.data.i64[i+6];
134             dataspace = (int)sharedSessionConfigs.data.i64[i+7];
135             usage = sharedSessionConfigs.data.i64[i+8];
136             streamUseCase = sharedSessionConfigs.data.i64[i+9];
137             physicalCameraIdLen = sharedSessionConfigs.data.i64[i+10];
138             numOfEntries -= SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES;
139             i += SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES;
140             if (numOfEntries < physicalCameraIdLen) {
141                 ALOGE("%s: Camera %s: Number of remaining data (%d entries) in shared configuration"
142                         " is less than physical camera id length %d. Malformed metadata"
143                         " android.info.availableSharedOutputConfigurations.", __FUNCTION__,
144                         mId.c_str(), numOfEntries, physicalCameraIdLen);
145                 break;
146             }
147             std::string physicalCameraId;
148             long asciiValue;
149             for (int j = 0; j < physicalCameraIdLen; j++) {
150                 asciiValue = sharedSessionConfigs.data.i64[i+j];
151                 if (asciiValue == 0) { // Check for null terminator
152                     break;
153                 }
154                 physicalCameraId += static_cast<char>(asciiValue);
155             }
156             OutputConfiguration* outConfig = new OutputConfiguration(surfaceType, width, height,
157                     format, colorspace, mirrorMode, isReadOutTimestampEnabled, timestampBase,
158                     dataspace, usage, streamUseCase, physicalCameraId);
159             sharedConfigs.push_back(*outConfig);
160             i += physicalCameraIdLen;
161             numOfEntries -= physicalCameraIdLen;
162         }
163         if (numOfEntries != 0) {
164             ALOGE("%s: Camera %s: there are still %d entries left in shared output configuration."
165                     " Malformed metadata android.info.availableSharedOutputConfigurations.",
166                     __FUNCTION__, mId.c_str(), numOfEntries);
167         }
168     }
169     return sharedConfigs;
170 }
171 
beginConfigure()172 status_t AidlCamera3SharedDevice::beginConfigure() {
173     status_t res;
174     int i = 0;
175 
176     if (mStatus != STATUS_UNCONFIGURED) {
177         return OK;
178     }
179 
180     for (auto config : mSharedOutputConfigurations) {
181         std::vector<SurfaceHolder> consumers;
182         android_dataspace dataSpace;
183         if (config.getColorSpace()
184                 != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED
185                 && config.getFormat() != HAL_PIXEL_FORMAT_BLOB) {
186             if (!dataSpaceFromColorSpace(&dataSpace, config.getColorSpace())) {
187                 std::string msg = fmt::sprintf("Camera %s: color space %d not supported, "
188                     " failed to convert to data space", mId.c_str(), config.getColorSpace());
189                 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
190                 return INVALID_OPERATION;
191             }
192         }
193         std::unordered_set<int32_t> overriddenSensorPixelModes;
194         if (checkAndOverrideSensorPixelModesUsed(config.getSensorPixelModesUsed(),
195                 config.getFormat(), config.getWidth(), config.getHeight(),
196                 mDeviceInfo, &overriddenSensorPixelModes) != OK) {
197             std::string msg = fmt::sprintf("Camera %s: sensor pixel modes for stream with "
198                         "format %#x are not valid",mId.c_str(), config.getFormat());
199             ALOGE("%s: %s", __FUNCTION__, msg.c_str());
200             return INVALID_OPERATION;
201         }
202         sp<IGraphicBufferProducer> producer;
203         sp<IGraphicBufferConsumer> consumer;
204         BufferQueue::createBufferQueue(&producer, &consumer);
205         mSharedSurfaces[i] = new Surface(producer);
206         consumers.push_back({mSharedSurfaces[i], config.getMirrorMode()});
207         mSharedStreams[i] = new Camera3SharedOutputStream(mNextStreamId, consumers,
208                 config.getWidth(),config.getHeight(), config.getFormat(), config.getUsage(),
209                 dataSpace, static_cast<camera_stream_rotation_t>(config.getRotation()),
210                 mTimestampOffset, config.getPhysicalCameraId(), overriddenSensorPixelModes,
211                 getTransportType(), config.getSurfaceSetID(), mUseHalBufManager,
212                 config.getDynamicRangeProfile(), config.getStreamUseCase(),
213                 mDeviceTimeBaseIsRealtime, config.getTimestampBase(),
214                 config.getColorSpace(), config.useReadoutTimestamp());
215         int id = mSharedStreams[i]->getSurfaceId(consumers[0].mSurface);
216         if (id < 0) {
217             SET_ERR_L("Invalid surface id");
218             return BAD_VALUE;
219         }
220         mSharedSurfaceIds[i] = id;
221         mSharedStreams[i]->setStatusTracker(mStatusTracker);
222         mSharedStreams[i]->setBufferManager(mBufferManager);
223         mSharedStreams[i]->setImageDumpMask(mImageDumpMask);
224         res = mOutputStreams.add(mNextStreamId, mSharedStreams[i]);
225         if (res < 0) {
226             SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
227             return res;
228         }
229         mSessionStatsBuilder.addStream(mNextStreamId);
230         mConfiguredOutputs.add(mNextStreamId++, config);
231         i++;
232     }
233     CameraMetadata sessionParams;
234     res = configureStreams(sessionParams, CAMERA_STREAM_CONFIGURATION_SHARED_MODE);
235     if (res != OK) {
236         std::string msg = fmt::sprintf("Camera %s: Error configuring streams: %s (%d)",
237                 mId.c_str(), strerror(-res), res);
238         ALOGE("%s: %s", __FUNCTION__, msg.c_str());
239         return res;
240     }
241     return OK;
242 }
243 
getSharedStreamId(const OutputConfiguration & config,int * streamId)244 status_t AidlCamera3SharedDevice::getSharedStreamId(const OutputConfiguration &config,
245         int *streamId) {
246     if (streamId ==  nullptr) {
247         return BAD_VALUE;
248     }
249     for (size_t i = 0 ; i < mConfiguredOutputs.size(); i++){
250         OutputConfiguration sharedConfig = mConfiguredOutputs.valueAt(i);
251         if (config.sharedConfigEqual(sharedConfig)) {
252             *streamId = mConfiguredOutputs.keyAt(i);
253             return OK;
254         }
255     }
256     return INVALID_OPERATION;
257 }
258 
addSharedSurfaces(int streamId,const std::vector<android::camera3::OutputStreamInfo> & outputInfo,const std::vector<SurfaceHolder> & surfaces,std::vector<int> * surfaceIds)259 status_t AidlCamera3SharedDevice::addSharedSurfaces(int streamId,
260         const std::vector<android::camera3::OutputStreamInfo> &outputInfo,
261         const std::vector<SurfaceHolder> &surfaces,  std::vector<int> *surfaceIds) {
262     KeyedVector<sp<Surface>, size_t> outputMap;
263     std::vector<size_t> removedSurfaceIds;
264     status_t res;
265     sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
266     if (stream == nullptr) {
267         CLOGE("Stream %d is unknown", streamId);
268         return BAD_VALUE;
269     }
270 
271     res = updateStream(streamId, surfaces, outputInfo, removedSurfaceIds, &outputMap);
272     if (res != OK) {
273         CLOGE("Stream %d failed to update stream (error %d %s) ",
274               streamId, res, strerror(-res));
275         return res;
276     }
277 
278     for (size_t i = 0 ; i < outputMap.size(); i++){
279         if (surfaceIds != nullptr) {
280             surfaceIds->push_back(outputMap.valueAt(i));
281         }
282     }
283     return OK;
284 }
285 
removeSharedSurfaces(int streamId,const std::vector<size_t> & removedSurfaceIds)286 status_t AidlCamera3SharedDevice::removeSharedSurfaces(int streamId,
287         const std::vector<size_t> &removedSurfaceIds) {
288     KeyedVector<sp<Surface>, size_t> outputMap;
289     std::vector<SurfaceHolder> surfaces;
290     std::vector<OutputStreamInfo> outputInfo;
291     status_t res;
292     sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
293     if (stream == nullptr) {
294         CLOGE("Stream %d is unknown", streamId);
295         return BAD_VALUE;
296     }
297 
298     res = updateStream(streamId, surfaces, outputInfo, removedSurfaceIds, &outputMap);
299     if (res != OK) {
300         CLOGE("Stream %d failed to update stream (error %d %s) ",
301               streamId, res, strerror(-res));
302         return res;
303     }
304     return OK;
305 }
306 }
307