1 /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "QCameraPerf"
31
32 // To remove
33 #include <cutils/properties.h>
34 #include <utils/Errors.h>
35
36 // System dependencies
37 #include <stdlib.h>
38 #include <dlfcn.h>
39 #include <utils/Timers.h>
40
41 #include <aidl/android/hardware/power/Boost.h>
42 #include <aidl/android/hardware/power/IPower.h>
43 #include <aidl/android/hardware/power/Mode.h>
44 #include <android/binder_manager.h>
45 #include <android-base/properties.h>
46
47 // Camera dependencies
48 #include "QCameraPerf.h"
49 #include "QCameraTrace.h"
50
51 extern "C" {
52 #include "mm_camera_dbg.h"
53 }
54
55 namespace qcamera {
56
57 using aidl::android::hardware::power::Boost;
58 using aidl::android::hardware::power::Mode;
59
60 // Protect gPowerHal_1_2_ and gPowerHal_Aidl_
61 static android::sp<android::hardware::power::V1_2::IPower> gPowerHal_1_2_ = nullptr;
62 static std::shared_ptr<aidl::android::hardware::power::IPower> gPowerHal_Aidl_ = nullptr;
63 static std::mutex gPowerHalMutex;
64 static const std::string kInstance =
65 std::string() + aidl::android::hardware::power::IPower::descriptor + "/default";
66
67 namespace {
68 constexpr int kDefaultBoostDurationMs = 1000;
69 constexpr int kDisableBoostDurationMs = -1;
70 }
71
72 enum hal_version {
73 NONE,
74 HIDL_1_2,
75 AIDL,
76 };
77
78 // Connnect PowerHAL
connectPowerHalLocked()79 static hal_version connectPowerHalLocked() {
80 static bool gPowerHalHidlExists = true;
81 static bool gPowerHalAidlExists = true;
82
83 if (!gPowerHalHidlExists && !gPowerHalAidlExists) {
84 return NONE;
85 }
86
87 if (gPowerHalHidlExists) {
88 if (!gPowerHal_1_2_) {
89 gPowerHal_1_2_ =
90 android::hardware::power::V1_2::IPower::getService();
91 }
92 if (gPowerHal_1_2_) {
93 ALOGV("Successfully connected to Power Hal Hidl service.");
94 return HIDL_1_2;
95 } else {
96 gPowerHalHidlExists = false;
97 }
98 }
99
100 if (gPowerHalAidlExists) {
101 if (!gPowerHal_Aidl_) {
102 ndk::SpAIBinder pwBinder = ndk::SpAIBinder(AServiceManager_getService(kInstance.c_str()));
103 gPowerHal_Aidl_ = aidl::android::hardware::power::IPower::fromBinder(pwBinder);
104 }
105 if (gPowerHal_Aidl_) {
106 ALOGV("Successfully connected to Power Hal Aidl service.");
107 return AIDL;
108 } else {
109 gPowerHalAidlExists = false;
110 }
111 }
112
113 return NONE;
114 }
115
116 typedef enum {
117 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0 = 0x40800000,
118 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_1 = 0x40800010,
119 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_2 = 0x40800020,
120 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_3 = 0x40800030,
121 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40800100,
122 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40800110,
123 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40800120,
124 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40800130,
125
126 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0 = 0x40804000,
127 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_1 = 0x40804010,
128 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_2 = 0x40804020,
129 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_3 = 0x40804030,
130 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40804100,
131 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40804110,
132 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40804120,
133 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40804130,
134
135 MPCTLV3_MIN_ONLINE_CPU_CLUSTER_BIG = 0x41000000,
136 MPCTLV3_MIN_ONLINE_CPU_CLUSTER_LITTLE = 0x41000100,
137 MPCTLV3_MAX_ONLINE_CPU_CLUSTER_BIG = 0x41004000,
138 MPCTLV3_MAX_ONLINE_CPU_CLUSTER_LITTLE = 0x41004100,
139
140 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS = 0x40400000,
141 MPCTLV3_CPUBW_HWMON_MIN_FREQ = 0x41800000,
142 MPCTLV3_CPUBW_HWMON_HYST_OPT = 0x4180C000
143 } perf_lock_params;
144
145
146 static int32_t perfLockParamsOpenCamera[] = {
147 // Disable power collapse and set CPU cloks to turbo
148 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1,
149 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
150 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
151 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
152 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF
153 };
154
155 static int32_t perfLockParamsCloseCamera[] = {
156 // Disable power collapse and set CPU cloks to turbo
157 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1,
158 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
159 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
160 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
161 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF
162 };
163
164 static int32_t perfLockParamsStartPreview[] = {
165 // Disable power collapse and set CPU cloks to turbo
166 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1,
167 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
168 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
169 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
170 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF
171 };
172
173 static int32_t perfLockParamsTakeSnapshot[] = {
174 // Disable power collapse and set CPU cloks to turbo
175 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1,
176 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
177 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF,
178 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
179 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
180 MPCTLV3_CPUBW_HWMON_HYST_OPT, 0x0,
181 MPCTLV3_CPUBW_HWMON_MIN_FREQ, 0x8C
182 };
183
184 PerfLockInfo QCameraPerfLock::mPerfLockInfo[] = {
185 { //PERF_LOCK_OPEN_CAMERA
186 perfLockParamsOpenCamera,
187 sizeof(perfLockParamsOpenCamera)/sizeof(int32_t) },
188 { //PERF_LOCK_CLOSE_CAMERA
189 perfLockParamsCloseCamera,
190 sizeof(perfLockParamsCloseCamera)/sizeof(int32_t) },
191 { //PERF_LOCK_START_PREVIEW
192 perfLockParamsStartPreview,
193 sizeof(perfLockParamsStartPreview)/sizeof(int32_t) },
194 { //PERF_LOCK_TAKE_SNAPSHOT
195 perfLockParamsTakeSnapshot,
196 sizeof(perfLockParamsTakeSnapshot)/sizeof(int32_t) },
197 { //PERF_LOCK_POWERHINT_PREVIEW
198 NULL, 0},
199 { //PERF_LOCK_POWERHINT_ENCODE
200 NULL, 0}
201 };
202
203 Mutex QCameraPerfLockIntf::mMutex;
204 QCameraPerfLockIntf* QCameraPerfLockIntf::mInstance = NULL;
205
206
207 /*===========================================================================
208 * FUNCTION : QCameraPerfLockMgr constructor
209 *
210 * DESCRIPTION: Initialize the perf locks
211 *
212 * PARAMETERS : None
213 *
214 * RETURN : void
215 *
216 *==========================================================================*/
QCameraPerfLockMgr()217 QCameraPerfLockMgr::QCameraPerfLockMgr() :
218 mState(LOCK_MGR_STATE_UNINITIALIZED)
219 {
220 for (int i = 0; i < PERF_LOCK_COUNT; ++i) {
221 mPerfLock[i] = QCameraPerfLock::create((PerfLockEnum)i);
222
223 if (mPerfLock[i] == NULL) {
224 mState = LOCK_MGR_STATE_ERROR;
225 LOGE("Could not allocate perf locks");
226
227 // Set the remaining perf locks to NULL
228 for (int j = i+1; j < PERF_LOCK_COUNT; ++j) {
229 mPerfLock[j] = NULL;
230 }
231 return;
232 }
233 }
234 mState = LOCK_MGR_STATE_READY;
235 }
236
237
238 /*===========================================================================
239 * FUNCTION : QCameraPerfLockMgr destructor
240 *
241 * DESCRIPTION: class destructor
242 *
243 * PARAMETERS : None
244 *
245 * RETURN : void
246 *
247 *==========================================================================*/
~QCameraPerfLockMgr()248 QCameraPerfLockMgr::~QCameraPerfLockMgr()
249 {
250 for (int i = 0; i < PERF_LOCK_COUNT; ++i) {
251 if (mPerfLock[i]) {
252 delete mPerfLock[i];
253 }
254 }
255 }
256
257
258 /*===========================================================================
259 * FUNCTION : acquirePerfLock
260 *
261 * DESCRIPTION: Call acquirePerfLock function for the requested perf lock
262 *
263 * PARAMETERS :
264 * @perfLockType: Perf lock enum
265 * @timer: Timer value in ms
266 *
267 * RETURN : true on success
268 * false on failure
269 *==========================================================================*/
acquirePerfLock(PerfLockEnum perfLockType,uint32_t timer)270 bool QCameraPerfLockMgr::acquirePerfLock(
271 PerfLockEnum perfLockType,
272 uint32_t timer)
273 {
274 bool ret = false;
275 if ((mState == LOCK_MGR_STATE_READY) &&
276 isValidPerfLockEnum(perfLockType)) {
277 ret = mPerfLock[perfLockType]->acquirePerfLock(true, timer);
278 }
279 return ret;
280 }
281
282
283 /*===========================================================================
284 * FUNCTION : acquirePerfLockIfExpired
285 *
286 * DESCRIPTION: Call acquirePerfLock function for the requested perf lock
287 *
288 * PARAMETERS :
289 * @perfLockType: Type of perf lock
290 * @timer: Timer value in ms
291 *
292 * RETURN : true on success
293 * false on failure
294 *==========================================================================*/
acquirePerfLockIfExpired(PerfLockEnum perfLockType,uint32_t timer)295 bool QCameraPerfLockMgr::acquirePerfLockIfExpired(
296 PerfLockEnum perfLockType,
297 uint32_t timer)
298 {
299 bool ret = false;
300 if ((mState == LOCK_MGR_STATE_READY) &&
301 isValidPerfLockEnum(perfLockType)) {
302 ret = mPerfLock[perfLockType]->acquirePerfLock(false, timer);
303 }
304 return ret;
305
306 }
307
308
309 /*===========================================================================
310 * FUNCTION : releasePerfLock
311 *
312 * DESCRIPTION: Call releasePerfLock function for the requested perf lock
313 *
314 * PARAMETERS :
315 * @perfLockType: Enum of perf lock
316 *
317 * RETURN : true on success
318 * false on failure
319 *==========================================================================*/
releasePerfLock(PerfLockEnum perfLockType)320 bool QCameraPerfLockMgr::releasePerfLock(
321 PerfLockEnum perfLockType)
322 {
323 bool ret = false;
324 if ((mState == LOCK_MGR_STATE_READY) &&
325 isValidPerfLockEnum(perfLockType)) {
326 ret = mPerfLock[perfLockType]->releasePerfLock();
327 }
328 return ret;
329 }
330
331
332 /*===========================================================================
333 * FUNCTION : powerHintInternal
334 *
335 * DESCRIPTION: Calls the appropriate perf lock's powerHintInternal function
336 *
337 * PARAMETERS :
338 * @perfLockType: Type of perf lock
339 * @hint : Power hint
340 * @enable : Enable power hint if set to 1. Disable if set to 0.
341 *
342 * RETURN : void
343 *
344 *==========================================================================*/
powerHintInternal(PerfLockEnum perfLockType,PowerHint powerHint,int32_t time_out)345 void QCameraPerfLockMgr::powerHintInternal(
346 PerfLockEnum perfLockType,
347 PowerHint powerHint,
348 int32_t time_out)
349 {
350 if ((mState == LOCK_MGR_STATE_READY) &&
351 isValidPerfLockEnum(perfLockType)) {
352 mPerfLock[perfLockType]->powerHintInternal(powerHint, time_out);
353 }
354 }
355
356
357 /*===========================================================================
358 * FUNCTION : create
359 *
360 * DESCRIPTION: This is a static method to create perf lock object. It calls
361 * protected constructor of the class and only returns a valid object
362 * if it can successfully initialize the perf lock.
363 *
364 * PARAMETERS : None
365 *
366 * RETURN : QCameraPerfLock object pointer on success
367 * NULL on failure
368 *
369 *==========================================================================*/
create(PerfLockEnum perfLockType)370 QCameraPerfLock* QCameraPerfLock::create(
371 PerfLockEnum perfLockType)
372 {
373 QCameraPerfLock *perfLock = NULL;
374
375 if (perfLockType < PERF_LOCK_COUNT) {
376 QCameraPerfLockIntf *perfLockIntf = QCameraPerfLockIntf::createSingleton();
377 if (perfLockIntf) {
378 perfLock = new QCameraPerfLock(perfLockType, perfLockIntf);
379 }
380 }
381 return perfLock;
382 }
383
384
385 /*===========================================================================
386 * FUNCTION : QCameraPerfLock constructor
387 *
388 * DESCRIPTION: Initialize member variables
389 *
390 * PARAMETERS : None
391 *
392 * RETURN : void
393 *
394 *==========================================================================*/
QCameraPerfLock(PerfLockEnum perfLockType,QCameraPerfLockIntf * perfLockIntf)395 QCameraPerfLock::QCameraPerfLock(
396 PerfLockEnum perfLockType,
397 QCameraPerfLockIntf *perfLockIntf) :
398 mHandle(0),
399 mRefCount(0),
400 mTimeOut(0),
401 mPerfLockType(perfLockType),
402 mPerfLockIntf(perfLockIntf)
403 {
404 mIsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false);
405 }
406
407
408 /*===========================================================================
409 * FUNCTION : QCameraPerfLock destructor
410 *
411 * DESCRIPTION: class destructor
412 *
413 * PARAMETERS : None
414 *
415 * RETURN : void
416 *
417 *==========================================================================*/
~QCameraPerfLock()418 QCameraPerfLock::~QCameraPerfLock()
419 {
420 if (mHandle > 0) {
421 (*mPerfLockIntf->perfLockRel())(mHandle);
422 }
423 QCameraPerfLockIntf::deleteInstance();
424 }
425
426
427 /*===========================================================================
428 * FUNCTION : isTimedOut
429 *
430 * DESCRIPTION: Check if the perf lock is timed out
431 *
432 * PARAMETERS : None
433 *
434 * RETURN : boolean indicating if the perf lock is timed out
435 *
436 *==========================================================================*/
isTimedOut()437 bool QCameraPerfLock::isTimedOut()
438 {
439 if (mTimeOut && (systemTime() > mTimeOut)) {
440 return true;
441 }
442 return false;
443 }
444
445
446 /*===========================================================================
447 * FUNCTION : restartTimer
448 *
449 * DESCRIPTION: Restart the timer for the duration specified
450 *
451 * PARAMETERS :
452 * @timer : timer duration in milliseconds
453 *
454 * RETURN : void
455 *
456 *==========================================================================*/
restartTimer(uint32_t timer)457 void inline QCameraPerfLock::restartTimer(
458 uint32_t timer)
459 {
460 if (timer > 0) {
461 mTimeOut = systemTime() + ms2ns(timer);
462 }
463 }
464
465
466 /*===========================================================================
467 * FUNCTION : acquirePerfLock
468 *
469 * DESCRIPTION: Acquires the perf lock for the duration specified. Do not acquire
470 * the perf lock is reacquire flag is set to false provided the perf
471 * lock is already acquired.
472 *
473 * PARAMETERS :
474 * @forceReaquirePerfLock: Reacquire
475 * @timer : Duration of the perf lock
476 *
477 * RETURN : true on success
478 * false on failure
479 *
480 *==========================================================================*/
acquirePerfLock(bool forceReaquirePerfLock,uint32_t timer)481 bool QCameraPerfLock::acquirePerfLock(
482 bool forceReaquirePerfLock,
483 uint32_t timer)
484 {
485 bool ret = true;
486 Mutex::Autolock lock(mMutex);
487
488 switch (mPerfLockType) {
489 case PERF_LOCK_POWERHINT_PREVIEW:
490 case PERF_LOCK_POWERHINT_ENCODE:
491 powerHintInternal(PowerHint::CAMERA_STREAMING, true);
492 return true;
493 case PERF_LOCK_OPEN_CAMERA:
494 case PERF_LOCK_CLOSE_CAMERA:
495 powerHintInternal(PowerHint::CAMERA_LAUNCH, timer);
496 return true;
497 case PERF_LOCK_START_PREVIEW:
498 powerHintInternal(PowerHint::CAMERA_SHOT, timer);
499 return true;
500 case PERF_LOCK_TAKE_SNAPSHOT:
501 powerHintInternal(PowerHint::CAMERA_SHOT, timer);
502 return true;
503 default:
504 LOGE("Unknown powerhint %d",(int)mPerfLockType);
505 return false;
506 }
507
508 if (!mIsPerfdEnabled) return ret;
509
510 if (isTimedOut()) {
511 mHandle = 0;
512 mRefCount = 0;
513 }
514
515 if ((mRefCount == 0) || forceReaquirePerfLock) {
516 mHandle = (*mPerfLockIntf->perfLockAcq())(
517 mHandle, timer,
518 mPerfLockInfo[mPerfLockType].perfLockParams,
519 mPerfLockInfo[mPerfLockType].perfLockParamsCount);
520
521 if (mHandle > 0) {
522 ++mRefCount;
523 restartTimer(timer);
524 LOGD("perfLockHandle %d, updated refCount: %d, perfLockType: %d",
525 mHandle, mRefCount, mPerfLockType);
526 } else {
527 LOGE("Failed to acquire the perf lock");
528 ret = false;
529 }
530 } else {
531 LOGD("Perf lock already acquired, not re-aquiring");
532 }
533
534 return ret;
535 }
536
537
538 /*===========================================================================
539 * FUNCTION : releasePerfLock
540 *
541 * DESCRIPTION: Releases the perf lock
542 *
543 * PARAMETERS : None
544 *
545 * RETURN : true on success
546 * false on failure
547 *
548 *==========================================================================*/
releasePerfLock()549 bool QCameraPerfLock::releasePerfLock()
550 {
551 bool ret = true;
552 Mutex::Autolock lock(mMutex);
553
554 switch (mPerfLockType) {
555 case PERF_LOCK_POWERHINT_PREVIEW:
556 case PERF_LOCK_POWERHINT_ENCODE:
557 powerHintInternal(PowerHint::CAMERA_STREAMING, false);
558 return true;
559 case PERF_LOCK_OPEN_CAMERA:
560 case PERF_LOCK_CLOSE_CAMERA:
561 powerHintInternal(PowerHint::CAMERA_LAUNCH, false);
562 return true;
563 case PERF_LOCK_START_PREVIEW:
564 powerHintInternal(PowerHint::CAMERA_SHOT, false);
565 return true;
566 case PERF_LOCK_TAKE_SNAPSHOT:
567 powerHintInternal(PowerHint::CAMERA_SHOT, false);
568 return true;
569 default:
570 LOGE("Unknown powerhint %d",(int)mPerfLockType);
571 return false;
572 }
573
574 if (!mIsPerfdEnabled) return ret;
575
576 if (mHandle > 0) {
577 LOGD("perfLockHandle %d, refCount: %d, perfLockType: %d",
578 mHandle, mRefCount, mPerfLockType);
579
580 if (isTimedOut()) {
581 mHandle = 0;
582 mRefCount = 0;
583 } else if (--mRefCount == 0) {
584 int32_t rc = (*mPerfLockIntf->perfLockRel())(mHandle);
585 mHandle = 0;
586 mTimeOut = 0;
587 if (rc < 0) {
588 LOGE("Failed to release the perf lock");
589 ret = false;
590 }
591 }
592 } else {
593 LOGW("Perf lock %d either not acquired or already released", mPerfLockType);
594 }
595
596 return ret;
597 }
598
599
600 /*===========================================================================
601 * FUNCTION : powerHintInternal
602 *
603 * DESCRIPTION: Sets the requested power hint and state to power HAL.
604 *
605 * PARAMETERS :
606 * @hint : Power hint
607 * @enable : Enable power hint if set to 1. Disable if set to 0.
608 *
609 * RETURN : void
610 *
611 *==========================================================================*/
powerHintInternal(PowerHint powerHint,int32_t time_out)612 void QCameraPerfLock::powerHintInternal(
613 PowerHint powerHint,
614 int32_t time_out)
615 {
616 #ifdef HAS_MULTIMEDIA_HINTS
617 if (!mPerfLockIntf->powerHint(powerHint, time_out)) {
618 LOGE("Send powerhint to PowerHal failed");
619 }
620 #endif
621 }
622
623
624
625 /*===========================================================================
626 * FUNCTION : createSingleton
627 *
628 * DESCRIPTION: Open the perf lock library, query the function pointers and
629 * create a singleton object upon success
630 *
631 * PARAMETERS : None
632 *
633 * RETURN : QCameraPerfLockIntf object pointer on success
634 * NULL on failure
635 *
636 *==========================================================================*/
createSingleton()637 QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton()
638 {
639 bool error = true;
640 Mutex::Autolock lock(mMutex);
641
642 if (mInstance == NULL) {
643 // Open perflock library and query for the function pointers
644 uint32_t perfLockEnable = 0;
645 char value[PROPERTY_VALUE_MAX];
646
647 property_get("persist.camera.perflock.enable", value, "1");
648 perfLockEnable = atoi(value);
649
650 if (perfLockEnable) {
651 mInstance = new QCameraPerfLockIntf();
652 if (mInstance) {
653 #ifdef HAS_MULTIMEDIA_HINTS
654 std::lock_guard<std::mutex> lock(gPowerHalMutex);
655 if (connectPowerHalLocked() == NONE) {
656 ALOGE("Couldn't load PowerHAL module");
657 } else {
658 error = false;
659 }
660 #else
661 {
662 /* Retrieve the name of the vendor extension library */
663 void *dlHandle = NULL;
664 if ((property_get("ro.vendor.extension_library", value, NULL) > 0) &&
665 (dlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL))) {
666
667 perfLockAcquire pLockAcq = (perfLockAcquire)dlsym(dlHandle, "perf_lock_acq");
668 perfLockRelease pLockRel = (perfLockRelease)dlsym(dlHandle, "perf_lock_rel");
669
670 if (pLockAcq && pLockRel) {
671 mInstance->mDlHandle = dlHandle;
672 mInstance->mPerfLockAcq = pLockAcq;
673 mInstance->mPerfLockRel = pLockRel;
674 error = false;
675 } else {
676 LOGE("Failed to link the symbols- perf_lock_acq, perf_lock_rel");
677 bool IsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false);
678 if (!IsPerfdEnabled) {
679 mInstance->mDlHandle = nullptr;
680 mInstance->mPerfLockAcq = nullptr;
681 mInstance->mPerfLockRel = nullptr;
682 error = false;
683 }
684 }
685 } else {
686 LOGE("Unable to load lib: %s", value);
687 }
688 }
689 #endif
690 if (error && mInstance) {
691 delete mInstance;
692 mInstance = NULL;
693 }
694 }
695 }
696 }
697
698 if (mInstance) {
699 ++(mInstance->mRefCount);
700 }
701
702 return mInstance;
703 }
704
705
706 /*===========================================================================
707 * FUNCTION : deleteInstance
708 *
709 * DESCRIPTION: Delete the object if refCount is 0
710 *
711 * PARAMETERS : None
712 *
713 * RETURN : void
714 *
715 *==========================================================================*/
deleteInstance()716 void QCameraPerfLockIntf::deleteInstance()
717 {
718 Mutex::Autolock lock(mMutex);
719
720 if (mInstance && (--(mInstance->mRefCount) == 0)) {
721 delete mInstance;
722 mInstance = NULL;
723 }
724 }
725
726
727 /*===========================================================================
728 * FUNCTION : QCameraPerfLockIntf destructor
729 *
730 * DESCRIPTION: class destructor
731 *
732 * PARAMETERS : None
733 *
734 * RETURN : void
735 *
736 *==========================================================================*/
~QCameraPerfLockIntf()737 QCameraPerfLockIntf::~QCameraPerfLockIntf()
738 {
739 if (mDlHandle) {
740 dlclose(mDlHandle);
741 }
742 }
743
powerHint(PowerHint hint,int32_t data)744 bool QCameraPerfLockIntf::powerHint(PowerHint hint, int32_t data) {
745 std::lock_guard<std::mutex> lock(gPowerHalMutex);
746 switch(connectPowerHalLocked()) {
747 case NONE:
748 return false;
749 case HIDL_1_2:
750 {
751 auto ret = gPowerHal_1_2_->powerHintAsync_1_2(hint, data);
752 if (!ret.isOk()) {
753 ALOGE("powerHint failed, error: %s",
754 ret.description().c_str());
755 gPowerHal_1_2_ = nullptr;
756 }
757 return ret.isOk();
758 }
759 case AIDL:
760 {
761 bool ret = false;
762 if (hint == PowerHint::CAMERA_LAUNCH) {
763 int32_t durationMs = data ? kDefaultBoostDurationMs : kDisableBoostDurationMs;
764 ret = gPowerHal_Aidl_->setBoost(Boost::CAMERA_LAUNCH, durationMs).isOk();
765 } else if (hint == PowerHint::CAMERA_SHOT) {
766 ret = gPowerHal_Aidl_->setBoost(Boost::CAMERA_SHOT, data).isOk();
767 } else if (hint == PowerHint::CAMERA_STREAMING) {
768 // Only CAMERA_STREAMING_MID is used
769 ret = gPowerHal_Aidl_->setMode(Mode::CAMERA_STREAMING_MID, static_cast<bool>(data)).isOk();
770 }
771 if (!ret) {
772 ALOGE("Failed to set power hint: %s.", toString(hint).c_str());
773 gPowerHal_Aidl_ = nullptr;
774 }
775 return ret;
776 }
777 default:
778 ALOGE("Unknown HAL state");
779 return false;
780 }
781 }
782
783 }; // namespace qcamera
784