1 /* 2 * Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <dlfcn.h> 31 #include <powermanager/IPowerManager.h> 32 #include <cutils/sockets.h> 33 #include <cutils/native_handle.h> 34 #include <utils/String16.h> 35 #include <binder/Parcel.h> 36 #include <gralloc_priv.h> 37 #include <hardware/hwcomposer.h> 38 #include <hardware/hwcomposer_defs.h> 39 #include <QService.h> 40 41 #include <core/dump_interface.h> 42 #include <utils/constants.h> 43 #include <utils/debug.h> 44 #include <core/buffer_allocator.h> 45 #include <private/color_params.h> 46 #include "hwc_buffer_allocator.h" 47 #include "hwc_buffer_sync_handler.h" 48 #include "hwc_session.h" 49 #include "hwc_debugger.h" 50 51 #define __CLASS__ "HWCColorManager" 52 53 namespace sdm { 54 55 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams ¶ms) { 56 uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) | 57 ((params.color.b) & 0xff); 58 return argb_color; 59 } 60 61 int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id, 62 PPDisplayAPIPayload *sink) { 63 int ret = 0; 64 uint32_t id(0); 65 uint32_t size(0); 66 67 id = UINT32(in.readInt32()); 68 size = UINT32(in.readInt32()); 69 if (size > 0 && size == in.dataAvail()) { 70 const void *data = in.readInplace(size); 71 const uint8_t *temp = reinterpret_cast<const uint8_t *>(data); 72 73 sink->size = size; 74 sink->payload = const_cast<uint8_t *>(temp); 75 *disp_id = id; 76 } else { 77 DLOGW("Failing size checking, size = %d", size); 78 ret = -EINVAL; 79 } 80 81 return ret; 82 } 83 84 void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data, 85 android::Parcel *out_parcel) { 86 out_parcel->writeInt32(INT32(data.size)); 87 if (data.payload) 88 out_parcel->write(data.payload, data.size); 89 } 90 91 HWCColorManager *HWCColorManager::CreateColorManager() { 92 HWCColorManager *color_mgr = new HWCColorManager(); 93 94 if (color_mgr) { 95 // Load display API interface library. And retrieve color API function tables. 96 DynLib &color_apis_lib = color_mgr->color_apis_lib_; 97 if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) { 98 if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) { 99 DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES, 100 DISPLAY_API_INTERFACE_LIBRARY_NAME); 101 delete color_mgr; 102 return NULL; 103 } 104 } else { 105 DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); 106 delete color_mgr; 107 return NULL; 108 } 109 DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); 110 111 // Load diagclient library and invokes its entry point to pass in display APIs. 112 DynLib &diag_client_lib = color_mgr->diag_client_lib_; 113 if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) { 114 if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME, 115 reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) || 116 !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME, 117 reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) { 118 DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME, 119 QDCM_DIAG_CLIENT_LIBRARY_NAME); 120 } else { 121 // invoke Diag Client entry point to initialize. 122 color_mgr->qdcm_diag_init_(color_mgr->color_apis_); 123 DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME, 124 QDCM_DIAG_CLIENT_LIBRARY_NAME); 125 } 126 } else { 127 DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME); 128 // only QDCM Diag client failed to be loaded and system still should function. 129 } 130 } else { 131 DLOGE("Unable to create HWCColorManager"); 132 return NULL; 133 } 134 135 return color_mgr; 136 } 137 138 HWCColorManager::~HWCColorManager() { 139 } 140 141 void HWCColorManager::DestroyColorManager() { 142 if (qdcm_mode_mgr_) { 143 delete qdcm_mode_mgr_; 144 } 145 if (qdcm_diag_deinit_) { 146 qdcm_diag_deinit_(); 147 } 148 delete this; 149 } 150 151 int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) { 152 int ret = 0; 153 154 if (!qdcm_mode_mgr_) { 155 qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr(); 156 if (!qdcm_mode_mgr_) { 157 DLOGE("Unable to create QDCM operating mode manager."); 158 ret = -EFAULT; 159 } 160 } 161 162 if (qdcm_mode_mgr_) { 163 ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display); 164 } 165 166 return ret; 167 } 168 169 bool HWCColorManager::SolidFillLayersPrepare(hwc_display_contents_1_t **displays, 170 HWCDisplay *hwc_display) { 171 SCOPE_LOCK(locker_); 172 173 // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode. 174 uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_); 175 hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY]; 176 177 if (solid_fill_enable_ && solid_fill_layers_ && layer_list) { 178 // 1. shallow copy HWC_FRAMEBUFFER_TARGET layer info solid fill layer list. 179 solid_fill_layers_->hwLayers[1] = layer_list->hwLayers[layer_list->numHwLayers - 1]; 180 181 // 2. continue the prepare<> on solid_fill_layers. 182 hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color); 183 hwc_display->Prepare(solid_fill_layers_); // RECT info included. 184 185 // 3. Set HWC_OVERLAY to all SF layers before returning to framework. 186 for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) { 187 hwc_layer_1_t *layer = &layer_list->hwLayers[i]; 188 layer->compositionType = HWC_OVERLAY; 189 } 190 191 return true; 192 } else if (!solid_fill_enable_) { 193 hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0); 194 } 195 196 return false; 197 } 198 199 bool HWCColorManager::SolidFillLayersSet(hwc_display_contents_1_t **displays, 200 HWCDisplay *hwc_display) { 201 // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode. 202 SCOPE_LOCK(locker_); 203 hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY]; 204 if (solid_fill_enable_ && solid_fill_layers_ && layer_list) { 205 hwc_display->Commit(solid_fill_layers_); 206 207 // SurfaceFlinger layer stack is dropped in solid fill case and replaced with local layer stack 208 // Close acquire fence fds associated with SF layer stack 209 // Close release/retire fence fds returned along with local layer stack 210 for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) { 211 int &fence_fd = layer_list->hwLayers[i].acquireFenceFd; 212 if (fence_fd >= 0) { 213 close(fence_fd); 214 fence_fd = -1; 215 } 216 } 217 218 for (size_t i = 0; i < (solid_fill_layers_->numHwLayers - 1); i++) { 219 int &fence_fd = solid_fill_layers_->hwLayers[i].releaseFenceFd; 220 if (fence_fd >= 0) { 221 close(fence_fd); 222 fence_fd = -1; 223 } 224 } 225 if (solid_fill_layers_->retireFenceFd >= 0) { 226 close(solid_fill_layers_->retireFenceFd); 227 solid_fill_layers_->retireFenceFd = -1; 228 } 229 230 return true; 231 } 232 233 return false; 234 } 235 236 int HWCColorManager::CreateSolidFillLayers(HWCDisplay *hwc_display) { 237 int ret = 0; 238 239 if (!solid_fill_layers_) { 240 uint32_t size = sizeof(hwc_display_contents_1) + kNumSolidFillLayers * sizeof(hwc_layer_1_t); 241 uint32_t primary_width = 0; 242 uint32_t primary_height = 0; 243 244 hwc_display->GetMixerResolution(&primary_width, &primary_height); 245 uint8_t *buf = new uint8_t[size](); 246 // handle for solid fill layer with fd = -1. 247 private_handle_t *handle = 248 new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER, BUFFER_TYPE_UI, 249 HAL_PIXEL_FORMAT_RGBA_8888, INT32(primary_width), 250 INT32(primary_height)); 251 252 if (!buf || !handle) { 253 DLOGE("Failed to allocate memory."); 254 if (buf) 255 delete[] buf; 256 if (handle) 257 delete handle; 258 259 return -ENOMEM; 260 } 261 262 solid_fill_layers_ = reinterpret_cast<hwc_display_contents_1 *>(buf); 263 hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0]; 264 layer.handle = handle; 265 } 266 267 solid_fill_layers_->flags = HWC_GEOMETRY_CHANGED; 268 solid_fill_layers_->numHwLayers = kNumSolidFillLayers; 269 solid_fill_layers_->retireFenceFd = -1; 270 solid_fill_layers_->outbuf = NULL; 271 solid_fill_layers_->outbufAcquireFenceFd = -1; 272 273 hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0]; 274 hwc_rect_t solid_fill_rect = { 275 INT(solid_fill_params_.rect.x), 276 INT(solid_fill_params_.rect.y), 277 solid_fill_params_.rect.x + INT(solid_fill_params_.rect.width), 278 solid_fill_params_.rect.y + INT(solid_fill_params_.rect.height), 279 }; 280 281 layer.compositionType = HWC_FRAMEBUFFER; 282 layer.blending = HWC_BLENDING_PREMULT; 283 layer.sourceCropf.left = solid_fill_params_.rect.x; 284 layer.sourceCropf.top = solid_fill_params_.rect.y; 285 layer.sourceCropf.right = UINT32(solid_fill_params_.rect.x) + solid_fill_params_.rect.width; 286 layer.sourceCropf.bottom = UINT32(solid_fill_params_.rect.y) + solid_fill_params_.rect.height; 287 layer.acquireFenceFd = -1; 288 layer.releaseFenceFd = -1; 289 layer.flags = 0; 290 layer.transform = 0; 291 layer.hints = 0; 292 layer.planeAlpha = 0xff; 293 layer.displayFrame = solid_fill_rect; 294 layer.visibleRegionScreen.numRects = 1; 295 layer.visibleRegionScreen.rects = &layer.displayFrame; 296 layer.surfaceDamage.numRects = 0; 297 298 return ret; 299 } 300 301 void HWCColorManager::DestroySolidFillLayers() { 302 if (solid_fill_layers_) { 303 hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0]; 304 uint8_t *buf = reinterpret_cast<uint8_t *>(solid_fill_layers_); 305 private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(layer.handle); 306 307 if (hnd) 308 delete hnd; 309 310 if (buf) 311 delete[] buf; 312 313 solid_fill_layers_ = NULL; 314 } 315 } 316 317 int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) { 318 SCOPE_LOCK(locker_); 319 int ret = 0; 320 321 if (params) { 322 solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params); 323 } else { 324 solid_fill_params_ = PPColorFillParams(); 325 } 326 327 if (enable) { 328 // will create solid fill layers for rendering if not present. 329 ret = CreateSolidFillLayers(hwc_display); 330 } else { 331 DestroySolidFillLayers(); 332 } 333 solid_fill_enable_ = enable; 334 335 return ret; 336 } 337 338 int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) { 339 SCOPE_LOCK(locker_); 340 int ret = 0; 341 342 PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData*>(params); 343 344 if (enable) { 345 std::memset(&buffer_info, 0x00, sizeof(buffer_info)); 346 hwc_display->GetPanelResolution(&buffer_info.buffer_config.width, 347 &buffer_info.buffer_config.height); 348 if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) { 349 buffer_info.buffer_config.format = kFormatRGB888; 350 } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) { 351 buffer_info.buffer_config.format = kFormatRGBA1010102; 352 } else { 353 DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format); 354 return -EFAULT; 355 } 356 357 buffer_info.buffer_config.buffer_count = 1; 358 buffer_info.alloc_buffer_info.fd = -1; 359 buffer_info.alloc_buffer_info.stride = 0; 360 buffer_info.alloc_buffer_info.size = 0; 361 362 buffer_allocator_ = new HWCBufferAllocator(); 363 if (buffer_allocator_ == NULL) { 364 DLOGE("Memory allocation for buffer_allocator_ FAILED"); 365 return -ENOMEM; 366 } 367 368 ret = buffer_allocator_->AllocateBuffer(&buffer_info); 369 if (ret != 0) { 370 DLOGE("Buffer allocation failed. ret: %d", ret); 371 delete buffer_allocator_; 372 buffer_allocator_ = NULL; 373 return -ENOMEM; 374 } else { 375 void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, 376 PROT_READ|PROT_WRITE, 377 MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0); 378 379 if (buffer == MAP_FAILED) { 380 DLOGE("mmap failed. err = %d", errno); 381 frame_capture_data->buffer = NULL; 382 ret = buffer_allocator_->FreeBuffer(&buffer_info); 383 delete buffer_allocator_; 384 buffer_allocator_ = NULL; 385 return -EFAULT; 386 } else { 387 frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer); 388 frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.aligned_width; 389 frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size; 390 } 391 ret = hwc_display->FrameCaptureAsync(buffer_info, 1); 392 if (ret < 0) { 393 DLOGE("FrameCaptureAsync failed. ret = %d", ret); 394 } 395 } 396 } else { 397 ret = hwc_display->GetFrameCaptureStatus(); 398 if (!ret) { 399 if (frame_capture_data->buffer != NULL) { 400 if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) { 401 DLOGE("munmap failed. err = %d", errno); 402 } 403 } 404 if (buffer_allocator_ != NULL) { 405 std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData)); 406 ret = buffer_allocator_->FreeBuffer(&buffer_info); 407 if (ret != 0) { 408 DLOGE("FreeBuffer failed. ret = %d", ret); 409 } 410 delete buffer_allocator_; 411 buffer_allocator_ = NULL; 412 } 413 } else { 414 DLOGE("GetFrameCaptureStatus failed. ret = %d", ret); 415 } 416 } 417 return ret; 418 } 419 420 int HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) { 421 int err = -1; 422 DisplayDetailEnhancerData de_data; 423 424 PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params); 425 if (de_tuning_cfg_data->cfg_pending == true) { 426 if (!de_tuning_cfg_data->cfg_en) { 427 de_data.enable = 0; 428 } else { 429 de_data.override_flags = kOverrideDEEnable; 430 de_data.enable = 1; 431 432 if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) { 433 de_data.override_flags |= kOverrideDESharpen1; 434 de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor; 435 } 436 437 if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) { 438 de_data.override_flags |= kOverrideDEClip; 439 de_data.clip = de_tuning_cfg_data->params.clip; 440 } 441 442 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) { 443 de_data.override_flags |= kOverrideDEThrQuiet; 444 de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet; 445 } 446 447 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) { 448 de_data.override_flags |= kOverrideDEThrDieout; 449 de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout; 450 } 451 452 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) { 453 de_data.override_flags |= kOverrideDEThrLow; 454 de_data.thr_low = de_tuning_cfg_data->params.thr_low; 455 } 456 457 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) { 458 de_data.override_flags |= kOverrideDEThrHigh; 459 de_data.thr_high = de_tuning_cfg_data->params.thr_high; 460 } 461 462 if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) { 463 switch (de_tuning_cfg_data->params.quality) { 464 case kDeContentQualLow: 465 de_data.quality_level = kContentQualityLow; 466 break; 467 case kDeContentQualMedium: 468 de_data.quality_level = kContentQualityMedium; 469 break; 470 case kDeContentQualHigh: 471 de_data.quality_level = kContentQualityHigh; 472 break; 473 case kDeContentQualUnknown: 474 default: 475 de_data.quality_level = kContentQualityUnknown; 476 break; 477 } 478 } 479 } 480 err = hwc_display->SetDetailEnhancerConfig(de_data); 481 if (err) { 482 DLOGW("SetDetailEnhancerConfig failed. err = %d", err); 483 } 484 de_tuning_cfg_data->cfg_pending = false; 485 } 486 return err; 487 } 488 489 void HWCColorManager::SetColorModeDetailEnhancer(HWCDisplay *hwc_display) { 490 SCOPE_LOCK(locker_); 491 int err = -1; 492 PPPendingParams pending_action; 493 PPDisplayAPIPayload req_payload; 494 495 pending_action.action = kGetDetailedEnhancerData; 496 pending_action.params = NULL; 497 498 if (hwc_display) { 499 err = hwc_display->ColorSVCRequestRoute(req_payload, NULL, &pending_action); 500 if (!err && pending_action.action == kConfigureDetailedEnhancer) { 501 err = SetHWDetailedEnhancerConfig(pending_action.params, hwc_display); 502 } 503 } 504 return; 505 } 506 507 int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) { 508 SCOPE_LOCK(locker_); 509 int err = -1; 510 err = SetHWDetailedEnhancerConfig(params, hwc_display); 511 return err; 512 } 513 514 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = { 515 HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"), 516 HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"), 517 HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"), 518 }; 519 520 const char *const HWCQDCMModeManager::kSocketName = "pps"; 521 const char *const HWCQDCMModeManager::kTagName = "surfaceflinger"; 522 const char *const HWCQDCMModeManager::kPackageName = "colormanager"; 523 524 HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() { 525 HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager(); 526 527 if (!mode_mgr) { 528 DLOGW("No memory to create HWCQDCMModeManager."); 529 return NULL; 530 } else { 531 mode_mgr->socket_fd_ = 532 ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 533 if (mode_mgr->socket_fd_ < 0) { 534 // it should not be disastrous and we still can grab wakelock in QDCM mode. 535 DLOGW("Unable to connect to dpps socket!"); 536 } 537 538 // retrieve system GPU idle timeout value for later to recover. 539 mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs()); 540 541 // acquire the binder handle to Android system PowerManager for later use. 542 android::sp<android::IBinder> binder = 543 android::defaultServiceManager()->checkService(android::String16("power")); 544 if (binder == NULL) { 545 DLOGW("Application can't connect to power manager service"); 546 delete mode_mgr; 547 mode_mgr = NULL; 548 } else { 549 mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder); 550 } 551 } 552 553 return mode_mgr; 554 } 555 556 HWCQDCMModeManager::~HWCQDCMModeManager() { 557 if (socket_fd_ >= 0) 558 ::close(socket_fd_); 559 } 560 561 int HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) { 562 int ret = 0; 563 564 if (enable) { 565 if (wakelock_token_ == NULL) { 566 android::sp<android::IBinder> binder = new android::BBinder(); 567 android::status_t status = power_mgr_->acquireWakeLock( 568 (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder, 569 android::String16(kTagName), android::String16(kPackageName)); 570 if (status == android::NO_ERROR) { 571 wakelock_token_ = binder; 572 } 573 } 574 } else { 575 if (wakelock_token_ != NULL && power_mgr_ != NULL) { 576 power_mgr_->releaseWakeLock(wakelock_token_, 0); 577 wakelock_token_.clear(); 578 wakelock_token_ = NULL; 579 } 580 } 581 582 return ret; 583 } 584 585 int HWCQDCMModeManager::EnableActiveFeatures(bool enable, 586 const HWCQDCMModeManager::ActiveFeatureCMD &cmds, 587 bool *was_running) { 588 int ret = 0; 589 ssize_t size = 0; 590 char response[kSocketCMDMaxLength] = { 591 0, 592 }; 593 594 if (socket_fd_ < 0) { 595 DLOGW("No socket connection available!"); 596 return -EFAULT; 597 } 598 599 if (!enable) { // if client requesting to disable it. 600 // query CABL status, if off, no action. keep the status. 601 size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status)); 602 if (size < 0) { 603 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 604 ret = -EFAULT; 605 } else { 606 size = ::read(socket_fd_, response, kSocketCMDMaxLength); 607 if (size < 0) { 608 DLOGW("Unable to read data over socket %s", ::strerror(errno)); 609 ret = -EFAULT; 610 } else if (!strncmp(response, cmds.running, strlen(cmds.running))) { 611 *was_running = true; 612 } 613 } 614 615 if (*was_running) { // if was running, it's requested to disable it. 616 size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off)); 617 if (size < 0) { 618 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 619 ret = -EFAULT; 620 } 621 } 622 } else { // if was running, need enable it back. 623 if (*was_running) { 624 size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on)); 625 if (size < 0) { 626 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 627 ret = -EFAULT; 628 } 629 } 630 } 631 632 return ret; 633 } 634 635 int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) { 636 int ret = 0; 637 638 ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature], 639 &cabl_was_running_); 640 ret = AcquireAndroidWakeLock(enable); 641 642 // if enter QDCM mode, disable GPU fallback idle timeout. 643 if (hwc_display) { 644 uint32_t timeout = enable ? 0 : entry_timeout_; 645 hwc_display->SetIdleTimeoutMs(timeout); 646 } 647 648 return ret; 649 } 650 651 } // namespace sdm 652