Home | History | Annotate | Download | only in hwc2
      1 /*
      2  * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
      3  * Not a Contribution.
      4  *
      5  * Copyright 2015 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  */
     19 
     20 #include <core/dump_interface.h>
     21 #include <core/buffer_allocator.h>
     22 #include <private/color_params.h>
     23 #include <utils/constants.h>
     24 #include <utils/String16.h>
     25 #include <cutils/properties.h>
     26 #include <hardware_legacy/uevent.h>
     27 #include <sys/resource.h>
     28 #include <sys/prctl.h>
     29 #include <binder/Parcel.h>
     30 #include <QService.h>
     31 #include <display_config.h>
     32 #include <utils/debug.h>
     33 #include <sync/sync.h>
     34 #include <profiler.h>
     35 #include <algorithm>
     36 #include <string>
     37 #include <bitset>
     38 #include <thread>
     39 #include <memory>
     40 
     41 #include "hwc_buffer_allocator.h"
     42 #include "hwc_buffer_sync_handler.h"
     43 #include "hwc_session.h"
     44 #include "hwc_debugger.h"
     45 #include "hwc_display_primary.h"
     46 #include "hwc_display_virtual.h"
     47 
     48 #define __CLASS__ "HWCSession"
     49 
     50 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
     51 #define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
     52 
     53 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
     54 
     55 hwc_module_t HAL_MODULE_INFO_SYM = {
     56   .common = {
     57     .tag = HARDWARE_MODULE_TAG,
     58     .version_major = 3,
     59     .version_minor = 0,
     60     .id = HWC_HARDWARE_MODULE_ID,
     61     .name = "QTI Hardware Composer Module",
     62     .author = "CodeAurora Forum",
     63     .methods = &g_hwc_module_methods,
     64     .dso = 0,
     65     .reserved = {0},
     66   }
     67 };
     68 
     69 namespace sdm {
     70 
     71 static HWCUEvent g_hwc_uevent_;
     72 Locker HWCSession::locker_;
     73 
     74 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
     75   const char *uevent_thread_name = "HWC_UeventThread";
     76 
     77   prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
     78   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
     79 
     80   int status = uevent_init();
     81   if (!status) {
     82     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
     83     hwc_uevent->caller_cv_.notify_one();
     84     DLOGE("Failed to init uevent with err %d", status);
     85     return;
     86   }
     87 
     88   {
     89     // Signal caller thread that worker thread is ready to listen to events.
     90     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
     91     hwc_uevent->init_done_ = true;
     92     hwc_uevent->caller_cv_.notify_one();
     93   }
     94 
     95   while (1) {
     96     char uevent_data[PAGE_SIZE] = {};
     97 
     98     // keep last 2 zeroes to ensure double 0 termination
     99     int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
    100 
    101     // scope of lock to this block only, so that caller is free to set event handler to nullptr;
    102     {
    103       std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
    104       if (hwc_uevent->uevent_listener_) {
    105         hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
    106       } else {
    107         DLOGW("UEvent dropped. No uevent listener.");
    108       }
    109     }
    110   }
    111 }
    112 
    113 HWCUEvent::HWCUEvent() {
    114   std::unique_lock<std::mutex> caller_lock(mutex_);
    115   std::thread thread(HWCUEvent::UEventThread, this);
    116   thread.detach();
    117   caller_cv_.wait(caller_lock);
    118 }
    119 
    120 void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
    121   DLOGI("Set uevent listener = %p", uevent_listener);
    122 
    123   std::lock_guard<std::mutex> obj(mutex_);
    124   uevent_listener_ = uevent_listener;
    125 }
    126 
    127 HWCSession::HWCSession(const hw_module_t *module) {
    128   hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
    129   hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
    130   hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
    131   hwc2_device_t::common.close = Close;
    132   hwc2_device_t::getCapabilities = GetCapabilities;
    133   hwc2_device_t::getFunction = GetFunction;
    134 }
    135 
    136 int HWCSession::Init() {
    137   int status = -EINVAL;
    138   const char *qservice_name = "display.qservice";
    139 
    140   if (!g_hwc_uevent_.InitDone()) {
    141     return status;
    142   }
    143 
    144   // Start QService and connect to it.
    145   qService::QService::init();
    146   android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
    147       android::defaultServiceManager()->getService(android::String16(qservice_name)));
    148 
    149   if (iqservice.get()) {
    150     iqservice->connect(android::sp<qClient::IQClient>(this));
    151     qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
    152   } else {
    153     DLOGE("Failed to acquire %s", qservice_name);
    154     return -EINVAL;
    155   }
    156 
    157   StartServices();
    158 
    159   DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
    160                                                  &buffer_sync_handler_, &socket_handler_,
    161                                                  &core_intf_);
    162   if (error != kErrorNone) {
    163     DLOGE("Display core initialization failed. Error = %d", error);
    164     return -EINVAL;
    165   }
    166 
    167   g_hwc_uevent_.Register(this);
    168 
    169   // If HDMI display is primary display, defer display creation until hotplug event is received.
    170   HWDisplayInterfaceInfo hw_disp_info = {};
    171   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
    172   if (error != kErrorNone) {
    173     g_hwc_uevent_.Register(nullptr);
    174     CoreInterface::DestroyCore();
    175     DLOGE("Primary display type not recognized. Error = %d", error);
    176     return -EINVAL;
    177   }
    178 
    179   if (hw_disp_info.type == kHDMI) {
    180     status = 0;
    181     hdmi_is_primary_ = true;
    182     // Create display if it is connected, else wait for hotplug connect event.
    183     if (hw_disp_info.is_connected) {
    184       status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
    185                                           &hwc_display_[HWC_DISPLAY_PRIMARY]);
    186     }
    187   } else {
    188     // Create and power on primary display
    189     status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
    190                                        &hwc_display_[HWC_DISPLAY_PRIMARY]);
    191     color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
    192     if (!color_mgr_) {
    193       DLOGW("Failed to load HWCColorManager.");
    194     }
    195   }
    196 
    197   if (status) {
    198     g_hwc_uevent_.Register(nullptr);
    199     CoreInterface::DestroyCore();
    200     return status;
    201   }
    202 
    203   struct rlimit fd_limit = {};
    204   getrlimit(RLIMIT_NOFILE, &fd_limit);
    205   fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
    206   if (fd_limit.rlim_cur < fd_limit.rlim_max) {
    207     auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
    208     if (err) {
    209       DLOGW("Unable to increase fd limit -  err:%d, %s", errno, strerror(errno));
    210     }
    211   }
    212 
    213   return 0;
    214 }
    215 
    216 int HWCSession::Deinit() {
    217   HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
    218   if (primary_display) {
    219     if (hdmi_is_primary_) {
    220       HWCDisplayExternal::Destroy(primary_display);
    221     } else {
    222       HWCDisplayPrimary::Destroy(primary_display);
    223     }
    224   }
    225   hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
    226 
    227   if (color_mgr_) {
    228     color_mgr_->DestroyColorManager();
    229   }
    230 
    231   g_hwc_uevent_.Register(nullptr);
    232 
    233   DisplayError error = CoreInterface::DestroyCore();
    234   if (error != kErrorNone) {
    235     DLOGE("Display core de-initialization failed. Error = %d", error);
    236   }
    237 
    238   return 0;
    239 }
    240 
    241 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
    242   SCOPE_LOCK(locker_);
    243 
    244   if (!module || !name || !device) {
    245     DLOGE("Invalid parameters.");
    246     return -EINVAL;
    247   }
    248 
    249   if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
    250     HWCSession *hwc_session = new HWCSession(module);
    251     if (!hwc_session) {
    252       return -ENOMEM;
    253     }
    254 
    255     int status = hwc_session->Init();
    256     if (status != 0) {
    257       return status;
    258     }
    259 
    260     hwc2_device_t *composer_device = hwc_session;
    261     *device = reinterpret_cast<hw_device_t *>(composer_device);
    262   }
    263 
    264   return 0;
    265 }
    266 
    267 int HWCSession::Close(hw_device_t *device) {
    268   SCOPE_LOCK(locker_);
    269 
    270   if (!device) {
    271     return -EINVAL;
    272   }
    273 
    274   hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
    275   HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
    276 
    277   hwc_session->Deinit();
    278 
    279   return 0;
    280 }
    281 
    282 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
    283                                  int32_t *outCapabilities) {
    284   if (!outCount) {
    285     return;
    286   }
    287 
    288   int value = 0;
    289   bool disable_skip_validate = false;
    290   if (Debug::Get()->GetProperty("sdm.debug.disable_skip_validate", &value) == kErrorNone) {
    291     disable_skip_validate = (value == 1);
    292   }
    293   uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
    294 
    295   if (outCapabilities != nullptr && (*outCount >= count)) {
    296     outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
    297     if (!disable_skip_validate) {
    298       outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
    299     }
    300   }
    301   *outCount = count;
    302 }
    303 
    304 template <typename PFN, typename T>
    305 static hwc2_function_pointer_t AsFP(T function) {
    306   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
    307   return reinterpret_cast<hwc2_function_pointer_t>(function);
    308 }
    309 
    310 // HWC2 functions returned in GetFunction
    311 // Defined in the same order as in the HWC2 header
    312 
    313 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
    314 
    315   if (display >= HWC_NUM_DISPLAY_TYPES) {
    316     return  HWC2_ERROR_BAD_DISPLAY;
    317   }
    318   SCOPE_LOCK(locker_);
    319   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
    320 }
    321 
    322 int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
    323                                 hwc2_layer_t *out_layer_id) {
    324   if (!out_layer_id) {
    325     return  HWC2_ERROR_BAD_PARAMETER;
    326   }
    327   if (display >= HWC_NUM_DISPLAY_TYPES) {
    328     return  HWC2_ERROR_BAD_DISPLAY;
    329   }
    330   SCOPE_LOCK(locker_);
    331   return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
    332 }
    333 
    334 int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
    335                                          int32_t *format, hwc2_display_t *out_display_id) {
    336   // TODO(user): Handle concurrency with HDMI
    337   SCOPE_LOCK(locker_);
    338   if (!device) {
    339     return HWC2_ERROR_BAD_DISPLAY;
    340   }
    341 
    342   if (!out_display_id || !width || !height || !format) {
    343     return  HWC2_ERROR_BAD_PARAMETER;
    344   }
    345 
    346   HWCSession *hwc_session = static_cast<HWCSession *>(device);
    347   auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
    348   if (status == HWC2::Error::None) {
    349     *out_display_id = HWC_DISPLAY_VIRTUAL;
    350     DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d",
    351           *out_display_id, width, height);
    352   } else {
    353     DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
    354   }
    355   return INT32(status);
    356 }
    357 
    358 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
    359                                  hwc2_layer_t layer) {
    360   if (display >= HWC_NUM_DISPLAY_TYPES) {
    361     return  HWC2_ERROR_BAD_DISPLAY;
    362   }
    363   SCOPE_LOCK(locker_);
    364   return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
    365 }
    366 
    367 int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
    368   SCOPE_LOCK(locker_);
    369   if (!device || display != HWC_DISPLAY_VIRTUAL) {
    370     return HWC2_ERROR_BAD_DISPLAY;
    371   }
    372 
    373   DLOGI("Destroying virtual display id:%" PRIu64, display);
    374   auto *hwc_session = static_cast<HWCSession *>(device);
    375 
    376   if (hwc_session->hwc_display_[display]) {
    377     HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
    378     hwc_session->hwc_display_[display] = nullptr;
    379     return HWC2_ERROR_NONE;
    380   } else {
    381     return HWC2_ERROR_BAD_DISPLAY;
    382   }
    383 }
    384 
    385 void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
    386   SCOPE_LOCK(locker_);
    387 
    388   if (!device || !out_size) {
    389     return;
    390   }
    391   auto *hwc_session = static_cast<HWCSession *>(device);
    392   const size_t max_dump_size = 8192;
    393 
    394   if (out_buffer == nullptr) {
    395     *out_size = max_dump_size;
    396   } else {
    397     char sdm_dump[4096];
    398     DumpInterface::GetDump(sdm_dump, 4096);  // TODO(user): Fix this workaround
    399     std::string s("");
    400     for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
    401       if (hwc_session->hwc_display_[id]) {
    402         s += hwc_session->hwc_display_[id]->Dump();
    403       }
    404     }
    405     s += sdm_dump;
    406     auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
    407     *out_size = UINT32(copied);
    408   }
    409 }
    410 
    411 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
    412                                hwc2_config_t *out_config) {
    413   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
    414 }
    415 
    416 static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
    417                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
    418                                           int32_t *out_types) {
    419   // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
    420   if (!out_num_elements) {
    421     return  HWC2_ERROR_BAD_PARAMETER;
    422   }
    423   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
    424                                          out_num_elements, out_layers, out_types);
    425 }
    426 
    427 static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
    428                                       uint32_t height, int32_t format, int32_t dataspace) {
    429   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
    430                                          width, height, format, dataspace);
    431 }
    432 
    433 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
    434                              int32_t /*android_color_mode_t*/ *int_out_modes) {
    435   auto out_modes = reinterpret_cast<android_color_mode_t *>(int_out_modes);
    436   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
    437                                          out_modes);
    438 }
    439 
    440 static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
    441                                    hwc2_config_t config, int32_t int_attribute,
    442                                    int32_t *out_value) {
    443   auto attribute = static_cast<HWC2::Attribute>(int_attribute);
    444   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
    445                                          attribute, out_value);
    446 }
    447 
    448 static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
    449                                  uint32_t *out_num_configs, hwc2_config_t *out_configs) {
    450   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
    451                                          out_num_configs, out_configs);
    452 }
    453 
    454 static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
    455                               char *out_name) {
    456   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
    457                                          out_name);
    458 }
    459 
    460 static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
    461                                   int32_t *out_display_requests, uint32_t *out_num_elements,
    462                                   hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
    463   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
    464                                          out_display_requests, out_num_elements, out_layers,
    465                                          out_layer_requests);
    466 }
    467 
    468 static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
    469   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
    470 }
    471 
    472 static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) {
    473   if (display == HWC_DISPLAY_PRIMARY) {
    474     *out_support = 1;
    475   } else {
    476     // TODO(user): Port over connect_display_ from HWC1
    477     // Return no error for connected displays
    478     *out_support = 0;
    479     return HWC2_ERROR_BAD_DISPLAY;
    480   }
    481   return HWC2_ERROR_NONE;
    482 }
    483 
    484 static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
    485                                   uint32_t* out_num_types, int32_t* out_types,
    486                                   float* out_max_luminance, float* out_max_average_luminance,
    487                                   float* out_min_luminance) {
    488   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
    489                                          out_num_types, out_types, out_max_luminance,
    490                                          out_max_average_luminance, out_min_luminance);
    491 }
    492 
    493 static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
    494   char property[PROPERTY_VALUE_MAX];
    495   property_get("debug.sdm.support_writeback", property, "1");
    496   return (uint32_t) atoi(property);
    497 }
    498 
    499 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
    500                                 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
    501                                 int32_t *out_fences) {
    502   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
    503                                          out_num_elements, out_layers, out_fences);
    504 }
    505 
    506 int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
    507                                    int32_t *out_retire_fence) {
    508   HWCSession *hwc_session = static_cast<HWCSession *>(device);
    509   DTRACE_SCOPED();
    510   if (!device) {
    511     return HWC2_ERROR_BAD_DISPLAY;
    512   }
    513 
    514   auto status = HWC2::Error::BadDisplay;
    515   // TODO(user): Handle virtual display/HDMI concurrency
    516   if (hwc_session->hwc_display_[display]) {
    517     status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
    518     // This is only indicative of how many times SurfaceFlinger posts
    519     // frames to the display.
    520     CALC_FPS();
    521   }
    522 
    523   return INT32(status);
    524 }
    525 
    526 int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
    527                                      hwc2_callback_data_t callback_data,
    528                                      hwc2_function_pointer_t pointer) {
    529   HWCSession *hwc_session = static_cast<HWCSession *>(device);
    530   if (!device) {
    531     return HWC2_ERROR_BAD_DISPLAY;
    532   }
    533   SCOPE_LOCK(hwc_session->callbacks_lock_);
    534   auto desc = static_cast<HWC2::Callback>(descriptor);
    535   auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
    536   DLOGD("Registering callback: %s", to_string(desc).c_str());
    537   if (descriptor == HWC2_CALLBACK_HOTPLUG) {
    538     if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY] && !hwc_session->hdmi_is_primary_) {
    539       hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
    540     }
    541   }
    542   hwc_session->callbacks_lock_.Broadcast();
    543   return INT32(error);
    544 }
    545 
    546 static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
    547                                hwc2_config_t config) {
    548   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
    549 }
    550 
    551 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
    552                                buffer_handle_t target, int32_t acquire_fence,
    553                                int32_t dataspace, hwc_region_t damage) {
    554   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
    555                                          acquire_fence, dataspace, damage);
    556 }
    557 
    558 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
    559                                  int32_t /*android_color_mode_t*/ int_mode) {
    560   auto mode = static_cast<android_color_mode_t>(int_mode);
    561   SCOPE_LOCK(locker_);
    562   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
    563 }
    564 
    565 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
    566                                       const float *matrix,
    567                                       int32_t /*android_color_transform_t*/ hint) {
    568   SCOPE_LOCK(locker_);
    569   android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
    570   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
    571                                          transform_hint);
    572 }
    573 
    574 static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    575                                  int32_t x, int32_t y) {
    576   auto status = INT32(HWC2::Error::None);
    577   status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
    578                                            layer, x, y);
    579   if (status == INT32(HWC2::Error::None)) {
    580     // Update cursor position
    581     HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
    582   }
    583   return status;
    584 }
    585 
    586 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    587                                  int32_t int_mode) {
    588   auto mode = static_cast<HWC2::BlendMode>(int_mode);
    589   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
    590 }
    591 
    592 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    593                               buffer_handle_t buffer, int32_t acquire_fence) {
    594   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
    595                                        acquire_fence);
    596 }
    597 
    598 static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    599                              hwc_color_t color) {
    600   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
    601 }
    602 
    603 static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
    604                                        hwc2_layer_t layer, int32_t int_type) {
    605   auto type = static_cast<HWC2::Composition>(int_type);
    606   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
    607                                        type);
    608 }
    609 
    610 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    611                                  int32_t dataspace) {
    612   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
    613                                        dataspace);
    614 }
    615 
    616 static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
    617                                     hwc2_layer_t layer, hwc_rect_t frame) {
    618   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
    619                                        frame);
    620 }
    621 
    622 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    623                                   float alpha) {
    624   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
    625                                        alpha);
    626 }
    627 
    628 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    629                                   hwc_frect_t crop) {
    630   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
    631 }
    632 
    633 static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
    634                                      hwc2_layer_t layer, hwc_region_t damage) {
    635   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
    636                                        damage);
    637 }
    638 
    639 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
    640                                  int32_t int_transform) {
    641   auto transform = static_cast<HWC2::Transform>(int_transform);
    642   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
    643                                        transform);
    644 }
    645 
    646 static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
    647                                      hwc2_layer_t layer, hwc_region_t visible) {
    648   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
    649                                        visible);
    650 }
    651 
    652 int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
    653                                    hwc2_layer_t layer, uint32_t z) {
    654   SCOPE_LOCK(locker_);
    655   return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
    656 }
    657 
    658 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
    659                                     buffer_handle_t buffer, int32_t releaseFence) {
    660   if (!device) {
    661     return HWC2_ERROR_BAD_DISPLAY;
    662   }
    663 
    664   if (display != HWC_DISPLAY_VIRTUAL) {
    665     return HWC2_ERROR_UNSUPPORTED;
    666   }
    667 
    668   auto *hwc_session = static_cast<HWCSession *>(device);
    669   if (hwc_session->hwc_display_[display]) {
    670     auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
    671     auto status = vds->SetOutputBuffer(buffer, releaseFence);
    672     return INT32(status);
    673   } else {
    674     return HWC2_ERROR_BAD_DISPLAY;
    675   }
    676 }
    677 
    678 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
    679   auto mode = static_cast<HWC2::PowerMode>(int_mode);
    680   SCOPE_LOCK(locker_);
    681   return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
    682 }
    683 
    684 static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
    685   auto enabled = static_cast<HWC2::Vsync>(int_enabled);
    686   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
    687 }
    688 
    689 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
    690                                     uint32_t *out_num_types, uint32_t *out_num_requests) {
    691   DTRACE_SCOPED();
    692   SCOPE_LOCK(locker_);
    693   HWCSession *hwc_session = static_cast<HWCSession *>(device);
    694   if (!device) {
    695     return HWC2_ERROR_BAD_DISPLAY;
    696   }
    697 
    698   // TODO(user): Handle secure session, handle QDCM solid fill
    699   // Handle external_pending_connect_ in CreateVirtualDisplay
    700   auto status = HWC2::Error::BadDisplay;
    701   if (hwc_session->hwc_display_[display]) {
    702     if (display == HWC_DISPLAY_PRIMARY) {
    703       // TODO(user): This can be moved to HWCDisplayPrimary
    704       if (hwc_session->reset_panel_) {
    705         DLOGW("panel is in bad state, resetting the panel");
    706         hwc_session->ResetPanel();
    707       }
    708 
    709       if (hwc_session->need_invalidate_) {
    710         hwc_session->Refresh(display);
    711       }
    712 
    713       if (hwc_session->color_mgr_) {
    714         hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
    715       }
    716     }
    717 
    718     status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
    719   }
    720   return INT32(status);
    721 }
    722 
    723 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
    724                                                 int32_t int_descriptor) {
    725   auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
    726 
    727   switch (descriptor) {
    728     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
    729       return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
    730     case HWC2::FunctionDescriptor::CreateLayer:
    731       return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
    732     case HWC2::FunctionDescriptor::CreateVirtualDisplay:
    733       return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
    734     case HWC2::FunctionDescriptor::DestroyLayer:
    735       return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
    736     case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
    737       return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
    738     case HWC2::FunctionDescriptor::Dump:
    739       return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
    740     case HWC2::FunctionDescriptor::GetActiveConfig:
    741       return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
    742     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
    743       return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
    744     case HWC2::FunctionDescriptor::GetClientTargetSupport:
    745       return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
    746     case HWC2::FunctionDescriptor::GetColorModes:
    747       return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
    748     case HWC2::FunctionDescriptor::GetDisplayAttribute:
    749       return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
    750     case HWC2::FunctionDescriptor::GetDisplayConfigs:
    751       return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
    752     case HWC2::FunctionDescriptor::GetDisplayName:
    753       return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
    754     case HWC2::FunctionDescriptor::GetDisplayRequests:
    755       return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
    756     case HWC2::FunctionDescriptor::GetDisplayType:
    757       return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
    758     case HWC2::FunctionDescriptor::GetHdrCapabilities:
    759       return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
    760     case HWC2::FunctionDescriptor::GetDozeSupport:
    761       return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
    762     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
    763       return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
    764     case HWC2::FunctionDescriptor::GetReleaseFences:
    765       return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
    766     case HWC2::FunctionDescriptor::PresentDisplay:
    767       return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
    768     case HWC2::FunctionDescriptor::RegisterCallback:
    769       return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
    770     case HWC2::FunctionDescriptor::SetActiveConfig:
    771       return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
    772     case HWC2::FunctionDescriptor::SetClientTarget:
    773       return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
    774     case HWC2::FunctionDescriptor::SetColorMode:
    775       return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
    776     case HWC2::FunctionDescriptor::SetColorTransform:
    777       return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
    778     case HWC2::FunctionDescriptor::SetCursorPosition:
    779       return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
    780     case HWC2::FunctionDescriptor::SetLayerBlendMode:
    781       return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
    782     case HWC2::FunctionDescriptor::SetLayerBuffer:
    783       return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
    784     case HWC2::FunctionDescriptor::SetLayerColor:
    785       return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
    786     case HWC2::FunctionDescriptor::SetLayerCompositionType:
    787       return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
    788     case HWC2::FunctionDescriptor::SetLayerDataspace:
    789       return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
    790     case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
    791       return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
    792     case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
    793       return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
    794     // Sideband stream is not supported
    795     // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
    796     case HWC2::FunctionDescriptor::SetLayerSourceCrop:
    797       return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
    798     case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
    799       return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
    800     case HWC2::FunctionDescriptor::SetLayerTransform:
    801       return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
    802     case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
    803       return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
    804     case HWC2::FunctionDescriptor::SetLayerZOrder:
    805       return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
    806     case HWC2::FunctionDescriptor::SetOutputBuffer:
    807       return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
    808     case HWC2::FunctionDescriptor::SetPowerMode:
    809       return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
    810     case HWC2::FunctionDescriptor::SetVsyncEnabled:
    811       return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
    812     case HWC2::FunctionDescriptor::ValidateDisplay:
    813       return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
    814     default:
    815       DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
    816             to_string(descriptor).c_str());
    817       return nullptr;
    818   }
    819   return nullptr;
    820 }
    821 
    822 // TODO(user): handle locking
    823 
    824 HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
    825                                                    int32_t *format) {
    826   if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
    827     return HWC2::Error::NoResources;
    828   }
    829   auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
    830                                           height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
    831   // TODO(user): validate width and height support
    832   if (status)
    833     return HWC2::Error::Unsupported;
    834 
    835   return HWC2::Error::None;
    836 }
    837 
    838 int32_t HWCSession::ConnectDisplay(int disp) {
    839   DLOGI("Display = %d", disp);
    840 
    841   int status = 0;
    842   uint32_t primary_width = 0;
    843   uint32_t primary_height = 0;
    844 
    845   hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
    846 
    847   if (disp == HWC_DISPLAY_EXTERNAL) {
    848     status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_, primary_width,
    849                                         primary_height, qservice_, false, &hwc_display_[disp]);
    850   } else {
    851     DLOGE("Invalid display type");
    852     return -1;
    853   }
    854 
    855   if (!status) {
    856     hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
    857   }
    858 
    859   return status;
    860 }
    861 
    862 int HWCSession::DisconnectDisplay(int disp) {
    863   DLOGI("Display = %d", disp);
    864 
    865   if (disp == HWC_DISPLAY_EXTERNAL) {
    866     HWCDisplayExternal::Destroy(hwc_display_[disp]);
    867   } else if (disp == HWC_DISPLAY_VIRTUAL) {
    868     HWCDisplayVirtual::Destroy(hwc_display_[disp]);
    869   } else {
    870     DLOGE("Invalid display type");
    871     return -1;
    872   }
    873 
    874   hwc_display_[disp] = NULL;
    875 
    876   return 0;
    877 }
    878 
    879 // Qclient methods
    880 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
    881                                              android::Parcel *output_parcel) {
    882   android::status_t status = 0;
    883 
    884   switch (command) {
    885     case qService::IQService::DYNAMIC_DEBUG:
    886       DynamicDebug(input_parcel);
    887       break;
    888 
    889     case qService::IQService::SCREEN_REFRESH:
    890       refreshScreen();
    891       break;
    892 
    893     case qService::IQService::SET_IDLE_TIMEOUT:
    894       setIdleTimeout(UINT32(input_parcel->readInt32()));
    895       break;
    896 
    897     case qService::IQService::SET_FRAME_DUMP_CONFIG:
    898       SetFrameDumpConfig(input_parcel);
    899       break;
    900 
    901     case qService::IQService::SET_MAX_PIPES_PER_MIXER:
    902       status = SetMaxMixerStages(input_parcel);
    903       break;
    904 
    905     case qService::IQService::SET_DISPLAY_MODE:
    906       status = SetDisplayMode(input_parcel);
    907       break;
    908 
    909     case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
    910         int disp_id = INT(input_parcel->readInt32());
    911         HWCDisplay::DisplayStatus disp_status =
    912               static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
    913         status = SetSecondaryDisplayStatus(disp_id, disp_status);
    914         output_parcel->writeInt32(status);
    915       }
    916       break;
    917 
    918     case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
    919       status = ConfigureRefreshRate(input_parcel);
    920       break;
    921 
    922     case qService::IQService::SET_VIEW_FRAME:
    923       break;
    924 
    925     case qService::IQService::TOGGLE_SCREEN_UPDATES: {
    926         int32_t input = input_parcel->readInt32();
    927         status = toggleScreenUpdate(input == 1);
    928         output_parcel->writeInt32(status);
    929       }
    930       break;
    931 
    932     case qService::IQService::QDCM_SVC_CMDS:
    933       status = QdcmCMDHandler(input_parcel, output_parcel);
    934       break;
    935 
    936     case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
    937         int disp_id = input_parcel->readInt32();
    938         uint32_t min_enc_level = UINT32(input_parcel->readInt32());
    939         status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
    940         output_parcel->writeInt32(status);
    941       }
    942       break;
    943 
    944     case qService::IQService::CONTROL_PARTIAL_UPDATE: {
    945         int disp_id = input_parcel->readInt32();
    946         uint32_t enable = UINT32(input_parcel->readInt32());
    947         status = ControlPartialUpdate(disp_id, enable == 1);
    948         output_parcel->writeInt32(status);
    949       }
    950       break;
    951 
    952     case qService::IQService::SET_ACTIVE_CONFIG: {
    953         uint32_t config = UINT32(input_parcel->readInt32());
    954         int disp_id = input_parcel->readInt32();
    955         status = SetActiveConfigIndex(disp_id, config);
    956       }
    957       break;
    958 
    959     case qService::IQService::GET_ACTIVE_CONFIG: {
    960         int disp_id = input_parcel->readInt32();
    961         uint32_t config = 0;
    962         status = GetActiveConfigIndex(disp_id, &config);
    963         output_parcel->writeInt32(INT(config));
    964       }
    965       break;
    966 
    967     case qService::IQService::GET_CONFIG_COUNT: {
    968         int disp_id = input_parcel->readInt32();
    969         uint32_t count = 0;
    970         status = GetConfigCount(disp_id, &count);
    971         output_parcel->writeInt32(INT(count));
    972       }
    973       break;
    974 
    975     case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
    976       status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
    977       break;
    978 
    979     case qService::IQService::GET_PANEL_BRIGHTNESS: {
    980         int level = 0;
    981         status = GetPanelBrightness(&level);
    982         output_parcel->writeInt32(level);
    983       }
    984       break;
    985 
    986     case qService::IQService::SET_PANEL_BRIGHTNESS: {
    987         uint32_t level = UINT32(input_parcel->readInt32());
    988         status = setPanelBrightness(level);
    989         output_parcel->writeInt32(status);
    990       }
    991       break;
    992 
    993     case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
    994       status = GetVisibleDisplayRect(input_parcel, output_parcel);
    995       break;
    996 
    997     case qService::IQService::SET_CAMERA_STATUS: {
    998         uint32_t camera_status = UINT32(input_parcel->readInt32());
    999         status = setCameraLaunchStatus(camera_status);
   1000       }
   1001       break;
   1002 
   1003     case qService::IQService::GET_BW_TRANSACTION_STATUS: {
   1004         bool state = true;
   1005         status = DisplayBWTransactionPending(&state);
   1006         output_parcel->writeInt32(state);
   1007       }
   1008       break;
   1009 
   1010     case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
   1011       status = SetMixerResolution(input_parcel);
   1012       break;
   1013 
   1014     case qService::IQService::SET_COLOR_MODE:
   1015       status = SetColorModeOverride(input_parcel);
   1016       break;
   1017 
   1018     case qService::IQService::SET_STAND_BY_MODE:
   1019       status = SetStandByMode(input_parcel);
   1020       break;
   1021 
   1022     default:
   1023       DLOGW("QService command = %d is not supported", command);
   1024       return -EINVAL;
   1025   }
   1026 
   1027   return status;
   1028 }
   1029 
   1030 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
   1031                                                                   *input_parcel,
   1032                                                                   android::Parcel *output_parcel) {
   1033   SCOPE_LOCK(locker_);
   1034 
   1035   int config = input_parcel->readInt32();
   1036   int dpy = input_parcel->readInt32();
   1037   int error = android::BAD_VALUE;
   1038   DisplayConfigVariableInfo display_attributes;
   1039 
   1040   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
   1041     return android::BAD_VALUE;
   1042   }
   1043 
   1044   if (hwc_display_[dpy]) {
   1045     error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
   1046     if (error == 0) {
   1047       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
   1048       output_parcel->writeInt32(INT(display_attributes.x_pixels));
   1049       output_parcel->writeInt32(INT(display_attributes.y_pixels));
   1050       output_parcel->writeFloat(display_attributes.x_dpi);
   1051       output_parcel->writeFloat(display_attributes.y_dpi);
   1052       output_parcel->writeInt32(0);  // Panel type, unsupported.
   1053     }
   1054   }
   1055 
   1056   return error;
   1057 }
   1058 
   1059 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
   1060   SCOPE_LOCK(locker_);
   1061 
   1062   uint32_t operation = UINT32(input_parcel->readInt32());
   1063   HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
   1064 
   1065   switch (operation) {
   1066     case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
   1067       return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
   1068 
   1069     case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
   1070       return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
   1071 
   1072     case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
   1073       uint32_t refresh_rate = UINT32(input_parcel->readInt32());
   1074       return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
   1075     }
   1076 
   1077     default:
   1078       DLOGW("Invalid operation %d", operation);
   1079       return -EINVAL;
   1080   }
   1081 
   1082   return 0;
   1083 }
   1084 
   1085 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
   1086   SCOPE_LOCK(locker_);
   1087 
   1088   uint32_t mode = UINT32(input_parcel->readInt32());
   1089   return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
   1090 }
   1091 
   1092 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
   1093   SCOPE_LOCK(locker_);
   1094 
   1095   DisplayError error = kErrorNone;
   1096   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
   1097   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
   1098 
   1099   if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
   1100     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
   1101       error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
   1102       if (error != kErrorNone) {
   1103         return -EINVAL;
   1104       }
   1105     }
   1106   }
   1107 
   1108   if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
   1109     if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
   1110       error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
   1111       if (error != kErrorNone) {
   1112         return -EINVAL;
   1113       }
   1114     }
   1115   }
   1116 
   1117   if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
   1118     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
   1119       error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
   1120       if (error != kErrorNone) {
   1121         return -EINVAL;
   1122       }
   1123     }
   1124   }
   1125 
   1126   return 0;
   1127 }
   1128 
   1129 void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
   1130   SCOPE_LOCK(locker_);
   1131 
   1132   uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
   1133   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
   1134   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
   1135 
   1136   if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
   1137     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
   1138       hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
   1139     }
   1140   }
   1141 
   1142   if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
   1143     if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
   1144       hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
   1145     }
   1146   }
   1147 
   1148   if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
   1149     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
   1150       hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
   1151     }
   1152   }
   1153 }
   1154 
   1155 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
   1156   SCOPE_LOCK(locker_);
   1157 
   1158   DisplayError error = kErrorNone;
   1159   uint32_t dpy = UINT32(input_parcel->readInt32());
   1160 
   1161   if (dpy != HWC_DISPLAY_PRIMARY) {
   1162     DLOGI("Resoulution change not supported for this display %d", dpy);
   1163     return -EINVAL;
   1164   }
   1165 
   1166   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
   1167     DLOGI("Primary display is not initialized");
   1168     return -EINVAL;
   1169   }
   1170 
   1171   uint32_t width = UINT32(input_parcel->readInt32());
   1172   uint32_t height = UINT32(input_parcel->readInt32());
   1173 
   1174   error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
   1175   if (error != kErrorNone) {
   1176     return -EINVAL;
   1177   }
   1178 
   1179   return 0;
   1180 }
   1181 
   1182 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
   1183   auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
   1184   auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
   1185   auto device = static_cast<hwc2_device_t *>(this);
   1186 
   1187   if (display >= HWC_NUM_DISPLAY_TYPES) {
   1188     return -EINVAL;
   1189   }
   1190 
   1191   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
   1192   if (err != HWC2_ERROR_NONE)
   1193     return -EINVAL;
   1194   return 0;
   1195 }
   1196 
   1197 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
   1198   SCOPE_LOCK(locker_);
   1199 
   1200   int type = input_parcel->readInt32();
   1201   bool enable = (input_parcel->readInt32() > 0);
   1202   DLOGI("type = %d enable = %d", type, enable);
   1203   int verbose_level = input_parcel->readInt32();
   1204 
   1205   switch (type) {
   1206     case qService::IQService::DEBUG_ALL:
   1207       HWCDebugHandler::DebugAll(enable, verbose_level);
   1208       break;
   1209 
   1210     case qService::IQService::DEBUG_MDPCOMP:
   1211       HWCDebugHandler::DebugStrategy(enable, verbose_level);
   1212       HWCDebugHandler::DebugCompManager(enable, verbose_level);
   1213       break;
   1214 
   1215     case qService::IQService::DEBUG_PIPE_LIFECYCLE:
   1216       HWCDebugHandler::DebugResources(enable, verbose_level);
   1217       break;
   1218 
   1219     case qService::IQService::DEBUG_DRIVER_CONFIG:
   1220       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
   1221       break;
   1222 
   1223     case qService::IQService::DEBUG_ROTATOR:
   1224       HWCDebugHandler::DebugResources(enable, verbose_level);
   1225       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
   1226       HWCDebugHandler::DebugRotator(enable, verbose_level);
   1227       break;
   1228 
   1229     case qService::IQService::DEBUG_QDCM:
   1230       HWCDebugHandler::DebugQdcm(enable, verbose_level);
   1231       break;
   1232 
   1233     default:
   1234       DLOGW("type = %d is not supported", type);
   1235   }
   1236 }
   1237 
   1238 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
   1239                                              android::Parcel *output_parcel) {
   1240   int ret = 0;
   1241   int32_t *brightness_value = NULL;
   1242   uint32_t display_id(0);
   1243   PPPendingParams pending_action;
   1244   PPDisplayAPIPayload resp_payload, req_payload;
   1245 
   1246   if (!color_mgr_) {
   1247     return -1;
   1248   }
   1249 
   1250   pending_action.action = kNoAction;
   1251   pending_action.params = NULL;
   1252 
   1253   // Read display_id, payload_size and payload from in_parcel.
   1254   ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
   1255   if (!ret) {
   1256     if (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY])
   1257       ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload, &resp_payload,
   1258                                                                     &pending_action);
   1259 
   1260     if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL])
   1261       ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload,
   1262                                                                      &pending_action);
   1263   }
   1264 
   1265   if (ret) {
   1266     output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
   1267     req_payload.DestroyPayload();
   1268     resp_payload.DestroyPayload();
   1269     return ret;
   1270   }
   1271 
   1272   switch (pending_action.action) {
   1273     case kInvalidating:
   1274       Refresh(HWC_DISPLAY_PRIMARY);
   1275       break;
   1276     case kEnterQDCMMode:
   1277       ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
   1278       break;
   1279     case kExitQDCMMode:
   1280       ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
   1281       break;
   1282     case kApplySolidFill:
   1283       ret =
   1284           color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
   1285       Refresh(HWC_DISPLAY_PRIMARY);
   1286       break;
   1287     case kDisableSolidFill:
   1288       ret =
   1289           color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
   1290       Refresh(HWC_DISPLAY_PRIMARY);
   1291       break;
   1292     case kSetPanelBrightness:
   1293       brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
   1294       if (brightness_value == NULL) {
   1295         DLOGE("Brightness value is Null");
   1296         return -EINVAL;
   1297       }
   1298       if (HWC_DISPLAY_PRIMARY == display_id)
   1299         ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
   1300       break;
   1301     case kEnableFrameCapture:
   1302       ret = color_mgr_->SetFrameCapture(pending_action.params, true,
   1303                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
   1304       Refresh(HWC_DISPLAY_PRIMARY);
   1305       break;
   1306     case kDisableFrameCapture:
   1307       ret = color_mgr_->SetFrameCapture(pending_action.params, false,
   1308                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
   1309       break;
   1310     case kConfigureDetailedEnhancer:
   1311       ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
   1312                                             hwc_display_[HWC_DISPLAY_PRIMARY]);
   1313       Refresh(HWC_DISPLAY_PRIMARY);
   1314       break;
   1315     case kNoAction:
   1316       break;
   1317     default:
   1318       DLOGW("Invalid pending action = %d!", pending_action.action);
   1319       break;
   1320   }
   1321 
   1322   // for display API getter case, marshall returned params into out_parcel.
   1323   output_parcel->writeInt32(ret);
   1324   HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
   1325   req_payload.DestroyPayload();
   1326   resp_payload.DestroyPayload();
   1327   hwc_display_[display_id]->ResetValidation();
   1328 
   1329   return (ret ? -EINVAL : 0);
   1330 }
   1331 
   1332 void HWCSession::UEventHandler(const char *uevent_data, int length) {
   1333   if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
   1334     DLOGI("Uevent HDMI = %s", uevent_data);
   1335     int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
   1336     if (connected >= 0) {
   1337       DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
   1338       if (HotPlugHandler(connected) == -1) {
   1339         DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
   1340       }
   1341     }
   1342   } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
   1343     DLOGI("Uevent FB0 = %s", uevent_data);
   1344     int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
   1345     if (panel_reset == 0) {
   1346       Refresh(0);
   1347       reset_panel_ = true;
   1348     }
   1349   }
   1350 }
   1351 
   1352 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
   1353   const char *iterator_str = uevent_data;
   1354   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
   1355     const char *pstr = strstr(iterator_str, event_info);
   1356     if (pstr != NULL) {
   1357       return (atoi(iterator_str + strlen(event_info)));
   1358     }
   1359     iterator_str += strlen(iterator_str) + 1;
   1360   }
   1361 
   1362   return -1;
   1363 }
   1364 
   1365 void HWCSession::ResetPanel() {
   1366   HWC2::Error status;
   1367 
   1368   DLOGI("Powering off primary");
   1369   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
   1370   if (status != HWC2::Error::None) {
   1371     DLOGE("power-off on primary failed with error = %d", status);
   1372   }
   1373 
   1374   DLOGI("Restoring power mode on primary");
   1375   HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
   1376   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
   1377   if (status != HWC2::Error::None) {
   1378     DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
   1379   }
   1380 
   1381   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
   1382   if (status != HWC2::Error::None) {
   1383     DLOGE("enabling vsync failed for primary with error = %d", status);
   1384   }
   1385 
   1386   reset_panel_ = false;
   1387 }
   1388 
   1389 int HWCSession::HotPlugHandler(bool connected) {
   1390   int status = 0;
   1391   bool notify_hotplug = false;
   1392 
   1393   // To prevent sending events to client while a lock is held, acquire scope locks only within
   1394   // below scope so that those get automatically unlocked after the scope ends.
   1395   do {
   1396     SCOPE_LOCK(locker_);
   1397 
   1398     // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
   1399     //    if it is already created, but got disconnected/connected again,
   1400     //    just toggle display status and do not notify surfaceflinger.
   1401     // If HDMI is not primary, create/destroy external display normally.
   1402     if (hdmi_is_primary_) {
   1403       if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
   1404         status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
   1405       } else {
   1406         status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
   1407                                             qservice_, &hwc_display_[HWC_DISPLAY_PRIMARY]);
   1408         notify_hotplug = true;
   1409       }
   1410 
   1411       break;
   1412     }
   1413 
   1414     // Primary display must be connected for HDMI as secondary cases.
   1415     if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
   1416       DLOGE("Primary display is not connected.");
   1417       return -1;
   1418     }
   1419 
   1420     if (connected) {
   1421       // Connect external display if virtual display is not connected.
   1422       // Else, defer external display connection and process it when virtual display
   1423       // tears down; Do not notify SurfaceFlinger since connection is deferred now.
   1424       if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
   1425         status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
   1426         if (status) {
   1427           return status;
   1428         }
   1429         notify_hotplug = true;
   1430       } else {
   1431         DLOGI("Virtual display is connected, pending connection");
   1432         external_pending_connect_ = true;
   1433       }
   1434     } else {
   1435       // Do not return error if external display is not in connected status.
   1436       // Due to virtual display concurrency, external display connection might be still pending
   1437       // but hdmi got disconnected before pending connection could be processed.
   1438       if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
   1439         status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
   1440         notify_hotplug = true;
   1441       }
   1442       external_pending_connect_ = false;
   1443     }
   1444   } while (0);
   1445 
   1446   if (connected) {
   1447     Refresh(0);
   1448 
   1449     if (!hdmi_is_primary_) {
   1450       // wait for sufficient time to ensure sufficient resources are available to process new
   1451       // new display connection.
   1452       uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
   1453       usleep(vsync_period * 2 / 1000);
   1454     }
   1455   }
   1456 
   1457   // notify client
   1458   if (notify_hotplug) {
   1459     HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
   1460             connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
   1461   }
   1462 
   1463   qservice_->onHdmiHotplug(INT(connected));
   1464 
   1465   return 0;
   1466 }
   1467 
   1468 int HWCSession::GetVsyncPeriod(int disp) {
   1469   SCOPE_LOCK(locker_);
   1470   // default value
   1471   int32_t vsync_period = 1000000000l / 60;
   1472   auto attribute = HWC2::Attribute::VsyncPeriod;
   1473 
   1474   if (hwc_display_[disp]) {
   1475     hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
   1476   }
   1477 
   1478   return vsync_period;
   1479 }
   1480 
   1481 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
   1482                                                     android::Parcel *output_parcel) {
   1483   SCOPE_LOCK(locker_);
   1484 
   1485   int dpy = input_parcel->readInt32();
   1486   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
   1487     return android::BAD_VALUE;
   1488   }
   1489 
   1490   if (!hwc_display_[dpy]) {
   1491     return android::NO_INIT;
   1492   }
   1493 
   1494   hwc_rect_t visible_rect = {0, 0, 0, 0};
   1495   int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
   1496   if (error < 0) {
   1497     return error;
   1498   }
   1499 
   1500   output_parcel->writeInt32(visible_rect.left);
   1501   output_parcel->writeInt32(visible_rect.top);
   1502   output_parcel->writeInt32(visible_rect.right);
   1503   output_parcel->writeInt32(visible_rect.bottom);
   1504 
   1505   return android::NO_ERROR;
   1506 }
   1507 
   1508 android::status_t HWCSession::SetStandByMode(const android::Parcel *input_parcel) {
   1509   SCOPE_LOCK(locker_);
   1510 
   1511   bool enable = (input_parcel->readInt32() > 0);
   1512 
   1513   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
   1514     DLOGI("Primary display is not initialized");
   1515     return -EINVAL;
   1516   }
   1517 
   1518   hwc_display_[HWC_DISPLAY_PRIMARY]->SetStandByMode(enable);
   1519 
   1520   return android::NO_ERROR;
   1521 }
   1522 
   1523 void HWCSession::Refresh(hwc2_display_t display) {
   1524   SCOPE_LOCK(callbacks_lock_);
   1525   HWC2::Error err = callbacks_.Refresh(display);
   1526   while (err != HWC2::Error::None) {
   1527     callbacks_lock_.Wait();
   1528     err = callbacks_.Refresh(display);
   1529   }
   1530 }
   1531 
   1532 void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
   1533   SCOPE_LOCK(callbacks_lock_);
   1534   HWC2::Error err = callbacks_.Hotplug(display, state);
   1535   while (err != HWC2::Error::None) {
   1536     callbacks_lock_.Wait();
   1537     err = callbacks_.Hotplug(display, state);
   1538   }
   1539 }
   1540 
   1541 }  // namespace sdm
   1542