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 <gui/BufferItemConsumer.h>
49 #include <utils/Log.h>
50 #include <utils/Trace.h>
51 #include <cstring>
52 #include "../../common/aidl/AidlProviderInfo.h"
53 #include "utils/SessionConfigurationUtils.h"
54
55 #include "AidlCamera3SharedDevice.h"
56
57 using namespace android::camera3;
58 using namespace android::camera3::SessionConfigurationUtils;
59
60 namespace android {
61
62 class OpaqueConsumerListener : public BufferItemConsumer::FrameAvailableListener {
63 public:
OpaqueConsumerListener(const wp<BufferItemConsumer> & consumer)64 OpaqueConsumerListener(const wp<BufferItemConsumer>& consumer) : mConsumer(consumer) {}
65
onFrameAvailable(const BufferItem &)66 virtual void onFrameAvailable(const BufferItem&) {
67 sp<BufferItemConsumer> consumer = mConsumer.promote();
68 if (consumer == nullptr) {
69 return;
70 }
71 BufferItem item;
72 consumer->acquireBuffer(&item, 0);
73 consumer->releaseBuffer(item, Fence::NO_FENCE);
74 }
onFrameReplaced(const BufferItem &)75 virtual void onFrameReplaced(const BufferItem&) {}
onFrameDequeued(const uint64_t)76 virtual void onFrameDequeued(const uint64_t) {}
onFrameCancelled(const uint64_t)77 virtual void onFrameCancelled(const uint64_t) {}
onFrameDetached(const uint64_t)78 virtual void onFrameDetached(const uint64_t) {}
79
80 wp<BufferItemConsumer> mConsumer;
81 };
82
83 // Metadata android.info.availableSharedOutputConfigurations has list of shared output
84 // configurations. Each output configuration has minimum of 11 entries of size long
85 // followed by the physical camera id if present.
86 // See android.info.availableSharedOutputConfigurations for details.
87 static const int SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES = 11;
88 std::map<std::string, sp<AidlCamera3SharedDevice>> AidlCamera3SharedDevice::sSharedDevices;
89 std::map<std::string, std::unordered_set<int>> AidlCamera3SharedDevice::sClientsPid;
90 Mutex AidlCamera3SharedDevice::sSharedClientsLock;
getInstance(std::shared_ptr<CameraServiceProxyWrapper> & cameraServiceProxyWrapper,std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,const std::string & id,bool overrideForPerfClass,int rotationOverride,bool isVendorClient,bool legacyClient)91 sp<AidlCamera3SharedDevice> AidlCamera3SharedDevice::getInstance(
92 std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
93 std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
94 const std::string& id, bool overrideForPerfClass, int rotationOverride,
95 bool isVendorClient, bool legacyClient) {
96 Mutex::Autolock l(sSharedClientsLock);
97 if (sClientsPid[id].empty()) {
98 AidlCamera3SharedDevice* sharedDevice = new AidlCamera3SharedDevice(
99 cameraServiceProxyWrapper, attributionAndPermissionUtils, id, overrideForPerfClass,
100 rotationOverride, isVendorClient, legacyClient);
101 sSharedDevices[id] = sharedDevice;
102 }
103 if (attributionAndPermissionUtils != nullptr) {
104 sClientsPid[id].insert(attributionAndPermissionUtils->getCallingPid());
105 }
106 return sSharedDevices[id];
107 }
108
initialize(sp<CameraProviderManager> manager,const std::string & monitorTags)109 status_t AidlCamera3SharedDevice::initialize(sp<CameraProviderManager> manager,
110 const std::string& monitorTags) {
111 ATRACE_CALL();
112 status_t res = OK;
113 Mutex::Autolock l(mSharedDeviceLock);
114 if (mStatus == STATUS_UNINITIALIZED) {
115 res = AidlCamera3Device::initialize(manager, monitorTags);
116 if (res == OK) {
117 mSharedOutputConfigurations = getSharedOutputConfiguration();
118 wp<NotificationListener> weakThis(this);
119 res = AidlCamera3Device::setNotifyCallback(weakThis);
120 if (res != OK) {
121 ALOGE("%s: Camera %s: Unable to set notify callback: %s (%d)",
122 __FUNCTION__, mId.c_str(), strerror(-res), res);
123 return res;
124 }
125 mFrameProcessor = new camera2::FrameProcessorBase(this);
126 std::string threadName = std::string("CDU-") + mId + "-FrameProc";
127 res = mFrameProcessor->run(threadName.c_str());
128 if (res != OK) {
129 ALOGE("%s: Unable to start frame processor thread: %s (%d)",
130 __FUNCTION__, strerror(-res), res);
131 return res;
132 }
133 }
134 }
135 return res;
136 }
137
disconnectClient(int clientPid)138 status_t AidlCamera3SharedDevice::disconnectClient(int clientPid) {
139 Mutex::Autolock l(mSharedDeviceLock);
140 if (sClientsPid[mId].erase(clientPid) == 0) {
141 ALOGW("%s: Camera %s: Client %d is not connected to shared device", __FUNCTION__,
142 mId.c_str(), clientPid);
143 }
144
145 if (sClientsPid[mId].empty()) {
146 return Camera3Device::disconnect();
147 }
148 return OK;
149 }
150
getSharedOutputConfiguration()151 std::vector<OutputConfiguration> AidlCamera3SharedDevice::getSharedOutputConfiguration() {
152 std::vector<OutputConfiguration> sharedConfigs;
153 int32_t colorspace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED;
154 camera_metadata_entry sharedSessionColorSpace = mDeviceInfo.find(
155 ANDROID_SHARED_SESSION_COLOR_SPACE);
156 if (sharedSessionColorSpace.count > 0) {
157 colorspace = *sharedSessionColorSpace.data.i32;
158 }
159 camera_metadata_entry sharedSessionConfigs = mDeviceInfo.find(
160 ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS);
161 if (sharedSessionConfigs.count > 0) {
162 int numOfEntries = sharedSessionConfigs.count;
163 int i = 0;
164 uint8_t physicalCameraIdLen;
165 int surfaceType, width, height, format, mirrorMode, timestampBase, dataspace;
166 long usage, streamUseCase;
167 bool isReadOutTimestampEnabled;
168 while (numOfEntries >= SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES) {
169 surfaceType = (int)sharedSessionConfigs.data.i64[i];
170 width = (int)sharedSessionConfigs.data.i64[i+1];
171 height = (int)sharedSessionConfigs.data.i64[i+2];
172 format = (int)sharedSessionConfigs.data.i64[i+3];
173 mirrorMode = (int)sharedSessionConfigs.data.i64[i+4];
174 isReadOutTimestampEnabled = (sharedSessionConfigs.data.i64[i+5] != 0);
175 timestampBase = (int)sharedSessionConfigs.data.i64[i+6];
176 dataspace = (int)sharedSessionConfigs.data.i64[i+7];
177 usage = sharedSessionConfigs.data.i64[i+8];
178 streamUseCase = sharedSessionConfigs.data.i64[i+9];
179 physicalCameraIdLen = sharedSessionConfigs.data.i64[i+10];
180 numOfEntries -= SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES;
181 i += SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES;
182 if (numOfEntries < physicalCameraIdLen) {
183 ALOGE("%s: Camera %s: Number of remaining data (%d entries) in shared configuration"
184 " is less than physical camera id length %d. Malformed metadata"
185 " android.info.availableSharedOutputConfigurations.", __FUNCTION__,
186 mId.c_str(), numOfEntries, physicalCameraIdLen);
187 break;
188 }
189 std::string physicalCameraId;
190 long asciiValue;
191 for (int j = 0; j < physicalCameraIdLen; j++) {
192 asciiValue = sharedSessionConfigs.data.i64[i+j];
193 if (asciiValue == 0) { // Check for null terminator
194 break;
195 }
196 physicalCameraId += static_cast<char>(asciiValue);
197 }
198 OutputConfiguration* outConfig = new OutputConfiguration(surfaceType, width, height,
199 format, colorspace, mirrorMode, isReadOutTimestampEnabled, timestampBase,
200 dataspace, usage, streamUseCase, physicalCameraId);
201 sharedConfigs.push_back(*outConfig);
202 i += physicalCameraIdLen;
203 numOfEntries -= physicalCameraIdLen;
204 }
205 if (numOfEntries != 0) {
206 ALOGE("%s: Camera %s: there are still %d entries left in shared output configuration."
207 " Malformed metadata android.info.availableSharedOutputConfigurations.",
208 __FUNCTION__, mId.c_str(), numOfEntries);
209 }
210 }
211 return sharedConfigs;
212 }
213
beginConfigure()214 status_t AidlCamera3SharedDevice::beginConfigure() {
215 Mutex::Autolock l(mSharedDeviceLock);
216 status_t res;
217 int i = 0;
218
219 if (mStatus != STATUS_UNCONFIGURED) {
220 return OK;
221 }
222
223 mSharedSurfaces.clear();
224 mOpaqueConsumers.clear();
225 mSharedSurfaceIds.clear();
226 mStreamInfoMap.clear();
227
228 for (auto config : mSharedOutputConfigurations) {
229 std::vector<SurfaceHolder> consumers;
230 android_dataspace dataspace = (android_dataspace)config.getDataspace();
231
232 if (config.getColorSpace()
233 != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED
234 && config.getFormat() != HAL_PIXEL_FORMAT_BLOB) {
235 if (!dataSpaceFromColorSpace(&dataspace, config.getColorSpace())) {
236 std::string msg = fmt::sprintf("Camera %s: color space %d not supported, "
237 " failed to convert to data space", mId.c_str(), config.getColorSpace());
238 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
239 return INVALID_OPERATION;
240 }
241 }
242 std::unordered_set<int32_t> overriddenSensorPixelModes;
243 if (checkAndOverrideSensorPixelModesUsed(config.getSensorPixelModesUsed(),
244 config.getFormat(), config.getWidth(), config.getHeight(),
245 mDeviceInfo, &overriddenSensorPixelModes) != OK) {
246 std::string msg = fmt::sprintf("Camera %s: sensor pixel modes for stream with "
247 "format %#x are not valid",mId.c_str(), config.getFormat());
248 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
249 return INVALID_OPERATION;
250 }
251
252 auto [consumer, surface] = BufferItemConsumer::create(AHARDWAREBUFFER_USAGE_CAMERA_READ);
253 mOpaqueConsumers.push_back(consumer);
254 mSharedSurfaces.push_back(surface);
255
256 sp<OpaqueConsumerListener> consumerListener = sp<OpaqueConsumerListener>::make(
257 mOpaqueConsumers[i]);
258 mOpaqueConsumers[i]->setFrameAvailableListener(consumerListener);
259 consumers.push_back({mSharedSurfaces[i], config.getMirrorMode()});
260 sp<Camera3SharedOutputStream> newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
261 config.getWidth(),config.getHeight(), config.getFormat(), config.getUsage(),
262 dataspace, static_cast<camera_stream_rotation_t>(config.getRotation()),
263 mTimestampOffset, config.getPhysicalCameraId(), overriddenSensorPixelModes,
264 getTransportType(), config.getSurfaceSetID(), mUseHalBufManager,
265 config.getDynamicRangeProfile(), config.getStreamUseCase(),
266 mDeviceTimeBaseIsRealtime, config.getTimestampBase(),
267 config.getColorSpace(), config.useReadoutTimestamp());
268 int id = newStream->getSurfaceId(consumers[0].mSurface);
269 if (id < 0) {
270 SET_ERR_L("Invalid surface id");
271 return BAD_VALUE;
272 }
273 mSharedSurfaceIds.push_back(id);
274 newStream->setStatusTracker(mStatusTracker);
275 newStream->setBufferManager(mBufferManager);
276 newStream->setImageDumpMask(mImageDumpMask);
277 res = mOutputStreams.add(mNextStreamId, newStream);
278 if (res < 0) {
279 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
280 return res;
281 }
282 mSessionStatsBuilder.addStream(mNextStreamId);
283 OutputStreamInfo streamInfo(config.getWidth(),config.getHeight(), config.getFormat(),
284 dataspace, config.getUsage(), overriddenSensorPixelModes,
285 config.getDynamicRangeProfile(), config.getStreamUseCase(),
286 config.getTimestampBase(), config.getColorSpace());
287 mStreamInfoMap[mNextStreamId++] = streamInfo;
288 i++;
289 }
290 CameraMetadata sessionParams;
291 res = configureStreams(sessionParams, CAMERA_STREAM_CONFIGURATION_NORMAL_MODE);
292 if (res != OK) {
293 std::string msg = fmt::sprintf("Camera %s: Error configuring streams: %s (%d)",
294 mId.c_str(), strerror(-res), res);
295 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
296 return res;
297 }
298 return OK;
299 }
300
getSharedStreamId(const OutputStreamInfo & config,int * streamId)301 status_t AidlCamera3SharedDevice::getSharedStreamId(const OutputStreamInfo &config,
302 int *streamId) {
303 Mutex::Autolock l(mSharedDeviceLock);
304 if (streamId == nullptr) {
305 return BAD_VALUE;
306 }
307
308 for (const auto& streamInfo : mStreamInfoMap) {
309 OutputStreamInfo info = streamInfo.second;
310 if (info == config) {
311 *streamId = streamInfo.first;
312 return OK;
313 }
314 }
315 return INVALID_OPERATION;
316 }
317
addSharedSurfaces(int streamId,const std::vector<android::camera3::OutputStreamInfo> & outputInfo,const std::vector<SurfaceHolder> & surfaces,std::vector<int> * surfaceIds)318 status_t AidlCamera3SharedDevice::addSharedSurfaces(int streamId,
319 const std::vector<android::camera3::OutputStreamInfo> &outputInfo,
320 const std::vector<SurfaceHolder> &surfaces, std::vector<int> *surfaceIds) {
321 Mutex::Autolock l(mSharedDeviceLock);
322 KeyedVector<sp<Surface>, size_t> outputMap;
323 std::vector<size_t> removedSurfaceIds;
324 status_t res;
325 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
326 if (stream == nullptr) {
327 CLOGE("Stream %d is unknown", streamId);
328 return BAD_VALUE;
329 }
330
331 res = updateStream(streamId, surfaces, outputInfo, removedSurfaceIds, &outputMap);
332 if (res != OK) {
333 CLOGE("Stream %d failed to update stream (error %d %s) ",
334 streamId, res, strerror(-res));
335 return res;
336 }
337 for (size_t i = 0 ; i < outputMap.size(); i++){
338 if (surfaceIds != nullptr) {
339 surfaceIds->push_back(outputMap.valueAt(i));
340 }
341 }
342 return OK;
343 }
344
removeSharedSurfaces(int streamId,const std::vector<size_t> & removedSurfaceIds)345 status_t AidlCamera3SharedDevice::removeSharedSurfaces(int streamId,
346 const std::vector<size_t> &removedSurfaceIds) {
347 Mutex::Autolock l(mSharedDeviceLock);
348 KeyedVector<sp<Surface>, size_t> outputMap;
349 std::vector<SurfaceHolder> surfaces;
350 std::vector<OutputStreamInfo> outputInfo;
351 status_t res;
352 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
353 if (stream == nullptr) {
354 CLOGE("Stream %d is unknown", streamId);
355 return BAD_VALUE;
356 }
357
358 res = updateStream(streamId, surfaces, outputInfo, removedSurfaceIds, &outputMap);
359 if (res != OK) {
360 CLOGE("Stream %d failed to update stream (error %d %s) ",
361 streamId, res, strerror(-res));
362 return res;
363 }
364 return OK;
365 }
366
mergeSurfaceMaps(const SurfaceMap & map1,const SurfaceMap & map2)367 SurfaceMap AidlCamera3SharedDevice::mergeSurfaceMaps(const SurfaceMap& map1,
368 const SurfaceMap& map2) {
369 SurfaceMap mergedMap = map1;
370
371 for (const auto& [key, value] : map2) {
372 // If the key exists in map1, append the values
373 if (mergedMap.count(key) > 0) {
374 mergedMap[key].insert(mergedMap[key].end(), value.begin(), value.end());
375 } else {
376 // Otherwise, insert the key-value pair from map2
377 mergedMap[key] = value;
378 }
379 }
380 return mergedMap;
381 }
382
removeClientSurfaceMap(const SurfaceMap & map1,const SurfaceMap & map2)383 SurfaceMap AidlCamera3SharedDevice::removeClientSurfaceMap(const SurfaceMap& map1,
384 const SurfaceMap& map2) {
385 SurfaceMap resultMap = map1;
386
387 for (const auto& [key, value2] : map2) {
388 auto it1 = resultMap.find(key);
389 if (it1 != resultMap.end()) {
390 // Key exists in both maps, remove matching values
391 std::vector<size_t>& value1 = it1->second;
392 for (size_t val2 : value2) {
393 value1.erase(std::remove(value1.begin(), value1.end(), val2), value1.end());
394 }
395
396 // If the vector is empty after removing, remove the key
397 if (value1.empty()) {
398 resultMap.erase(it1);
399 }
400 }
401 }
402 return resultMap;
403 }
404
setSharedStreamingRequest(const CameraDeviceBase::PhysicalCameraSettingsList & clientSettings,const SurfaceMap & surfaceMap,int32_t * sharedReqID,int64_t * lastFrameNumber)405 status_t AidlCamera3SharedDevice::setSharedStreamingRequest(
406 const CameraDeviceBase::PhysicalCameraSettingsList &clientSettings,
407 const SurfaceMap &surfaceMap, int32_t *sharedReqID,
408 int64_t *lastFrameNumber) {
409 if ((sharedReqID == nullptr) || (lastFrameNumber == nullptr)) {
410 return BAD_VALUE;
411 }
412
413 Mutex::Autolock l(mSharedDeviceLock);
414 auto requestIdEntry = clientSettings.begin()->metadata.find(ANDROID_REQUEST_ID);
415 if (requestIdEntry.count == 0) {
416 CLOGE("RequestID does not exist in metadata");
417 return BAD_VALUE;
418 }
419 int clientRequestId = requestIdEntry.data.i32[0];
420 CameraDeviceBase::PhysicalCameraSettingsList newSettings = clientSettings;
421 SurfaceMap newSurfaceMap = surfaceMap;
422 List<const CameraDeviceBase::PhysicalCameraSettingsList> settingsList;
423 std::list<SurfaceMap> surfaceMaps;
424 int32_t requestID = mRequestIdCounter;
425 const sp<CaptureRequest> curRequest = getOngoingRepeatingRequestLocked();
426
427 if (curRequest != nullptr) {
428 // If there is ongoing streaming going by secondary clients, then
429 // merge their surface map in the new repeating request.
430 newSurfaceMap = mergeSurfaceMaps(surfaceMap, curRequest->mOutputSurfaces);
431 }
432
433 std::vector<int32_t> outputStreamIds;
434 for (const auto& [key, value] : newSurfaceMap) {
435 outputStreamIds.push_back(key);
436 }
437 surfaceMaps.push_back(newSurfaceMap);
438 newSettings.begin()->metadata.update(ANDROID_REQUEST_ID, &requestID, /*size*/1);
439 mRequestIdCounter++;
440 newSettings.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS,
441 &outputStreamIds[0], outputStreamIds.size());
442 settingsList.push_back(newSettings);
443 status_t err = setStreamingRequestList(settingsList, surfaceMaps, lastFrameNumber);
444 if (err != OK) {
445 CLOGE("Cannot start shared streaming request");
446 return err;
447 }
448 mStreamingRequestId = requestID;
449 int clientPid = mAttributionAndPermissionUtils->getCallingPid();
450 mClientRequestIds[clientPid] = clientRequestId;
451 mClientSurfaces[clientPid] = surfaceMap;
452 *sharedReqID = mStreamingRequestId;
453
454 return err;
455 }
456
clearSharedStreamingRequest(int64_t * lastFrameNumber)457 status_t AidlCamera3SharedDevice::clearSharedStreamingRequest(int64_t *lastFrameNumber) {
458 Mutex::Autolock l(mSharedDeviceLock);
459 int clientPid = mAttributionAndPermissionUtils->getCallingPid();
460 const sp<CaptureRequest> curRequest = getOngoingRepeatingRequestLocked();
461 if (curRequest == nullptr) {
462 CLOGE("No streaming ongoing");
463 return INVALID_OPERATION;
464 }
465
466 SurfaceMap newSurfaceMap;
467 newSurfaceMap = removeClientSurfaceMap(curRequest->mOutputSurfaces, mClientSurfaces[clientPid]);
468 mClientRequestIds.erase(clientPid);
469 mClientSurfaces.erase(clientPid);
470 if (newSurfaceMap.empty()) {
471 status_t err = clearStreamingRequest(lastFrameNumber);
472 if (err != OK) {
473 CLOGE("Error clearing streaming request");
474 }
475 return err;
476 }
477 *lastFrameNumber = getRepeatingRequestLastFrameNumberLocked();
478 return updateOngoingRepeatingRequestLocked(newSurfaceMap);
479 }
480
setSharedCaptureRequest(const PhysicalCameraSettingsList & request,const SurfaceMap & surfaceMap,int32_t * sharedReqID,int64_t * lastFrameNumber)481 status_t AidlCamera3SharedDevice::setSharedCaptureRequest(const PhysicalCameraSettingsList &request,
482 const SurfaceMap &surfaceMap, int32_t *sharedReqID, int64_t *lastFrameNumber) {
483 Mutex::Autolock l(mSharedDeviceLock);
484 if (sharedReqID == nullptr) {
485 return BAD_VALUE;
486 }
487 CameraDeviceBase::PhysicalCameraSettingsList newRequest = request;
488 int newReqID = mRequestIdCounter;
489 List<const CameraDeviceBase::PhysicalCameraSettingsList> settingsList;
490 std::list<SurfaceMap> surfaceMaps;
491 surfaceMaps.push_back(surfaceMap);
492 newRequest.begin()->metadata.update(ANDROID_REQUEST_ID, &newReqID, /*size*/1);
493 settingsList.push_back(newRequest);
494 mRequestIdCounter++;
495 status_t err = captureList(settingsList, surfaceMaps, lastFrameNumber);
496 if (err != OK) {
497 CLOGE("Cannot start shared capture request");
498 return err;
499 }
500 *sharedReqID = newReqID;
501
502 return err;
503 }
504
startStreaming(const int32_t reqId,const SurfaceMap & surfaceMap,int32_t * sharedReqID,int64_t * lastFrameNumber)505 status_t AidlCamera3SharedDevice::startStreaming(const int32_t reqId, const SurfaceMap& surfaceMap,
506 int32_t* sharedReqID, int64_t* lastFrameNumber) {
507 ATRACE_CALL();
508
509 if ((sharedReqID == nullptr) || (lastFrameNumber == nullptr)) {
510 return BAD_VALUE;
511 }
512
513 Mutex::Autolock l(mSharedDeviceLock);
514 const sp<CaptureRequest> curRequest = getOngoingRepeatingRequestLocked();
515 if (curRequest != nullptr) {
516 // If there is already repeating request ongoing, attach the surfaces to
517 // the request.
518 SurfaceMap newSurfaceMap = mergeSurfaceMaps(surfaceMap, curRequest->mOutputSurfaces);
519 updateOngoingRepeatingRequestLocked(newSurfaceMap);
520 *lastFrameNumber = getRepeatingRequestLastFrameNumberLocked();
521 } else {
522 // If there is no ongoing repeating request, then send a default
523 // request with template preview.
524 std::vector<int32_t> outputStreamIds;
525 for (const auto& [key, value] : surfaceMap) {
526 outputStreamIds.push_back(key);
527 }
528
529 CameraMetadata previewTemplate;
530 status_t err = createDefaultRequest(CAMERA_TEMPLATE_PREVIEW, &previewTemplate);
531 if (err != OK) {
532 ALOGE("%s: Failed to create default PREVIEW request: %s (%d)",
533 __FUNCTION__, strerror(-err), err);
534 return err;
535 }
536 int32_t requestID = mRequestIdCounter;
537 previewTemplate.update(ANDROID_REQUEST_ID, &requestID, /*size*/1);
538 mRequestIdCounter++;
539 previewTemplate.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
540 outputStreamIds.size());
541 CameraDeviceBase::PhysicalCameraSettingsList previewSettings;
542 previewSettings.push_back({mId, previewTemplate});
543
544 List<const CameraDeviceBase::PhysicalCameraSettingsList> settingsList;
545 std::list<SurfaceMap> surfaceMaps;
546 settingsList.push_back(previewSettings);
547 surfaceMaps.push_back(surfaceMap);
548 err = setStreamingRequestList(settingsList, surfaceMaps, lastFrameNumber);
549 if (err != OK) {
550 CLOGE("Cannot start shared streaming request");
551 return err;
552 }
553 mStreamingRequestId = requestID;
554 }
555
556 int clientPid = mAttributionAndPermissionUtils->getCallingPid();
557 mClientRequestIds[clientPid] = reqId;
558 mClientSurfaces[clientPid] = surfaceMap;
559 *sharedReqID = mStreamingRequestId;
560 return OK;
561 }
562
setNotifyCallback(wp<NotificationListener> listener)563 status_t AidlCamera3SharedDevice::setNotifyCallback(wp<NotificationListener> listener) {
564 ATRACE_CALL();
565 Mutex::Autolock l(mSharedDeviceLock);
566
567 if (listener == NULL) {
568 return BAD_VALUE;
569 }
570 mClientListeners[mAttributionAndPermissionUtils->getCallingPid()] = listener;
571 return OK;
572 }
573
notifyError(int32_t errorCode,const CaptureResultExtras & resultExtras)574 void AidlCamera3SharedDevice::notifyError(
575 int32_t errorCode,
576 const CaptureResultExtras& resultExtras) {
577 for (auto clientListener : mClientListeners) {
578 sp<NotificationListener> listener = clientListener.second.promote();
579 if (listener != NULL) {
580 listener->notifyError(errorCode, resultExtras);
581 }
582 }
583 }
584
notifyActive(float maxPreviewFps)585 status_t AidlCamera3SharedDevice::notifyActive(float maxPreviewFps) {
586 Mutex::Autolock l(mSharedDeviceActiveLock);
587 for (auto activeClient : mClientRequestIds) {
588 sp<NotificationListener> listener = mClientListeners[activeClient.first].promote();
589 if (listener != NULL) {
590 listener->notifyActive(maxPreviewFps);
591 }
592 }
593
594 return OK;
595 }
596
notifyIdle(int64_t requestCount,int64_t resultErrorCount,bool deviceError,std::pair<int32_t,int32_t> mostRequestedFpsRange,const std::vector<hardware::CameraStreamStats> & stats)597 void AidlCamera3SharedDevice::notifyIdle(int64_t requestCount, int64_t resultErrorCount,
598 bool deviceError,
599 std::pair<int32_t, int32_t> mostRequestedFpsRange,
600 const std::vector<hardware::CameraStreamStats>& stats) {
601 Mutex::Autolock l(mSharedDeviceActiveLock);
602 for (auto clientListener : mClientListeners) {
603 sp<NotificationListener> listener = clientListener.second.promote();
604 if (listener != NULL) {
605 listener->notifyIdle(requestCount, resultErrorCount, deviceError, mostRequestedFpsRange,
606 stats);
607 }
608 }
609 }
610
notifyShutter(const CaptureResultExtras & resultExtras,nsecs_t timestamp)611 void AidlCamera3SharedDevice::notifyShutter(const CaptureResultExtras& resultExtras,
612 nsecs_t timestamp) {
613 for (auto clientListener : mClientListeners) {
614 sp<NotificationListener> listener = clientListener.second.promote();
615 if (listener != NULL) {
616 listener->notifyShutter(resultExtras, timestamp);
617 }
618 }
619 }
620
621 }
622