hwc_session.cpp revision f31e45897c5f3d981922222644b9778af2302474
1/* 2* Copyright (c) 2014 - 2015, 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 <core/dump_interface.h> 31#include <core/buffer_allocator.h> 32#include <private/color_params.h> 33#include <utils/constants.h> 34#include <utils/String16.h> 35#include <cutils/properties.h> 36#include <hardware_legacy/uevent.h> 37#include <sys/resource.h> 38#include <sys/prctl.h> 39#include <binder/Parcel.h> 40#include <QService.h> 41#include <gr.h> 42#include <gralloc_priv.h> 43#include <display_config.h> 44#include <utils/debug.h> 45#include <sync/sync.h> 46#include <profiler.h> 47 48#include "hwc_buffer_allocator.h" 49#include "hwc_buffer_sync_handler.h" 50#include "hwc_session.h" 51#include "hwc_debugger.h" 52#include "hwc_display_primary.h" 53#include "hwc_display_virtual.h" 54 55#define __CLASS__ "HWCSession" 56 57#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi" 58#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0" 59 60static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods; 61 62hwc_module_t HAL_MODULE_INFO_SYM = { 63 .common = { 64 .tag = HARDWARE_MODULE_TAG, 65 .version_major = 2, 66 .version_minor = 0, 67 .id = HWC_HARDWARE_MODULE_ID, 68 .name = "QTI Hardware Composer Module", 69 .author = "CodeAurora Forum", 70 .methods = &g_hwc_module_methods, 71 .dso = 0, 72 .reserved = {0}, 73 } 74}; 75 76namespace sdm { 77 78Locker HWCSession::locker_; 79 80static void Invalidate(const struct hwc_procs *procs) { 81} 82 83static void VSync(const struct hwc_procs* procs, int disp, int64_t timestamp) { 84} 85 86static void Hotplug(const struct hwc_procs* procs, int disp, int connected) { 87} 88 89HWCSession::HWCSession(const hw_module_t *module) { 90 // By default, drop any events. Calls will be routed to SurfaceFlinger after registerProcs. 91 hwc_procs_default_.invalidate = Invalidate; 92 hwc_procs_default_.vsync = VSync; 93 hwc_procs_default_.hotplug = Hotplug; 94 95 hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG; 96 hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_5; 97 hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module); 98 hwc_composer_device_1_t::common.close = Close; 99 hwc_composer_device_1_t::prepare = Prepare; 100 hwc_composer_device_1_t::set = Set; 101 hwc_composer_device_1_t::eventControl = EventControl; 102 hwc_composer_device_1_t::setPowerMode = SetPowerMode; 103 hwc_composer_device_1_t::query = Query; 104 hwc_composer_device_1_t::registerProcs = RegisterProcs; 105 hwc_composer_device_1_t::dump = Dump; 106 hwc_composer_device_1_t::getDisplayConfigs = GetDisplayConfigs; 107 hwc_composer_device_1_t::getDisplayAttributes = GetDisplayAttributes; 108 hwc_composer_device_1_t::getActiveConfig = GetActiveConfig; 109 hwc_composer_device_1_t::setActiveConfig = SetActiveConfig; 110 hwc_composer_device_1_t::setCursorPositionAsync = SetCursorPositionAsync; 111} 112 113int HWCSession::Init() { 114 int status = -EINVAL; 115 const char *qservice_name = "display.qservice"; 116 117 // Start QService and connect to it. 118 qService::QService::init(); 119 android::sp<qService::IQService> qservice = android::interface_cast<qService::IQService>( 120 android::defaultServiceManager()->getService(android::String16(qservice_name))); 121 122 if (qservice.get()) { 123 qservice->connect(android::sp<qClient::IQClient>(this)); 124 } else { 125 DLOGE("Failed to acquire %s", qservice_name); 126 return -EINVAL; 127 } 128 129 buffer_allocator_ = new HWCBufferAllocator(); 130 if (buffer_allocator_ == NULL) { 131 DLOGE("Display core initialization failed due to no memory"); 132 return -ENOMEM; 133 } 134 135 buffer_sync_handler_ = new HWCBufferSyncHandler(); 136 if (buffer_sync_handler_ == NULL) { 137 DLOGE("Display core initialization failed due to no memory"); 138 return -ENOMEM; 139 } 140 141 DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), buffer_allocator_, 142 buffer_sync_handler_, &core_intf_); 143 if (error != kErrorNone) { 144 DLOGE("Display core initialization failed. Error = %d", error); 145 return -EINVAL; 146 } 147 148 // Create and power on primary display 149 status = HWCDisplayPrimary::Create(core_intf_, &hwc_procs_, 150 &hwc_display_[HWC_DISPLAY_PRIMARY]); 151 if (status) { 152 CoreInterface::DestroyCore(); 153 return status; 154 } 155 156 color_mgr_ = HWCColorManager::CreateColorManager(); 157 if (!color_mgr_) { 158 DLOGW("Failed to load HWCColorManager."); 159 } 160 161 if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) { 162 DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno)); 163 HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]); 164 hwc_display_[HWC_DISPLAY_PRIMARY] = 0; 165 CoreInterface::DestroyCore(); 166 return -errno; 167 } 168 169 return 0; 170} 171 172int HWCSession::Deinit() { 173 HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]); 174 hwc_display_[HWC_DISPLAY_PRIMARY] = 0; 175 if (color_mgr_) { 176 color_mgr_->DestroyColorManager(); 177 } 178 uevent_thread_exit_ = true; 179 pthread_join(uevent_thread_, NULL); 180 181 DisplayError error = CoreInterface::DestroyCore(); 182 if (error != kErrorNone) { 183 DLOGE("Display core de-initialization failed. Error = %d", error); 184 } 185 186 return 0; 187} 188 189int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) { 190 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 191 192 if (!module || !name || !device) { 193 DLOGE("Invalid parameters."); 194 return -EINVAL; 195 } 196 197 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 198 HWCSession *hwc_session = new HWCSession(module); 199 if (!hwc_session) { 200 return -ENOMEM; 201 } 202 203 int status = hwc_session->Init(); 204 if (status != 0) { 205 delete hwc_session; 206 return status; 207 } 208 209 hwc_composer_device_1_t *composer_device = hwc_session; 210 *device = reinterpret_cast<hw_device_t *>(composer_device); 211 } 212 213 return 0; 214} 215 216int HWCSession::Close(hw_device_t *device) { 217 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 218 219 if (!device) { 220 return -EINVAL; 221 } 222 223 hwc_composer_device_1_t *composer_device = reinterpret_cast<hwc_composer_device_1_t *>(device); 224 HWCSession *hwc_session = static_cast<HWCSession *>(composer_device); 225 226 hwc_session->Deinit(); 227 delete hwc_session; 228 229 return 0; 230} 231 232int HWCSession::Prepare(hwc_composer_device_1 *device, size_t num_displays, 233 hwc_display_contents_1_t **displays) { 234 DTRACE_SCOPED(); 235 236 if (!device || !displays || num_displays > HWC_NUM_DISPLAY_TYPES) { 237 return -EINVAL; 238 } 239 240 HWCSession *hwc_session = static_cast<HWCSession *>(device); 241 hwc_procs_t const *hwc_procs = NULL; 242 bool hotplug_connect = false; 243 244 // Hold mutex only in this scope. 245 { 246 SEQUENCE_ENTRY_SCOPE_LOCK(locker_); 247 248 hwc_procs = hwc_session->hwc_procs_; 249 250 if (hwc_session->reset_panel_) { 251 DLOGW("panel is in bad state, resetting the panel"); 252 hwc_session->ResetPanel(); 253 } 254 255 if (hwc_session->need_invalidate_) { 256 hwc_procs->invalidate(hwc_procs); 257 } 258 259 hwc_session->HandleSecureDisplaySession(displays); 260 261 if (hwc_session->color_mgr_) { 262 HWCDisplay *primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]; 263 if (primary_display) { 264 int ret = hwc_session->color_mgr_->SolidFillLayersPrepare(displays, primary_display); 265 if (ret) 266 return 0; 267 } 268 } 269 270 for (ssize_t dpy = static_cast<ssize_t>(num_displays - 1); dpy >= 0; dpy--) { 271 hwc_display_contents_1_t *content_list = displays[dpy]; 272 // If external display is connected, ignore virtual display content list. 273 // If virtual display content list is valid, connect virtual display if not connected. 274 // If virtual display content list is invalid, disconnect virtual display if connected. 275 // If external display connection is pending, connect external display when virtual 276 // display is destroyed. 277 if (dpy == HWC_DISPLAY_VIRTUAL) { 278 if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL]) { 279 continue; 280 } 281 282 bool valid_content = HWCDisplayVirtual::IsValidContentList(content_list); 283 bool connected = (hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL] != NULL); 284 285 if (valid_content && !connected) { 286 hwc_session->ConnectDisplay(HWC_DISPLAY_VIRTUAL, content_list); 287 } else if (!valid_content && connected) { 288 hwc_session->DisconnectDisplay(HWC_DISPLAY_VIRTUAL); 289 290 if (hwc_session->external_pending_connect_) { 291 DLOGI("Process pending external display connection"); 292 hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL); 293 hwc_session->external_pending_connect_ = false; 294 hotplug_connect = true; 295 } 296 } 297 } 298 299 if (hwc_session->hwc_display_[dpy]) { 300 hwc_session->hwc_display_[dpy]->Prepare(content_list); 301 } 302 } 303 } 304 305 if (hotplug_connect) { 306 // notify client 307 hwc_procs->hotplug(hwc_procs, HWC_DISPLAY_EXTERNAL, true); 308 } 309 // Return 0, else client will go into bad state 310 return 0; 311} 312 313int HWCSession::GetVsyncPeriod(int disp) { 314 SCOPE_LOCK(locker_); 315 // default value 316 int32_t vsync_period = 1000000000l / 60; 317 const uint32_t attribute = HWC_DISPLAY_VSYNC_PERIOD; 318 319 if (hwc_display_[disp]) { 320 hwc_display_[disp]->GetDisplayAttributes(0, &attribute, &vsync_period); 321 } 322 323 return vsync_period; 324} 325 326int HWCSession::Set(hwc_composer_device_1 *device, size_t num_displays, 327 hwc_display_contents_1_t **displays) { 328 DTRACE_SCOPED(); 329 330 SEQUENCE_EXIT_SCOPE_LOCK(locker_); 331 332 if (!device || !displays || num_displays > HWC_NUM_DISPLAY_TYPES) { 333 return -EINVAL; 334 } 335 336 HWCSession *hwc_session = static_cast<HWCSession *>(device); 337 338 if (hwc_session->color_mgr_) { 339 HWCDisplay *primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]; 340 if (primary_display) { 341 int ret = hwc_session->color_mgr_->SolidFillLayersSet(displays, primary_display); 342 if (ret) 343 return 0; 344 } 345 } 346 347 for (size_t dpy = 0; dpy < num_displays; dpy++) { 348 hwc_display_contents_1_t *content_list = displays[dpy]; 349 350 // Drop virtual display composition if virtual display object could not be created 351 // due to HDMI concurrency. 352 if (dpy == HWC_DISPLAY_VIRTUAL && !hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) { 353 CloseAcquireFds(content_list); 354 if (content_list) { 355 content_list->retireFenceFd = -1; 356 } 357 358 continue; 359 } 360 361 if (hwc_session->hwc_display_[dpy]) { 362 hwc_session->hwc_display_[dpy]->Commit(content_list); 363 } 364 CloseAcquireFds(content_list); 365 } 366 367 if (hwc_session->new_bw_mode_) { 368 hwc_display_contents_1_t *content_list = displays[HWC_DISPLAY_PRIMARY]; 369 hwc_session->new_bw_mode_ = false; 370 if (hwc_session->bw_mode_release_fd_ >= 0) { 371 close(hwc_session->bw_mode_release_fd_); 372 } 373 hwc_session->bw_mode_release_fd_ = dup(content_list->retireFenceFd); 374 } 375 376 // This is only indicative of how many times SurfaceFlinger posts 377 // frames to the display. 378 CALC_FPS(); 379 380 // Return 0, else client will go into bad state 381 return 0; 382} 383 384void HWCSession::CloseAcquireFds(hwc_display_contents_1_t *content_list) { 385 if (content_list) { 386 for (size_t i = 0; i < content_list->numHwLayers; i++) { 387 int &acquireFenceFd = content_list->hwLayers[i].acquireFenceFd; 388 if (acquireFenceFd >= 0) { 389 close(acquireFenceFd); 390 acquireFenceFd = -1; 391 } 392 } 393 394 int &outbufAcquireFenceFd = content_list->outbufAcquireFenceFd; 395 if (outbufAcquireFenceFd >= 0) { 396 close(outbufAcquireFenceFd); 397 outbufAcquireFenceFd = -1; 398 } 399 } 400} 401 402int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) { 403 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 404 405 if (!device) { 406 return -EINVAL; 407 } 408 409 HWCSession *hwc_session = static_cast<HWCSession *>(device); 410 int status = -EINVAL; 411 if (hwc_session->hwc_display_[disp]) { 412 status = hwc_session->hwc_display_[disp]->EventControl(event, enable); 413 } 414 415 return status; 416} 417 418int HWCSession::SetPowerMode(hwc_composer_device_1 *device, int disp, int mode) { 419 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 420 421 if (!device) { 422 return -EINVAL; 423 } 424 425 HWCSession *hwc_session = static_cast<HWCSession *>(device); 426 int status = -EINVAL; 427 if (hwc_session->hwc_display_[disp]) { 428 status = hwc_session->hwc_display_[disp]->SetPowerMode(mode); 429 } 430 if (disp == HWC_DISPLAY_PRIMARY && hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) { 431 // Set the power mode for virtual display while setting power mode for primary, as SF 432 // does not invoke SetPowerMode() for virtual display. 433 status = hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(mode); 434 } 435 436 return status; 437} 438 439int HWCSession::Query(hwc_composer_device_1 *device, int param, int *value) { 440 SCOPE_LOCK(locker_); 441 442 if (!device || !value) { 443 return -EINVAL; 444 } 445 446 int status = 0; 447 448 switch (param) { 449 case HWC_BACKGROUND_LAYER_SUPPORTED: 450 value[0] = 1; 451 break; 452 453 default: 454 status = -EINVAL; 455 } 456 457 return status; 458} 459 460void HWCSession::RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs) { 461 SCOPE_LOCK(locker_); 462 463 if (!device || !procs) { 464 return; 465 } 466 467 HWCSession *hwc_session = static_cast<HWCSession *>(device); 468 hwc_session->hwc_procs_ = procs; 469} 470 471void HWCSession::Dump(hwc_composer_device_1 *device, char *buffer, int length) { 472 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 473 474 if (!device || !buffer || !length) { 475 return; 476 } 477 478 DumpInterface::GetDump(buffer, length); 479} 480 481int HWCSession::GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs, 482 size_t *num_configs) { 483 SCOPE_LOCK(locker_); 484 485 if (!device || !configs || !num_configs) { 486 return -EINVAL; 487 } 488 489 if (disp < HWC_DISPLAY_PRIMARY || disp > HWC_NUM_PHYSICAL_DISPLAY_TYPES) { 490 return -EINVAL; 491 } 492 493 HWCSession *hwc_session = static_cast<HWCSession *>(device); 494 int status = -EINVAL; 495 if (hwc_session->hwc_display_[disp]) { 496 status = hwc_session->hwc_display_[disp]->GetDisplayConfigs(configs, num_configs); 497 } 498 499 return status; 500} 501 502int HWCSession::GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config, 503 const uint32_t *attributes, int32_t *values) { 504 SCOPE_LOCK(locker_); 505 506 if (!device || !attributes || !values) { 507 return -EINVAL; 508 } 509 510 if (disp < HWC_DISPLAY_PRIMARY || disp > HWC_NUM_PHYSICAL_DISPLAY_TYPES) { 511 return -EINVAL; 512 } 513 514 HWCSession *hwc_session = static_cast<HWCSession *>(device); 515 int status = -EINVAL; 516 if (hwc_session->hwc_display_[disp]) { 517 status = hwc_session->hwc_display_[disp]->GetDisplayAttributes(config, attributes, values); 518 } 519 520 return status; 521} 522 523int HWCSession::GetActiveConfig(hwc_composer_device_1 *device, int disp) { 524 SCOPE_LOCK(locker_); 525 526 if (!device) { 527 return -EINVAL; 528 } 529 530 if (disp < HWC_DISPLAY_PRIMARY || disp > HWC_NUM_PHYSICAL_DISPLAY_TYPES) { 531 return -EINVAL; 532 } 533 534 HWCSession *hwc_session = static_cast<HWCSession *>(device); 535 int active_config = -1; 536 if (hwc_session->hwc_display_[disp]) { 537 active_config = hwc_session->hwc_display_[disp]->GetActiveConfig(); 538 } 539 540 return active_config; 541} 542 543int HWCSession::SetActiveConfig(hwc_composer_device_1 *device, int disp, int index) { 544 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 545 546 if (!device) { 547 return -EINVAL; 548 } 549 550 if (disp < HWC_DISPLAY_PRIMARY || disp > HWC_NUM_PHYSICAL_DISPLAY_TYPES) { 551 return -EINVAL; 552 } 553 554 HWCSession *hwc_session = static_cast<HWCSession *>(device); 555 int status = -EINVAL; 556 557 if (hwc_session->hwc_display_[disp]) { 558 status = hwc_session->hwc_display_[disp]->SetActiveConfig(index); 559 } 560 561 return status; 562} 563 564int HWCSession::SetCursorPositionAsync(hwc_composer_device_1 *device, int disp, int x, int y) { 565 DTRACE_SCOPED(); 566 567 SCOPE_LOCK(locker_); 568 569 if (!device || (disp < HWC_DISPLAY_PRIMARY) || (disp > HWC_DISPLAY_VIRTUAL)) { 570 return -EINVAL; 571 } 572 573 int status = -EINVAL; 574 HWCSession *hwc_session = static_cast<HWCSession *>(device); 575 if (hwc_session->hwc_display_[disp]) { 576 status = hwc_session->hwc_display_[disp]->SetCursorPosition(x, y); 577 } 578 579 return status; 580} 581 582int HWCSession::ConnectDisplay(int disp, hwc_display_contents_1_t *content_list) { 583 DLOGI("Display = %d", disp); 584 585 int status = 0; 586 uint32_t primary_width = 0; 587 uint32_t primary_height = 0; 588 589 hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height); 590 591 if (disp == HWC_DISPLAY_EXTERNAL) { 592 status = HWCDisplayExternal::Create(core_intf_, &hwc_procs_, primary_width, primary_height, 593 &hwc_display_[disp]); 594 } else if (disp == HWC_DISPLAY_VIRTUAL) { 595 status = HWCDisplayVirtual::Create(core_intf_, &hwc_procs_, primary_width, primary_height, 596 content_list, &hwc_display_[disp]); 597 } else { 598 DLOGE("Invalid display type"); 599 return -1; 600 } 601 602 if (!status) { 603 hwc_display_[disp]->SetSecureDisplay(secure_display_active_); 604 } 605 606 return status; 607} 608 609int HWCSession::DisconnectDisplay(int disp) { 610 DLOGI("Display = %d", disp); 611 612 if (disp == HWC_DISPLAY_EXTERNAL) { 613 HWCDisplayExternal::Destroy(hwc_display_[disp]); 614 } else if (disp == HWC_DISPLAY_VIRTUAL) { 615 HWCDisplayVirtual::Destroy(hwc_display_[disp]); 616 } else { 617 DLOGE("Invalid display type"); 618 return -1; 619 } 620 621 hwc_display_[disp] = NULL; 622 623 return 0; 624} 625 626android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel, 627 android::Parcel *output_parcel) { 628 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 629 630 android::status_t status = 0; 631 632 switch (command) { 633 case qService::IQService::DYNAMIC_DEBUG: 634 DynamicDebug(input_parcel); 635 break; 636 637 case qService::IQService::SCREEN_REFRESH: 638 hwc_procs_->invalidate(hwc_procs_); 639 break; 640 641 case qService::IQService::SET_IDLE_TIMEOUT: 642 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 643 uint32_t timeout = UINT32(input_parcel->readInt32()); 644 hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout); 645 } 646 break; 647 648 case qService::IQService::SET_FRAME_DUMP_CONFIG: 649 SetFrameDumpConfig(input_parcel); 650 break; 651 652 case qService::IQService::SET_MAX_PIPES_PER_MIXER: 653 status = SetMaxMixerStages(input_parcel); 654 break; 655 656 case qService::IQService::SET_DISPLAY_MODE: 657 status = SetDisplayMode(input_parcel); 658 break; 659 660 case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: 661 status = SetSecondaryDisplayStatus(input_parcel, output_parcel); 662 break; 663 664 case qService::IQService::CONFIGURE_DYN_REFRESH_RATE: 665 status = ConfigureRefreshRate(input_parcel); 666 break; 667 668 case qService::IQService::SET_VIEW_FRAME: 669 break; 670 671 case qService::IQService::TOGGLE_SCREEN_UPDATES: 672 status = ToggleScreenUpdates(input_parcel, output_parcel); 673 break; 674 675 case qService::IQService::QDCM_SVC_CMDS: 676 status = QdcmCMDHandler(input_parcel, output_parcel); 677 break; 678 679 case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: 680 status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel); 681 break; 682 683 case qService::IQService::CONTROL_PARTIAL_UPDATE: 684 status = ControlPartialUpdate(input_parcel, output_parcel); 685 break; 686 687 case qService::IQService::SET_ACTIVE_CONFIG: 688 status = HandleSetActiveDisplayConfig(input_parcel, output_parcel); 689 break; 690 691 case qService::IQService::GET_ACTIVE_CONFIG: 692 status = HandleGetActiveDisplayConfig(input_parcel, output_parcel); 693 break; 694 695 case qService::IQService::GET_CONFIG_COUNT: 696 status = HandleGetDisplayConfigCount(input_parcel, output_parcel); 697 break; 698 699 case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG: 700 status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel); 701 break; 702 703 case qService::IQService::GET_PANEL_BRIGHTNESS: 704 status = GetPanelBrightness(input_parcel, output_parcel); 705 break; 706 707 case qService::IQService::SET_PANEL_BRIGHTNESS: 708 status = SetPanelBrightness(input_parcel, output_parcel); 709 break; 710 711 case qService::IQService::GET_DISPLAY_VISIBLE_REGION: 712 status = GetVisibleDisplayRect(input_parcel, output_parcel); 713 break; 714 715 case qService::IQService::SET_CAMERA_STATUS: 716 status = SetDynamicBWForCamera(input_parcel, output_parcel); 717 break; 718 719 case qService::IQService::GET_BW_TRANSACTION_STATUS: 720 status = GetBWTransactionStatus(input_parcel, output_parcel); 721 break; 722 723 default: 724 DLOGW("QService command = %d is not supported", command); 725 return -EINVAL; 726 } 727 728 return status; 729} 730 731android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel, 732 android::Parcel *output_parcel) { 733 int input = input_parcel->readInt32(); 734 int error = android::BAD_VALUE; 735 736 if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) { 737 error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1); 738 if (error != 0) { 739 DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error); 740 } 741 } 742 output_parcel->writeInt32(error); 743 744 return error; 745} 746 747android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel, 748 android::Parcel *output_parcel) { 749 int level = input_parcel->readInt32(); 750 int error = android::BAD_VALUE; 751 752 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 753 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level); 754 if (error != 0) { 755 DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error); 756 } 757 } 758 output_parcel->writeInt32(error); 759 760 return error; 761} 762 763android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel, 764 android::Parcel *output_parcel) { 765 int error = android::BAD_VALUE; 766 int ret = error; 767 768 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 769 error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret); 770 if (error != 0) { 771 ret = error; 772 DLOGE("Failed to get the panel brightness. Error = %d", error); 773 } 774 } 775 output_parcel->writeInt32(ret); 776 777 return error; 778} 779 780android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel, 781 android::Parcel *out) { 782 DisplayError error = kErrorNone; 783 int ret = 0; 784 uint32_t disp_id = UINT32(input_parcel->readInt32()); 785 uint32_t enable = UINT32(input_parcel->readInt32()); 786 787 if (disp_id != HWC_DISPLAY_PRIMARY) { 788 DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id); 789 ret = -EINVAL; 790 out->writeInt32(ret); 791 return ret; 792 } 793 794 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) { 795 DLOGE("primary display object is not instantiated"); 796 ret = -EINVAL; 797 out->writeInt32(ret); 798 return ret; 799 } 800 801 uint32_t pending = 0; 802 error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending); 803 804 if (error == kErrorNone) { 805 if (!pending) { 806 out->writeInt32(ret); 807 return ret; 808 } 809 } else if (error == kErrorNotSupported) { 810 out->writeInt32(ret); 811 return ret; 812 } else { 813 ret = -EINVAL; 814 out->writeInt32(ret); 815 return ret; 816 } 817 818 // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future. 819 hwc_procs_->invalidate(hwc_procs_); 820 821 // Wait until partial update control is complete 822 ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs); 823 824 out->writeInt32(ret); 825 826 return ret; 827} 828 829android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel, 830 android::Parcel *output_parcel) { 831 int config = input_parcel->readInt32(); 832 int dpy = input_parcel->readInt32(); 833 int error = android::BAD_VALUE; 834 835 if (dpy > HWC_DISPLAY_VIRTUAL) { 836 return android::BAD_VALUE; 837 } 838 839 if (hwc_display_[dpy]) { 840 error = hwc_display_[dpy]->SetActiveDisplayConfig(config); 841 if (error == 0) { 842 hwc_procs_->invalidate(hwc_procs_); 843 } 844 } 845 846 return error; 847} 848 849android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel, 850 android::Parcel *output_parcel) { 851 int dpy = input_parcel->readInt32(); 852 int error = android::BAD_VALUE; 853 854 if (dpy > HWC_DISPLAY_VIRTUAL) { 855 return android::BAD_VALUE; 856 } 857 858 if (hwc_display_[dpy]) { 859 uint32_t config = 0; 860 error = hwc_display_[dpy]->GetActiveDisplayConfig(&config); 861 if (error == 0) { 862 output_parcel->writeInt32(config); 863 } 864 } 865 866 return error; 867} 868 869android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel, 870 android::Parcel *output_parcel) { 871 int dpy = input_parcel->readInt32(); 872 int error = android::BAD_VALUE; 873 874 if (dpy > HWC_DISPLAY_VIRTUAL) { 875 return android::BAD_VALUE; 876 } 877 878 uint32_t count = 0; 879 if (hwc_display_[dpy]) { 880 error = hwc_display_[dpy]->GetDisplayConfigCount(&count); 881 if (error == 0) { 882 output_parcel->writeInt32(count); 883 } 884 } 885 886 return error; 887} 888 889android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel 890 *input_parcel, 891 android::Parcel *output_parcel) { 892 int config = input_parcel->readInt32(); 893 int dpy = input_parcel->readInt32(); 894 int error = android::BAD_VALUE; 895 DisplayConfigVariableInfo attributes; 896 897 if (dpy > HWC_DISPLAY_VIRTUAL) { 898 return android::BAD_VALUE; 899 } 900 901 if (hwc_display_[dpy]) { 902 error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &attributes); 903 if (error == 0) { 904 output_parcel->writeInt32(attributes.vsync_period_ns); 905 output_parcel->writeInt32(attributes.x_pixels); 906 output_parcel->writeInt32(attributes.y_pixels); 907 output_parcel->writeFloat(attributes.x_dpi); 908 output_parcel->writeFloat(attributes.y_dpi); 909 output_parcel->writeInt32(0); // Panel type, unsupported. 910 } 911 } 912 913 return error; 914} 915 916android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel, 917 android::Parcel *output_parcel) { 918 int ret = -EINVAL; 919 920 uint32_t display_id = UINT32(input_parcel->readInt32()); 921 uint32_t display_status = UINT32(input_parcel->readInt32()); 922 923 DLOGI("Display = %d, Status = %d", display_id, display_status); 924 925 if (display_id >= HWC_NUM_DISPLAY_TYPES) { 926 DLOGE("Invalid display_id"); 927 } else if (display_id == HWC_DISPLAY_PRIMARY) { 928 DLOGE("Not supported for this display"); 929 } else if (!hwc_display_[display_id]) { 930 DLOGW("Display is not connected"); 931 } else { 932 ret = hwc_display_[display_id]->SetDisplayStatus(display_status); 933 } 934 935 output_parcel->writeInt32(ret); 936 937 return ret; 938} 939 940android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) { 941 uint32_t operation = UINT32(input_parcel->readInt32()); 942 switch (operation) { 943 case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE: 944 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform( 945 HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false); 946 case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE: 947 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform( 948 HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true); 949 case qdutils::SET_BINDER_DYN_REFRESH_RATE: 950 { 951 uint32_t refresh_rate = UINT32(input_parcel->readInt32()); 952 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform( 953 HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, 954 refresh_rate); 955 } 956 default: 957 DLOGW("Invalid operation %d", operation); 958 return -EINVAL; 959 } 960 961 return 0; 962} 963 964android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) { 965 uint32_t mode = UINT32(input_parcel->readInt32()); 966 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode); 967} 968 969android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) { 970 DisplayError error = kErrorNone; 971 uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32()); 972 uint32_t max_mixer_stages = UINT32(input_parcel->readInt32()); 973 974 if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) { 975 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 976 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages); 977 if (error != kErrorNone) { 978 return -EINVAL; 979 } 980 } 981 } 982 983 if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) { 984 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 985 error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages); 986 if (error != kErrorNone) { 987 return -EINVAL; 988 } 989 } 990 } 991 992 if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) { 993 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) { 994 error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages); 995 if (error != kErrorNone) { 996 return -EINVAL; 997 } 998 } 999 } 1000 1001 return 0; 1002} 1003 1004android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel, 1005 android::Parcel *output_parcel) { 1006 DisplayError error = kErrorNone; 1007 uint32_t camera_status = UINT32(input_parcel->readInt32()); 1008 HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault; 1009 1010 // trigger invalidate to apply new bw caps. 1011 hwc_procs_->invalidate(hwc_procs_); 1012 1013 error = core_intf_->SetMaxBandwidthMode(mode); 1014 if (error != kErrorNone) { 1015 return -EINVAL; 1016 } 1017 1018 new_bw_mode_ = true; 1019 need_invalidate_ = true; 1020 1021 return 0; 1022} 1023 1024android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel, 1025 android::Parcel *output_parcel) { 1026 bool state = true; 1027 1028 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 1029 if (sync_wait(bw_mode_release_fd_, 0) < 0) { 1030 DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno)); 1031 state = false; 1032 } 1033 output_parcel->writeInt32(state); 1034 } 1035 1036 return 0; 1037} 1038 1039void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) { 1040 uint32_t frame_dump_count = UINT32(input_parcel->readInt32()); 1041 uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32()); 1042 uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32()); 1043 1044 if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) { 1045 if (hwc_display_[HWC_DISPLAY_PRIMARY]) { 1046 hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type); 1047 } 1048 } 1049 1050 if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) { 1051 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1052 hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type); 1053 } 1054 } 1055 1056 if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) { 1057 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) { 1058 hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type); 1059 } 1060 } 1061} 1062 1063void HWCSession::DynamicDebug(const android::Parcel *input_parcel) { 1064 int type = input_parcel->readInt32(); 1065 bool enable = (input_parcel->readInt32() > 0); 1066 DLOGI("type = %d enable = %d", type, enable); 1067 int verbose_level = input_parcel->readInt32(); 1068 1069 switch (type) { 1070 case qService::IQService::DEBUG_ALL: 1071 HWCDebugHandler::DebugAll(enable, verbose_level); 1072 break; 1073 1074 case qService::IQService::DEBUG_MDPCOMP: 1075 HWCDebugHandler::DebugStrategy(enable, verbose_level); 1076 HWCDebugHandler::DebugCompManager(enable, verbose_level); 1077 break; 1078 1079 case qService::IQService::DEBUG_PIPE_LIFECYCLE: 1080 HWCDebugHandler::DebugResources(enable, verbose_level); 1081 break; 1082 1083 case qService::IQService::DEBUG_DRIVER_CONFIG: 1084 HWCDebugHandler::DebugDriverConfig(enable, verbose_level); 1085 break; 1086 1087 case qService::IQService::DEBUG_ROTATOR: 1088 HWCDebugHandler::DebugResources(enable, verbose_level); 1089 HWCDebugHandler::DebugDriverConfig(enable, verbose_level); 1090 HWCDebugHandler::DebugRotator(enable, verbose_level); 1091 break; 1092 1093 case qService::IQService::DEBUG_QDCM: 1094 HWCDebugHandler::DebugQdcm(enable, verbose_level); 1095 break; 1096 1097 default: 1098 DLOGW("type = %d is not supported", type); 1099 } 1100} 1101 1102android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel, 1103 android::Parcel *output_parcel) { 1104 int ret = 0; 1105 int32_t *brightness_value = NULL; 1106 uint32_t display_id(0); 1107 PPPendingParams pending_action; 1108 PPDisplayAPIPayload resp_payload, req_payload; 1109 1110 if (!color_mgr_) { 1111 return -1; 1112 } 1113 1114 // Read display_id, payload_size and payload from in_parcel. 1115 ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload); 1116 if (!ret) { 1117 if (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY]) 1118 ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload, 1119 &resp_payload, &pending_action); 1120 1121 if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL]) 1122 ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload, 1123 &pending_action); 1124 } 1125 1126 if (ret) { 1127 output_parcel->writeInt32(ret); // first field in out parcel indicates return code. 1128 req_payload.DestroyPayload(); 1129 resp_payload.DestroyPayload(); 1130 return ret; 1131 } 1132 1133 switch (pending_action.action) { 1134 case kInvalidating: 1135 hwc_procs_->invalidate(hwc_procs_); 1136 break; 1137 case kEnterQDCMMode: 1138 ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]); 1139 break; 1140 case kExitQDCMMode: 1141 ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]); 1142 break; 1143 case kApplySolidFill: 1144 ret = color_mgr_->SetSolidFill(pending_action.params, 1145 true, hwc_display_[HWC_DISPLAY_PRIMARY]); 1146 hwc_procs_->invalidate(hwc_procs_); 1147 break; 1148 case kDisableSolidFill: 1149 ret = color_mgr_->SetSolidFill(pending_action.params, 1150 false, hwc_display_[HWC_DISPLAY_PRIMARY]); 1151 hwc_procs_->invalidate(hwc_procs_); 1152 break; 1153 case kSetPanelBrightness: 1154 brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload); 1155 if (brightness_value == NULL) { 1156 DLOGE("Brightness value is Null"); 1157 return -EINVAL; 1158 } 1159 if (HWC_DISPLAY_PRIMARY == display_id) 1160 ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value); 1161 break; 1162 case kNoAction: 1163 break; 1164 default: 1165 DLOGW("Invalid pending action = %d!", pending_action.action); 1166 break; 1167 } 1168 1169 // for display API getter case, marshall returned params into out_parcel. 1170 output_parcel->writeInt32(ret); 1171 HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel); 1172 req_payload.DestroyPayload(); 1173 resp_payload.DestroyPayload(); 1174 1175 return (ret? -EINVAL : 0); 1176} 1177 1178android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel, 1179 android::Parcel *output_parcel) { 1180 int ret = -EINVAL; 1181 uint32_t display_id = UINT32(input_parcel->readInt32()); 1182 uint32_t min_enc_level = UINT32(input_parcel->readInt32()); 1183 1184 DLOGI("Display %d", display_id); 1185 1186 if (display_id >= HWC_NUM_DISPLAY_TYPES) { 1187 DLOGE("Invalid display_id"); 1188 } else if (display_id != HWC_DISPLAY_EXTERNAL) { 1189 DLOGE("Not supported for display"); 1190 } else if (!hwc_display_[display_id]) { 1191 DLOGW("Display is not connected"); 1192 } else { 1193 ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level); 1194 } 1195 1196 output_parcel->writeInt32(ret); 1197 1198 return ret; 1199} 1200 1201void* HWCSession::HWCUeventThread(void *context) { 1202 if (context) { 1203 return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler(); 1204 } 1205 1206 return NULL; 1207} 1208 1209void* HWCSession::HWCUeventThreadHandler() { 1210 static char uevent_data[PAGE_SIZE]; 1211 int length = 0; 1212 prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0); 1213 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 1214 if (!uevent_init()) { 1215 DLOGE("Failed to init uevent"); 1216 pthread_exit(0); 1217 return NULL; 1218 } 1219 1220 while (!uevent_thread_exit_) { 1221 // keep last 2 zeroes to ensure double 0 termination 1222 length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2); 1223 1224 if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) { 1225 DLOGI("Uevent HDMI = %s", uevent_data); 1226 int connected = GetEventValue(uevent_data, length, "SWITCH_STATE="); 1227 if (connected >= 0) { 1228 DLOGI("HDMI = %s", connected ? "connected" : "disconnected"); 1229 if (HotPlugHandler(connected) == -1) { 1230 DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected"); 1231 } 1232 } 1233 } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) { 1234 DLOGI("Uevent FB0 = %s", uevent_data); 1235 int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE="); 1236 if (panel_reset == 0) { 1237 if (hwc_procs_) { 1238 reset_panel_ = true; 1239 hwc_procs_->invalidate(hwc_procs_); 1240 } else { 1241 DLOGW("Ignore resetpanel - hwc_proc not registered"); 1242 } 1243 } 1244 } 1245 } 1246 pthread_exit(0); 1247 1248 return NULL; 1249} 1250 1251int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) { 1252 const char *iterator_str = uevent_data; 1253 while (((iterator_str - uevent_data) <= length) && (*iterator_str)) { 1254 char *pstr = strstr(iterator_str, event_info); 1255 if (pstr != NULL) { 1256 return (atoi(iterator_str + strlen(event_info))); 1257 } 1258 iterator_str += strlen(iterator_str) + 1; 1259 } 1260 1261 return -1; 1262} 1263 1264void HWCSession::ResetPanel() { 1265 int status = -EINVAL; 1266 1267 DLOGI("Powering off primary"); 1268 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC_POWER_MODE_OFF); 1269 if (status) { 1270 DLOGE("power-off on primary failed with error = %d", status); 1271 } 1272 1273 DLOGI("Restoring power mode on primary"); 1274 uint32_t mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode(); 1275 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode); 1276 if (status) { 1277 DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status); 1278 } 1279 1280 status = hwc_display_[HWC_DISPLAY_PRIMARY]->EventControl(HWC_EVENT_VSYNC, 1); 1281 if (status) { 1282 DLOGE("enabling vsync failed for primary with error = %d", status); 1283 } 1284 1285 reset_panel_ = false; 1286} 1287 1288int HWCSession::HotPlugHandler(bool connected) { 1289 int status = 0; 1290 bool notify_hotplug = false; 1291 1292 // To prevent sending events to client while a lock is held, acquire scope locks only within 1293 // below scope so that those get automatically unlocked after the scope ends. 1294 { 1295 SEQUENCE_WAIT_SCOPE_LOCK(locker_); 1296 1297 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) { 1298 DLOGE("Primay display is not connected."); 1299 return -1; 1300 } 1301 1302 if (connected) { 1303 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1304 DLOGE("HDMI is already connected"); 1305 return -1; 1306 } 1307 1308 // Connect external display if virtual display is not connected. 1309 // Else, defer external display connection and process it when virtual display 1310 // tears down; Do not notify SurfaceFlinger since connection is deferred now. 1311 if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) { 1312 status = ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL); 1313 if (status) { 1314 return status; 1315 } 1316 notify_hotplug = true; 1317 } else { 1318 DLOGI("Virtual display is connected, pending connection"); 1319 external_pending_connect_ = true; 1320 } 1321 } else { 1322 // Do not return error if external display is not in connected status. 1323 // Due to virtual display concurrency, external display connection might be still pending 1324 // but hdmi got disconnected before pending connection could be processed. 1325 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) { 1326 status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL); 1327 notify_hotplug = true; 1328 } 1329 external_pending_connect_ = false; 1330 } 1331 } 1332 if (connected && notify_hotplug) { 1333 // trigger screen refresh to ensure sufficient resources are available to process new 1334 // new display connection. 1335 hwc_procs_->invalidate(hwc_procs_); 1336 int32_t vsync_period = GetVsyncPeriod(HWC_DISPLAY_PRIMARY); 1337 usleep(vsync_period * 2 / 1000); 1338 } 1339 // notify client 1340 if (notify_hotplug) { 1341 hwc_procs_->hotplug(hwc_procs_, HWC_DISPLAY_EXTERNAL, connected); 1342 } 1343 1344 return 0; 1345} 1346 1347void HWCSession::HandleSecureDisplaySession(hwc_display_contents_1_t **displays) { 1348 secure_display_active_ = false; 1349 if (!*displays) { 1350 DLOGW("Invalid display contents"); 1351 return; 1352 } 1353 1354 hwc_display_contents_1_t *content_list = displays[HWC_DISPLAY_PRIMARY]; 1355 if (!content_list) { 1356 DLOGW("Invalid primary content list"); 1357 return; 1358 } 1359 size_t num_hw_layers = content_list->numHwLayers; 1360 1361 for (size_t i = 0; i < num_hw_layers - 1; i++) { 1362 hwc_layer_1_t &hwc_layer = content_list->hwLayers[i]; 1363 const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle); 1364 if (pvt_handle && pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) { 1365 secure_display_active_ = true; 1366 } 1367 } 1368 1369 for (ssize_t dpy = static_cast<ssize_t>(HWC_NUM_DISPLAY_TYPES - 1); dpy >= 0; dpy--) { 1370 if (hwc_display_[dpy]) { 1371 hwc_display_[dpy]->SetSecureDisplay(secure_display_active_); 1372 } 1373 } 1374} 1375 1376android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel, 1377 android::Parcel *output_parcel) { 1378 int dpy = input_parcel->readInt32(); 1379 1380 if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) { 1381 return android::BAD_VALUE;; 1382 } 1383 1384 if (!hwc_display_[dpy]) { 1385 return android::NO_INIT; 1386 } 1387 1388 hwc_rect_t visible_rect = {0, 0, 0, 0}; 1389 int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect); 1390 if (error < 0) { 1391 return error; 1392 } 1393 1394 output_parcel->writeInt32(visible_rect.left); 1395 output_parcel->writeInt32(visible_rect.top); 1396 output_parcel->writeInt32(visible_rect.right); 1397 output_parcel->writeInt32(visible_rect.bottom); 1398 1399 return android::NO_ERROR; 1400} 1401 1402} // namespace sdm 1403 1404