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