1 /*
2 * Copyright (C) 2020 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 #define LOG_TAG "CameraServiceProxyWrapper"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include <binder/IServiceManager.h>
22 #include <camera/StringUtils.h>
23 #include <gui/Flags.h> // remove with WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
24 #include <gui/Surface.h>
25 #include <inttypes.h>
26 #include <system/window.h>
27 #include <utils/Log.h>
28 #include <utils/String16.h>
29
30 #include "aidl/android/hardware/graphics/common/Dataspace.h"
31
32 #include "CameraServiceProxyWrapper.h"
33
34 namespace android {
35
36 using hardware::CameraExtensionSessionStats;
37 using hardware::CameraFeatureCombinationStats;
38 using hardware::CameraSessionStats;
39 using hardware::ICameraServiceProxy;
40 using hardware::camera2::params::SessionConfiguration;
41
42 namespace {
43 // Sentinel value to be returned when extension session with a stale or invalid key is reported.
44 const std::string POISON_EXT_STATS_KEY("poisoned_stats");
45 } // anonymous namespace
46
47 /**
48 * CameraSessionStatsWrapper functions
49 */
50
updateProxyDeviceState(sp<hardware::ICameraServiceProxy> & proxyBinder)51 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::updateProxyDeviceState(
52 sp<hardware::ICameraServiceProxy>& proxyBinder) {
53 if (proxyBinder == nullptr) return;
54 proxyBinder->notifyCameraState(mSessionStats);
55 }
56
onOpen(sp<hardware::ICameraServiceProxy> & proxyBinder)57 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onOpen(
58 sp<hardware::ICameraServiceProxy>& proxyBinder) {
59 Mutex::Autolock l(mLock);
60 updateProxyDeviceState(proxyBinder);
61 }
62
onClose(sp<hardware::ICameraServiceProxy> & proxyBinder,int32_t latencyMs,bool deviceError)63 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onClose(
64 sp<hardware::ICameraServiceProxy>& proxyBinder, int32_t latencyMs,
65 bool deviceError) {
66 Mutex::Autolock l(mLock);
67
68 mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_CLOSED;
69 mSessionStats.mLatencyMs = latencyMs;
70 mSessionStats.mDeviceError = deviceError;
71 mSessionStats.mSessionIndex = 0;
72 updateProxyDeviceState(proxyBinder);
73 }
74
onStreamConfigured(int operatingMode,bool internalReconfig,int32_t latencyMs)75 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onStreamConfigured(
76 int operatingMode, bool internalReconfig, int32_t latencyMs) {
77 Mutex::Autolock l(mLock);
78
79 if (internalReconfig) {
80 mSessionStats.mInternalReconfigure++;
81 } else {
82 mSessionStats.mLatencyMs = latencyMs;
83 mSessionStats.mSessionType = operatingMode;
84 }
85 }
86
onActive(sp<hardware::ICameraServiceProxy> & proxyBinder,float maxPreviewFps)87 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onActive(
88 sp<hardware::ICameraServiceProxy>& proxyBinder, float maxPreviewFps) {
89 Mutex::Autolock l(mLock);
90
91 mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_ACTIVE;
92 mSessionStats.mMaxPreviewFps = maxPreviewFps;
93 mSessionStats.mSessionIndex++;
94 updateProxyDeviceState(proxyBinder);
95
96 // Reset mCreationDuration to -1 to distinguish between 1st session
97 // after configuration, and all other sessions after configuration.
98 mSessionStats.mLatencyMs = -1;
99 }
100
onIdle(sp<hardware::ICameraServiceProxy> & proxyBinder,int64_t requestCount,int64_t resultErrorCount,bool deviceError,const std::string & userTag,int32_t videoStabilizationMode,bool usedUltraWide,bool usedZoomOverride,std::pair<int32_t,int32_t> mostRequestedFpsRange,const std::vector<hardware::CameraStreamStats> & streamStats)101 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onIdle(
102 sp<hardware::ICameraServiceProxy>& proxyBinder,
103 int64_t requestCount, int64_t resultErrorCount, bool deviceError,
104 const std::string& userTag, int32_t videoStabilizationMode, bool usedUltraWide,
105 bool usedZoomOverride, std::pair<int32_t, int32_t> mostRequestedFpsRange,
106 const std::vector<hardware::CameraStreamStats>& streamStats) {
107 Mutex::Autolock l(mLock);
108
109 mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_IDLE;
110 mSessionStats.mRequestCount = requestCount;
111 mSessionStats.mResultErrorCount = resultErrorCount;
112 mSessionStats.mDeviceError = deviceError;
113 mSessionStats.mUserTag = userTag;
114 mSessionStats.mVideoStabilizationMode = videoStabilizationMode;
115 mSessionStats.mUsedUltraWide = usedUltraWide;
116 mSessionStats.mUsedZoomOverride = usedZoomOverride;
117 mSessionStats.mMostRequestedFpsRange = mostRequestedFpsRange;
118 mSessionStats.mStreamStats = streamStats;
119
120 updateProxyDeviceState(proxyBinder);
121
122 mSessionStats.mInternalReconfigure = 0;
123 mSessionStats.mStreamStats.clear();
124 mSessionStats.mCameraExtensionSessionStats = {};
125 }
126
getLogId()127 int64_t CameraServiceProxyWrapper::CameraSessionStatsWrapper::getLogId() {
128 Mutex::Autolock l(mLock);
129 return mSessionStats.mLogId;
130 }
131
updateExtensionSessionStats(const hardware::CameraExtensionSessionStats & extStats)132 std::string CameraServiceProxyWrapper::CameraSessionStatsWrapper::updateExtensionSessionStats(
133 const hardware::CameraExtensionSessionStats& extStats) {
134 Mutex::Autolock l(mLock);
135 CameraExtensionSessionStats& currStats = mSessionStats.mCameraExtensionSessionStats;
136 if (currStats.key != extStats.key) {
137 // Mismatched keys. Extensions stats likely reported for a closed session
138 ALOGW("%s: mismatched extensions stats key: current='%s' reported='%s'. Dropping stats.",
139 __FUNCTION__, toStdString(currStats.key).c_str(), toStdString(extStats.key).c_str());
140 return POISON_EXT_STATS_KEY; // return poisoned key to so future calls are
141 // definitely dropped.
142 }
143
144 // Matching keys...
145 if (currStats.key.size()) {
146 // non-empty matching keys. overwrite.
147 ALOGV("%s: Overwriting extension session stats: %s", __FUNCTION__,
148 extStats.toString().c_str());
149 currStats = extStats;
150 return toStdString(currStats.key);
151 }
152
153 // Matching empty keys...
154 if (mSessionStats.mClientName != toStdString(extStats.clientName)) {
155 ALOGW("%s: extension stats reported for unexpected package: current='%s' reported='%s'. "
156 "Dropping stats.", __FUNCTION__,
157 mSessionStats.mClientName.c_str(),
158 toStdString(extStats.clientName).c_str());
159 return POISON_EXT_STATS_KEY;
160 }
161
162 // Matching empty keys for the current client...
163 if (mSessionStats.mNewCameraState == CameraSessionStats::CAMERA_STATE_OPEN ||
164 mSessionStats.mNewCameraState == CameraSessionStats::CAMERA_STATE_IDLE) {
165 // Camera is open, but not active. It is possible that the active callback hasn't
166 // occurred yet. Keep the stats, but don't associate it with any session.
167 ALOGV("%s: extension stat reported for an open, but not active camera. "
168 "Saving stats, but not generating key.", __FUNCTION__);
169 currStats = extStats;
170 return {}; // Subsequent calls will handle setting the correct key.
171 }
172
173 if (mSessionStats.mNewCameraState == CameraSessionStats::CAMERA_STATE_ACTIVE) {
174 // camera is active. First call for the session!
175 currStats = extStats;
176
177 // Generate a new key from logId and sessionIndex.
178 std::ostringstream key;
179 key << mSessionStats.mSessionIndex << '/' << mSessionStats.mLogId;
180 currStats.key = String16(key.str().c_str());
181 ALOGV("%s: New extension session stats: %s", __FUNCTION__, currStats.toString().c_str());
182 return toStdString(currStats.key);
183 }
184
185 // Camera is closed. Probably a stale call.
186 ALOGW("%s: extension stats reported for closed camera id '%s'. Dropping stats.",
187 __FUNCTION__, mSessionStats.mCameraId.c_str());
188 return {};
189 }
190
191 /**
192 * CameraServiceProxyWrapper functions
193 */
194
getCameraServiceProxy()195 sp<ICameraServiceProxy> CameraServiceProxyWrapper::getCameraServiceProxy() {
196 #ifndef __BRILLO__
197 Mutex::Autolock al(mProxyMutex);
198 if (mCameraServiceProxy == nullptr) {
199 mCameraServiceProxy = getDefaultCameraServiceProxy();
200 }
201 #endif
202 return mCameraServiceProxy;
203 }
204
getDefaultCameraServiceProxy()205 sp<hardware::ICameraServiceProxy> CameraServiceProxyWrapper::getDefaultCameraServiceProxy() {
206 #ifndef __BRILLO__
207 sp<IServiceManager> sm = defaultServiceManager();
208 // Use checkService because cameraserver normally starts before the
209 // system server and the proxy service. So the long timeout that getService
210 // has before giving up is inappropriate.
211 sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
212 if (binder != nullptr) {
213 return interface_cast<ICameraServiceProxy>(binder);
214 }
215 #endif
216 return nullptr;
217 }
218
pingCameraServiceProxy()219 void CameraServiceProxyWrapper::pingCameraServiceProxy() {
220 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
221 if (proxyBinder == nullptr) return;
222 proxyBinder->pingForUserUpdate();
223 }
224
encodeSessionConfiguration(const SessionConfiguration & sessionConfig)225 int64_t CameraServiceProxyWrapper::encodeSessionConfiguration(
226 const SessionConfiguration& sessionConfig) {
227 int64_t features = CameraFeatureCombinationStats::CAMERA_FEATURE_UNKNOWN;
228 const static int32_t WIDTH_4K = 3840;
229 const static int32_t HEIGHT_4K = 2160;
230
231 // Check session parameters
232 if (sessionConfig.hasSessionParameters()) {
233 const auto& parameters = sessionConfig.getSessionParameters();
234
235 camera_metadata_ro_entry fpsEntry = parameters.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
236 if (fpsEntry.count == 2 && fpsEntry.data.i32[1] == 60) {
237 features |= CameraFeatureCombinationStats::CAMERA_FEATURE_60_FPS;
238 }
239
240 camera_metadata_ro_entry stabEntry =
241 parameters.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE);
242 if (stabEntry.count == 1 && stabEntry.data.u8[0] ==
243 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION) {
244 features |= CameraFeatureCombinationStats::CAMERA_FEATURE_STABILIZATION;
245 }
246 }
247
248 // Check output configurations
249 const auto& outputConfigs = sessionConfig.getOutputConfigurations();
250 for (const auto& config : outputConfigs) {
251 int format = config.getFormat();
252 int dataSpace = config.getDataspace();
253 int64_t dynamicRangeProfile = config.getDynamicRangeProfile();
254
255 // Check JPEG and JPEG_R features
256 if (format == HAL_PIXEL_FORMAT_BLOB) {
257 if (dataSpace == HAL_DATASPACE_V0_JFIF) {
258 features |= CameraFeatureCombinationStats::CAMERA_FEATURE_JPEG;
259 } else if (dataSpace == static_cast<android_dataspace_t>(
260 aidl::android::hardware::graphics::common::Dataspace::JPEG_R)) {
261 features |= CameraFeatureCombinationStats::CAMERA_FEATURE_JPEG_R;
262 }
263 } else {
264 if (dynamicRangeProfile == HAL_DATASPACE_BT2020_HLG) {
265 features |= CameraFeatureCombinationStats::CAMERA_FEATURE_HLG10;
266 }
267
268 // Check 4K
269 const std::vector<ParcelableSurfaceType>& surfaces = config.getSurfaces();
270 int32_t width = 0, height = 0;
271 if (surfaces.size() > 0) {
272 #if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
273 if (surfaces[0].isEmpty()) {
274 #else
275 if (surfaces[0] == nullptr) {
276 #endif
277 ALOGE("%s: Failed to query size due to abandoned surface.",
278 __FUNCTION__);
279 return CameraFeatureCombinationStats::CAMERA_FEATURE_UNKNOWN;
280 }
281
282 #if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
283 sp<Surface> surface = surfaces[0].toSurface();
284 #else
285 sp<Surface> surface = new Surface(surfaces[0], /*useAsync*/false);
286 #endif
287 ANativeWindow *anw = surface.get();
288
289 width = ANativeWindow_getWidth(anw);
290 if (width < 0) {
291 ALOGE("%s: Failed to query Surface width: %s (%d)",
292 __FUNCTION__, strerror(-width), width);
293 return CameraFeatureCombinationStats::CAMERA_FEATURE_UNKNOWN;
294 }
295 height = ANativeWindow_getHeight(anw);
296 if (height < 0) {
297 ALOGE("%s: Failed to query Surface height: %s (%d)",
298 __FUNCTION__, strerror(-height), height);
299 return CameraFeatureCombinationStats::CAMERA_FEATURE_UNKNOWN;
300 }
301 } else {
302 width = config.getWidth();
303 height = config.getHeight();
304 }
305 if (width == WIDTH_4K && height == HEIGHT_4K) {
306 features |= CameraFeatureCombinationStats::CAMERA_FEATURE_4K;
307 }
308 }
309 }
310 return features;
311 }
312
313 // Note: The `ret` parameter is the return value of the
314 // `isSessionConfigurationWithParametersSupporteed` binder call from the app.
315 void CameraServiceProxyWrapper::logFeatureCombinationInternal(
316 const std::string &cameraId, int clientUid,
317 const SessionConfiguration& sessionConfiguration, binder::Status ret,
318 int type) {
319 sp<hardware::ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
320 if (proxyBinder == nullptr) return;
321
322 int64_t featureCombination = encodeSessionConfiguration(sessionConfiguration);
323 int queryStatus = ret.isOk() ? OK : ret.serviceSpecificErrorCode();
324 CameraFeatureCombinationStats stats;
325 stats.mCameraId = cameraId;
326 stats.mUid = clientUid;
327 stats.mFeatureCombination = featureCombination;
328 stats.mQueryType = type;
329 stats.mStatus = queryStatus;
330
331 auto status = proxyBinder->notifyFeatureCombinationStats(stats);
332 if (!status.isOk()) {
333 ALOGE("%s: Failed to notify feature combination stats: %s", __FUNCTION__,
334 status.exceptionMessage().c_str());
335 }
336 }
337
338 int CameraServiceProxyWrapper::getRotateAndCropOverride(const std::string &packageName,
339 int lensFacing, int userId) {
340 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
341 if (proxyBinder == nullptr) return true;
342 int ret = 0;
343 auto status = proxyBinder->getRotateAndCropOverride(packageName, lensFacing,
344 userId, &ret);
345 if (!status.isOk()) {
346 ALOGE("%s: Failed during top activity orientation query: %s", __FUNCTION__,
347 status.exceptionMessage().c_str());
348 }
349
350 return ret;
351 }
352
353 int CameraServiceProxyWrapper::getAutoframingOverride(const std::string& packageName) {
354 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
355 if (proxyBinder == nullptr) {
356 return ANDROID_CONTROL_AUTOFRAMING_OFF;
357 }
358 int ret = 0;
359 auto status = proxyBinder->getAutoframingOverride(packageName, &ret);
360 if (!status.isOk()) {
361 ALOGE("%s: Failed during autoframing override query: %s", __FUNCTION__,
362 status.exceptionMessage().c_str());
363 }
364
365 return ret;
366 }
367
368 void CameraServiceProxyWrapper::logStreamConfigured(const std::string& id,
369 int operatingMode, bool internalConfig, int32_t latencyMs) {
370 std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
371 {
372 Mutex::Autolock l(mLock);
373 if (mSessionStatsMap.count(id) == 0) {
374 ALOGE("%s: SessionStatsMap should contain camera %s",
375 __FUNCTION__, id.c_str());
376 return;
377 }
378 sessionStats = mSessionStatsMap[id];
379 }
380
381 ALOGV("%s: id %s, operatingMode %d, internalConfig %d, latencyMs %d",
382 __FUNCTION__, id.c_str(), operatingMode, internalConfig, latencyMs);
383 sessionStats->onStreamConfigured(operatingMode, internalConfig, latencyMs);
384 }
385
386 void CameraServiceProxyWrapper::logActive(const std::string& id, float maxPreviewFps) {
387 std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
388 {
389 Mutex::Autolock l(mLock);
390 if (mSessionStatsMap.count(id) == 0) {
391 ALOGE("%s: SessionStatsMap should contain camera %s when logActive is called",
392 __FUNCTION__, id.c_str());
393 return;
394 }
395 sessionStats = mSessionStatsMap[id];
396 }
397
398 ALOGV("%s: id %s", __FUNCTION__, id.c_str());
399 sp<hardware::ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
400 sessionStats->onActive(proxyBinder, maxPreviewFps);
401 }
402
403 void CameraServiceProxyWrapper::logIdle(const std::string& id,
404 int64_t requestCount, int64_t resultErrorCount, bool deviceError,
405 const std::string& userTag, int32_t videoStabilizationMode, bool usedUltraWide,
406 bool usedZoomOverride, std::pair<int32_t, int32_t> mostRequestedFpsRange,
407 const std::vector<hardware::CameraStreamStats>& streamStats) {
408 std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
409 {
410 Mutex::Autolock l(mLock);
411 if (mSessionStatsMap.count(id) == 0) {
412 ALOGE("%s: SessionStatsMap should contain camera %s when logIdle is called",
413 __FUNCTION__, id.c_str());
414 return;
415 }
416 sessionStats = mSessionStatsMap[id];
417 }
418
419 ALOGV("%s: id %s, requestCount %" PRId64 ", resultErrorCount %" PRId64 ", deviceError %d"
420 ", userTag %s, videoStabilizationMode %d, most common FPS [%d,%d]",
421 __FUNCTION__, id.c_str(), requestCount, resultErrorCount, deviceError, userTag.c_str(),
422 videoStabilizationMode, mostRequestedFpsRange.first, mostRequestedFpsRange.second);
423 for (size_t i = 0; i < streamStats.size(); i++) {
424 ALOGV("%s: streamStats[%zu]: w %d h %d, requestedCount %" PRId64 ", dropCount %"
425 PRId64 ", startTimeMs %d" ,
426 __FUNCTION__, i, streamStats[i].mWidth, streamStats[i].mHeight,
427 streamStats[i].mRequestCount, streamStats[i].mErrorCount,
428 streamStats[i].mStartLatencyMs);
429 }
430
431 sp<hardware::ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
432 sessionStats->onIdle(proxyBinder, requestCount, resultErrorCount, deviceError, userTag,
433 videoStabilizationMode, usedUltraWide, usedZoomOverride,
434 mostRequestedFpsRange, streamStats);
435 }
436
437 void CameraServiceProxyWrapper::logOpen(const std::string& id, int facing,
438 const std::string& clientPackageName, int effectiveApiLevel, bool isNdk,
439 int32_t latencyMs) {
440 std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
441 {
442 Mutex::Autolock l(mLock);
443 if (mSessionStatsMap.count(id) > 0) {
444 ALOGE("%s: SessionStatsMap shouldn't contain camera %s",
445 __FUNCTION__, id.c_str());
446 return;
447 }
448
449 int apiLevel = CameraSessionStats::CAMERA_API_LEVEL_1;
450 if (effectiveApiLevel == 2) {
451 apiLevel = CameraSessionStats::CAMERA_API_LEVEL_2;
452 }
453
454 // Generate a new log ID for open events
455 int64_t logId = generateLogId(mRandomDevice);
456
457 sessionStats = std::make_shared<CameraSessionStatsWrapper>(
458 id, facing, CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
459 apiLevel, isNdk, latencyMs, logId);
460 mSessionStatsMap.emplace(id, sessionStats);
461 ALOGV("%s: Adding id %s", __FUNCTION__, id.c_str());
462 }
463
464 ALOGV("%s: id %s, facing %d, effectiveApiLevel %d, isNdk %d, latencyMs %d",
465 __FUNCTION__, id.c_str(), facing, effectiveApiLevel, isNdk, latencyMs);
466 sp<hardware::ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
467 sessionStats->onOpen(proxyBinder);
468 }
469
470 void CameraServiceProxyWrapper::logClose(const std::string& id, int32_t latencyMs,
471 bool deviceError) {
472 std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
473 {
474 Mutex::Autolock l(mLock);
475 if (mSessionStatsMap.count(id) == 0) {
476 ALOGE("%s: SessionStatsMap should contain camera %s before it's closed",
477 __FUNCTION__, id.c_str());
478 return;
479 }
480
481 sessionStats = mSessionStatsMap[id];
482 if (sessionStats == nullptr) {
483 ALOGE("%s: SessionStatsMap should contain camera %s",
484 __FUNCTION__, id.c_str());
485 return;
486 }
487
488 mSessionStatsMap.erase(id);
489 ALOGV("%s: Erasing id %s, deviceError %d", __FUNCTION__, id.c_str(), deviceError);
490 }
491
492 ALOGV("%s: id %s, latencyMs %d, deviceError %d", __FUNCTION__,
493 id.c_str(), latencyMs, deviceError);
494 sp<hardware::ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
495 sessionStats->onClose(proxyBinder, latencyMs, deviceError);
496 }
497
498 bool CameraServiceProxyWrapper::isCameraDisabled(int userId) {
499 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
500 if (proxyBinder == nullptr) return true;
501 bool ret = false;
502 auto status = proxyBinder->isCameraDisabled(userId, &ret);
503 if (!status.isOk()) {
504 ALOGE("%s: Failed during camera disabled query: %s", __FUNCTION__,
505 status.exceptionMessage().c_str());
506 }
507 return ret;
508 }
509
510 int64_t CameraServiceProxyWrapper::getCurrentLogIdForCamera(const std::string& cameraId) {
511 std::shared_ptr<CameraSessionStatsWrapper> stats;
512 {
513 Mutex::Autolock _l(mLock);
514 if (mSessionStatsMap.count(cameraId) == 0) {
515 ALOGE("%s: SessionStatsMap should contain camera %s before asking for its logging ID.",
516 __FUNCTION__, cameraId.c_str());
517 return 0;
518 }
519
520 stats = mSessionStatsMap[cameraId];
521 }
522 return stats->getLogId();
523 }
524
525 int64_t CameraServiceProxyWrapper::generateLogId(std::random_device& randomDevice) {
526 int64_t ret = 0;
527 do {
528 // std::random_device generates 32 bits per call, so we call it twice
529 ret = randomDevice();
530 ret = ret << 32;
531 ret = ret | randomDevice();
532 } while (ret == 0); // 0 is not a valid identifier
533
534 return ret;
535 }
536
537 std::string CameraServiceProxyWrapper::updateExtensionStats(
538 const hardware::CameraExtensionSessionStats& extStats) {
539 std::shared_ptr<CameraSessionStatsWrapper> stats;
540 std::string cameraId = toStdString(extStats.cameraId);
541 {
542 Mutex::Autolock _l(mLock);
543 if (mSessionStatsMap.count(cameraId) == 0) {
544 ALOGE("%s CameraExtensionSessionStats reported for camera id that isn't open: %s",
545 __FUNCTION__, cameraId.c_str());
546 return {};
547 }
548
549 stats = mSessionStatsMap[cameraId];
550 return stats->updateExtensionSessionStats(extStats);
551 }
552 }
553
554 } // namespace android
555