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// Camera dependencies 41#include "QCameraPerf.h" 42#include "QCameraTrace.h" 43 44#include <android-base/properties.h> 45 46extern "C" { 47#include "mm_camera_dbg.h" 48} 49 50namespace qcamera { 51 52using android::hidl::base::V1_0::IBase; 53using android::hardware::hidl_death_recipient; 54 55static std::mutex gPowerHalMutex; 56static sp<IPower> gPowerHal = nullptr; 57static void getPowerHalLocked(); 58 59// struct PowerHalDeathRecipient; 60struct PowerHalDeathRecipient : virtual public hidl_death_recipient { 61 // hidl_death_recipient interface 62 virtual void serviceDied(uint64_t, const wp<IBase>&) override { 63 std::lock_guard<std::mutex> lock(gPowerHalMutex); 64 ALOGE("PowerHAL just died"); 65 gPowerHal = nullptr; 66 getPowerHalLocked(); 67 } 68}; 69 70sp<PowerHalDeathRecipient> gPowerHalDeathRecipient = nullptr; 71 72// The caller must be holding gPowerHalMutex. 73static void getPowerHalLocked() { 74 if (gPowerHal != nullptr) { 75 return; 76 } 77 78 gPowerHal = IPower::getService(); 79 80 if (gPowerHal == nullptr) { 81 ALOGE("Unable to get Power service."); 82 } else { 83 if (gPowerHalDeathRecipient == nullptr) { 84 gPowerHalDeathRecipient = new PowerHalDeathRecipient(); 85 } 86 hardware::Return<bool> linked = gPowerHal->linkToDeath( 87 gPowerHalDeathRecipient, 0x451F /* cookie */); 88 if (!linked.isOk()) { 89 ALOGE("Transaction error in linking to PowerHAL death: %s", 90 linked.description().c_str()); 91 gPowerHal = nullptr; 92 } else if (!linked) { 93 ALOGW("Unable to link to PowerHal death notifications"); 94 gPowerHal = nullptr; 95 } else { 96 ALOGD("Link to death notification successful"); 97 } 98 } 99} 100 101typedef enum { 102 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0 = 0x40800000, 103 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_1 = 0x40800010, 104 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_2 = 0x40800020, 105 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_3 = 0x40800030, 106 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40800100, 107 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40800110, 108 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40800120, 109 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40800130, 110 111 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0 = 0x40804000, 112 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_1 = 0x40804010, 113 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_2 = 0x40804020, 114 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_3 = 0x40804030, 115 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40804100, 116 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40804110, 117 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40804120, 118 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40804130, 119 120 MPCTLV3_MIN_ONLINE_CPU_CLUSTER_BIG = 0x41000000, 121 MPCTLV3_MIN_ONLINE_CPU_CLUSTER_LITTLE = 0x41000100, 122 MPCTLV3_MAX_ONLINE_CPU_CLUSTER_BIG = 0x41004000, 123 MPCTLV3_MAX_ONLINE_CPU_CLUSTER_LITTLE = 0x41004100, 124 125 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS = 0x40400000, 126 MPCTLV3_CPUBW_HWMON_MIN_FREQ = 0x41800000, 127 MPCTLV3_CPUBW_HWMON_HYST_OPT = 0x4180C000 128} perf_lock_params; 129 130 131static int32_t perfLockParamsOpenCamera[] = { 132 // Disable power collapse and set CPU cloks to turbo 133 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 134 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 135 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 136 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 137 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF 138}; 139 140static int32_t perfLockParamsCloseCamera[] = { 141 // Disable power collapse and set CPU cloks to turbo 142 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 143 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 144 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 145 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 146 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF 147}; 148 149static int32_t perfLockParamsStartPreview[] = { 150 // Disable power collapse and set CPU cloks to turbo 151 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 152 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 153 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 154 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 155 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF 156}; 157 158static int32_t perfLockParamsTakeSnapshot[] = { 159 // Disable power collapse and set CPU cloks to turbo 160 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 161 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 162 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 163 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 164 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 165 MPCTLV3_CPUBW_HWMON_HYST_OPT, 0x0, 166 MPCTLV3_CPUBW_HWMON_MIN_FREQ, 0x8C 167}; 168 169PerfLockInfo QCameraPerfLock::mPerfLockInfo[] = { 170 { //PERF_LOCK_OPEN_CAMERA 171 perfLockParamsOpenCamera, 172 sizeof(perfLockParamsOpenCamera)/sizeof(int32_t) }, 173 { //PERF_LOCK_CLOSE_CAMERA 174 perfLockParamsCloseCamera, 175 sizeof(perfLockParamsCloseCamera)/sizeof(int32_t) }, 176 { //PERF_LOCK_START_PREVIEW 177 perfLockParamsStartPreview, 178 sizeof(perfLockParamsStartPreview)/sizeof(int32_t) }, 179 { //PERF_LOCK_TAKE_SNAPSHOT 180 perfLockParamsTakeSnapshot, 181 sizeof(perfLockParamsTakeSnapshot)/sizeof(int32_t) }, 182 { //PERF_LOCK_POWERHINT_PREVIEW 183 NULL, 0}, 184 { //PERF_LOCK_POWERHINT_ENCODE 185 NULL, 0} 186 }; 187 188Mutex QCameraPerfLockIntf::mMutex; 189QCameraPerfLockIntf* QCameraPerfLockIntf::mInstance = NULL; 190 191 192/*=========================================================================== 193 * FUNCTION : QCameraPerfLockMgr constructor 194 * 195 * DESCRIPTION: Initialize the perf locks 196 * 197 * PARAMETERS : None 198 * 199 * RETURN : void 200 * 201 *==========================================================================*/ 202QCameraPerfLockMgr::QCameraPerfLockMgr() : 203 mState(LOCK_MGR_STATE_UNINITIALIZED) 204{ 205 for (int i = 0; i < PERF_LOCK_COUNT; ++i) { 206 mPerfLock[i] = QCameraPerfLock::create((PerfLockEnum)i); 207 208 if (mPerfLock[i] == NULL) { 209 mState = LOCK_MGR_STATE_ERROR; 210 LOGE("Could not allocate perf locks"); 211 212 // Set the remaining perf locks to NULL 213 for (int j = i+1; j < PERF_LOCK_COUNT; ++j) { 214 mPerfLock[j] = NULL; 215 } 216 return; 217 } 218 } 219 mState = LOCK_MGR_STATE_READY; 220} 221 222 223/*=========================================================================== 224 * FUNCTION : QCameraPerfLockMgr destructor 225 * 226 * DESCRIPTION: class destructor 227 * 228 * PARAMETERS : None 229 * 230 * RETURN : void 231 * 232 *==========================================================================*/ 233QCameraPerfLockMgr::~QCameraPerfLockMgr() 234{ 235 for (int i = 0; i < PERF_LOCK_COUNT; ++i) { 236 if (mPerfLock[i]) { 237 delete mPerfLock[i]; 238 } 239 } 240} 241 242 243/*=========================================================================== 244 * FUNCTION : acquirePerfLock 245 * 246 * DESCRIPTION: Call acquirePerfLock function for the requested perf lock 247 * 248 * PARAMETERS : 249 * @perfLockType: Perf lock enum 250 * @timer: Timer value in ms 251 * 252 * RETURN : true on success 253 * false on failure 254 *==========================================================================*/ 255bool QCameraPerfLockMgr::acquirePerfLock( 256 PerfLockEnum perfLockType, 257 uint32_t timer) 258{ 259 bool ret = false; 260 if ((mState == LOCK_MGR_STATE_READY) && 261 isValidPerfLockEnum(perfLockType)) { 262 ret = mPerfLock[perfLockType]->acquirePerfLock(true, timer); 263 } 264 return ret; 265} 266 267 268/*=========================================================================== 269 * FUNCTION : acquirePerfLockIfExpired 270 * 271 * DESCRIPTION: Call acquirePerfLock function for the requested perf lock 272 * 273 * PARAMETERS : 274 * @perfLockType: Type of perf lock 275 * @timer: Timer value in ms 276 * 277 * RETURN : true on success 278 * false on failure 279 *==========================================================================*/ 280bool QCameraPerfLockMgr::acquirePerfLockIfExpired( 281 PerfLockEnum perfLockType, 282 uint32_t timer) 283{ 284 bool ret = false; 285 if ((mState == LOCK_MGR_STATE_READY) && 286 isValidPerfLockEnum(perfLockType)) { 287 ret = mPerfLock[perfLockType]->acquirePerfLock(false, timer); 288 } 289 return ret; 290 291} 292 293 294/*=========================================================================== 295 * FUNCTION : releasePerfLock 296 * 297 * DESCRIPTION: Call releasePerfLock function for the requested perf lock 298 * 299 * PARAMETERS : 300 * @perfLockType: Enum of perf lock 301 * 302 * RETURN : true on success 303 * false on failure 304 *==========================================================================*/ 305bool QCameraPerfLockMgr::releasePerfLock( 306 PerfLockEnum perfLockType) 307{ 308 bool ret = false; 309 if ((mState == LOCK_MGR_STATE_READY) && 310 isValidPerfLockEnum(perfLockType)) { 311 ret = mPerfLock[perfLockType]->releasePerfLock(); 312 } 313 return ret; 314} 315 316 317/*=========================================================================== 318 * FUNCTION : powerHintInternal 319 * 320 * DESCRIPTION: Calls the appropriate perf lock's powerHintInternal function 321 * 322 * PARAMETERS : 323 * @perfLockType: Type of perf lock 324 * @hint : Power hint 325 * @enable : Enable power hint if set to 1. Disable if set to 0. 326 * 327 * RETURN : void 328 * 329 *==========================================================================*/ 330void QCameraPerfLockMgr::powerHintInternal( 331 PerfLockEnum perfLockType, 332 PowerHint powerHint, 333 int32_t time_out) 334{ 335 if ((mState == LOCK_MGR_STATE_READY) && 336 isValidPerfLockEnum(perfLockType)) { 337 mPerfLock[perfLockType]->powerHintInternal(powerHint, time_out); 338 } 339} 340 341 342/*=========================================================================== 343 * FUNCTION : create 344 * 345 * DESCRIPTION: This is a static method to create perf lock object. It calls 346 * protected constructor of the class and only returns a valid object 347 * if it can successfully initialize the perf lock. 348 * 349 * PARAMETERS : None 350 * 351 * RETURN : QCameraPerfLock object pointer on success 352 * NULL on failure 353 * 354 *==========================================================================*/ 355QCameraPerfLock* QCameraPerfLock::create( 356 PerfLockEnum perfLockType) 357{ 358 QCameraPerfLock *perfLock = NULL; 359 360 if (perfLockType < PERF_LOCK_COUNT) { 361 QCameraPerfLockIntf *perfLockIntf = QCameraPerfLockIntf::createSingleton(); 362 if (perfLockIntf) { 363 perfLock = new QCameraPerfLock(perfLockType, perfLockIntf); 364 } 365 } 366 return perfLock; 367} 368 369 370/*=========================================================================== 371 * FUNCTION : QCameraPerfLock constructor 372 * 373 * DESCRIPTION: Initialize member variables 374 * 375 * PARAMETERS : None 376 * 377 * RETURN : void 378 * 379 *==========================================================================*/ 380QCameraPerfLock::QCameraPerfLock( 381 PerfLockEnum perfLockType, 382 QCameraPerfLockIntf *perfLockIntf) : 383 mHandle(0), 384 mRefCount(0), 385 mTimeOut(0), 386 mPerfLockType(perfLockType), 387 mPerfLockIntf(perfLockIntf) 388{ 389 mIsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false); 390} 391 392 393/*=========================================================================== 394 * FUNCTION : QCameraPerfLock destructor 395 * 396 * DESCRIPTION: class destructor 397 * 398 * PARAMETERS : None 399 * 400 * RETURN : void 401 * 402 *==========================================================================*/ 403QCameraPerfLock::~QCameraPerfLock() 404{ 405 if (mHandle > 0) { 406 (*mPerfLockIntf->perfLockRel())(mHandle); 407 } 408 QCameraPerfLockIntf::deleteInstance(); 409} 410 411 412/*=========================================================================== 413 * FUNCTION : isTimedOut 414 * 415 * DESCRIPTION: Check if the perf lock is timed out 416 * 417 * PARAMETERS : None 418 * 419 * RETURN : boolean indicating if the perf lock is timed out 420 * 421 *==========================================================================*/ 422bool QCameraPerfLock::isTimedOut() 423{ 424 if (mTimeOut && (systemTime() > mTimeOut)) { 425 return true; 426 } 427 return false; 428} 429 430 431/*=========================================================================== 432 * FUNCTION : restartTimer 433 * 434 * DESCRIPTION: Restart the timer for the duration specified 435 * 436 * PARAMETERS : 437 * @timer : timer duration in milliseconds 438 * 439 * RETURN : void 440 * 441 *==========================================================================*/ 442void inline QCameraPerfLock::restartTimer( 443 uint32_t timer) 444{ 445 if (timer > 0) { 446 mTimeOut = systemTime() + ms2ns(timer); 447 } 448} 449 450 451/*=========================================================================== 452 * FUNCTION : acquirePerfLock 453 * 454 * DESCRIPTION: Acquires the perf lock for the duration specified. Do not acquire 455 * the perf lock is reacquire flag is set to false provided the perf 456 * lock is already acquired. 457 * 458 * PARAMETERS : 459 * @forceReaquirePerfLock: Reacquire 460 * @timer : Duration of the perf lock 461 * 462 * RETURN : true on success 463 * false on failure 464 * 465 *==========================================================================*/ 466bool QCameraPerfLock::acquirePerfLock( 467 bool forceReaquirePerfLock, 468 uint32_t timer) 469{ 470 bool ret = true; 471 Mutex::Autolock lock(mMutex); 472 473 switch (mPerfLockType) { 474 case PERF_LOCK_POWERHINT_PREVIEW: 475 case PERF_LOCK_POWERHINT_ENCODE: 476 powerHintInternal(PowerHint::VIDEO_ENCODE, true); 477 return true; 478 case PERF_LOCK_OPEN_CAMERA: 479 case PERF_LOCK_CLOSE_CAMERA: 480 powerHintInternal(PowerHint::CAMERA_LAUNCH, timer); 481 return true; 482 case PERF_LOCK_START_PREVIEW: 483 powerHintInternal(PowerHint::CAMERA_STREAMING, timer); 484 return true; 485 case PERF_LOCK_TAKE_SNAPSHOT: 486 powerHintInternal(PowerHint::CAMERA_SHOT, timer); 487 return true; 488 default: 489 LOGE("Unknown powerhint %d",(int)mPerfLockType); 490 return false; 491 } 492 493 if (!mIsPerfdEnabled) return ret; 494 495 if (isTimedOut()) { 496 mHandle = 0; 497 mRefCount = 0; 498 } 499 500 if ((mRefCount == 0) || forceReaquirePerfLock) { 501 mHandle = (*mPerfLockIntf->perfLockAcq())( 502 mHandle, timer, 503 mPerfLockInfo[mPerfLockType].perfLockParams, 504 mPerfLockInfo[mPerfLockType].perfLockParamsCount); 505 506 if (mHandle > 0) { 507 ++mRefCount; 508 restartTimer(timer); 509 LOGD("perfLockHandle %d, updated refCount: %d, perfLockType: %d", 510 mHandle, mRefCount, mPerfLockType); 511 } else { 512 LOGE("Failed to acquire the perf lock"); 513 ret = false; 514 } 515 } else { 516 LOGD("Perf lock already acquired, not re-aquiring"); 517 } 518 519 return ret; 520} 521 522 523/*=========================================================================== 524 * FUNCTION : releasePerfLock 525 * 526 * DESCRIPTION: Releases the perf lock 527 * 528 * PARAMETERS : None 529 * 530 * RETURN : true on success 531 * false on failure 532 * 533 *==========================================================================*/ 534bool QCameraPerfLock::releasePerfLock() 535{ 536 bool ret = true; 537 Mutex::Autolock lock(mMutex); 538 539 switch (mPerfLockType) { 540 case PERF_LOCK_POWERHINT_PREVIEW: 541 case PERF_LOCK_POWERHINT_ENCODE: 542 powerHintInternal(PowerHint::VIDEO_ENCODE, false); 543 return true; 544 case PERF_LOCK_OPEN_CAMERA: 545 case PERF_LOCK_CLOSE_CAMERA: 546 powerHintInternal(PowerHint::CAMERA_LAUNCH, false); 547 return true; 548 case PERF_LOCK_START_PREVIEW: 549 powerHintInternal(PowerHint::CAMERA_STREAMING, false); 550 return true; 551 case PERF_LOCK_TAKE_SNAPSHOT: 552 powerHintInternal(PowerHint::CAMERA_SHOT, false); 553 return true; 554 default: 555 LOGE("Unknown powerhint %d",(int)mPerfLockType); 556 return false; 557 } 558 559 if (!mIsPerfdEnabled) return ret; 560 561 if (mHandle > 0) { 562 LOGD("perfLockHandle %d, refCount: %d, perfLockType: %d", 563 mHandle, mRefCount, mPerfLockType); 564 565 if (isTimedOut()) { 566 mHandle = 0; 567 mRefCount = 0; 568 } else if (--mRefCount == 0) { 569 int32_t rc = (*mPerfLockIntf->perfLockRel())(mHandle); 570 mHandle = 0; 571 mTimeOut = 0; 572 if (rc < 0) { 573 LOGE("Failed to release the perf lock"); 574 ret = false; 575 } 576 } 577 } else { 578 LOGW("Perf lock %d either not acquired or already released", mPerfLockType); 579 } 580 581 return ret; 582} 583 584 585/*=========================================================================== 586 * FUNCTION : powerHintInternal 587 * 588 * DESCRIPTION: Sets the requested power hint and state to power HAL. 589 * 590 * PARAMETERS : 591 * @hint : Power hint 592 * @enable : Enable power hint if set to 1. Disable if set to 0. 593 * 594 * RETURN : void 595 * 596 *==========================================================================*/ 597void QCameraPerfLock::powerHintInternal( 598 PowerHint powerHint, 599 int32_t time_out) 600{ 601#ifdef HAS_MULTIMEDIA_HINTS 602 if (!mPerfLockIntf->powerHint(powerHint, time_out)) { 603 LOGE("Send powerhint to PowerHal failed"); 604 } 605#endif 606} 607 608 609 610/*=========================================================================== 611 * FUNCTION : createSingleton 612 * 613 * DESCRIPTION: Open the perf lock library, query the function pointers and 614 * create a singleton object upon success 615 * 616 * PARAMETERS : None 617 * 618 * RETURN : QCameraPerfLockIntf object pointer on success 619 * NULL on failure 620 * 621 *==========================================================================*/ 622QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton() 623{ 624 bool error = true; 625 Mutex::Autolock lock(mMutex); 626 627 if (mInstance == NULL) { 628 // Open perflock library and query for the function pointers 629 uint32_t perfLockEnable = 0; 630 char value[PROPERTY_VALUE_MAX]; 631 632 property_get("persist.camera.perflock.enable", value, "1"); 633 perfLockEnable = atoi(value); 634 635 if (perfLockEnable) { 636 mInstance = new QCameraPerfLockIntf(); 637 if (mInstance) { 638 #ifdef HAS_MULTIMEDIA_HINTS 639 std::lock_guard<std::mutex> lock(gPowerHalMutex); 640 getPowerHalLocked(); 641 if (gPowerHal == nullptr) { 642 ALOGE("Couldn't load PowerHAL module"); 643 } 644 else 645 #endif 646 { 647 /* Retrieve the name of the vendor extension library */ 648 void *dlHandle = NULL; 649 if ((property_get("ro.vendor.extension_library", value, NULL) > 0) && 650 (dlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL))) { 651 652 perfLockAcquire pLockAcq = (perfLockAcquire)dlsym(dlHandle, "perf_lock_acq"); 653 perfLockRelease pLockRel = (perfLockRelease)dlsym(dlHandle, "perf_lock_rel"); 654 655 if (pLockAcq && pLockRel) { 656 mInstance->mDlHandle = dlHandle; 657 mInstance->mPerfLockAcq = pLockAcq; 658 mInstance->mPerfLockRel = pLockRel; 659 error = false; 660 } else { 661 LOGE("Failed to link the symbols- perf_lock_acq, perf_lock_rel"); 662 bool IsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false); 663 if (!IsPerfdEnabled) { 664 mInstance->mDlHandle = nullptr; 665 mInstance->mPerfLockAcq = nullptr; 666 mInstance->mPerfLockRel = nullptr; 667 error = false; 668 } 669 } 670 } else { 671 LOGE("Unable to load lib: %s", value); 672 } 673 } 674 if (error && mInstance) { 675 delete mInstance; 676 mInstance = NULL; 677 } 678 } 679 } 680 } 681 682 if (mInstance) { 683 ++(mInstance->mRefCount); 684 } 685 686 return mInstance; 687} 688 689 690/*=========================================================================== 691 * FUNCTION : deleteInstance 692 * 693 * DESCRIPTION: Delete the object if refCount is 0 694 * 695 * PARAMETERS : None 696 * 697 * RETURN : void 698 * 699 *==========================================================================*/ 700void QCameraPerfLockIntf::deleteInstance() 701{ 702 Mutex::Autolock lock(mMutex); 703 704 if (mInstance && (--(mInstance->mRefCount) == 0)) { 705 delete mInstance; 706 mInstance = NULL; 707 } 708} 709 710 711/*=========================================================================== 712 * FUNCTION : QCameraPerfLockIntf destructor 713 * 714 * DESCRIPTION: class destructor 715 * 716 * PARAMETERS : None 717 * 718 * RETURN : void 719 * 720 *==========================================================================*/ 721QCameraPerfLockIntf::~QCameraPerfLockIntf() 722{ 723 if (mDlHandle) { 724 dlclose(mDlHandle); 725 } 726} 727 728bool QCameraPerfLockIntf::powerHint(PowerHint hint, int32_t data) { 729 std::lock_guard<std::mutex> lock(gPowerHalMutex); 730 getPowerHalLocked(); 731 if (gPowerHal == nullptr) { 732 ALOGE("Couldn't do powerHint because of HAL error."); 733 return false; 734 } 735 auto ret = gPowerHal->powerHintAsync_1_2(hint, data); 736 if (!ret.isOk()) { 737 ALOGE("powerHint failed error: %s", ret.description().c_str()); 738 } 739 return ret.isOk(); 740} 741 742}; // namespace qcamera 743