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 
UEventThread(HWCUEvent * hwc_uevent)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 
HWCUEvent()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 
Register(HWCUEventListener * uevent_listener)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 
HWCSession(const hw_module_t * module)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 
Init()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 
Deinit()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 
Open(const hw_module_t * module,const char * name,hw_device_t ** device)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 
Close(hw_device_t * device)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 
GetCapabilities(struct hwc2_device * device,uint32_t * outCount,int32_t * outCapabilities)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>
AsFP(T function)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 
AcceptDisplayChanges(hwc2_device_t * device,hwc2_display_t display)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 
CreateLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * out_layer_id)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 
CreateVirtualDisplay(hwc2_device_t * device,uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)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 
DestroyLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)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 
DestroyVirtualDisplay(hwc2_device_t * device,hwc2_display_t display)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 
Dump(hwc2_device_t * device,uint32_t * out_size,char * out_buffer)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 
GetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t * out_config)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 
GetChangedCompositionTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)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 
GetClientTargetSupport(hwc2_device_t * device,hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)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 
GetColorModes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_modes,int32_t * int_out_modes)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 
GetDisplayAttribute(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,int32_t int_attribute,int32_t * out_value)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 
GetDisplayConfigs(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)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 
GetDisplayName(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_size,char * out_name)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 
GetDisplayRequests(hwc2_device_t * device,hwc2_display_t display,int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_layer_requests)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 
GetDisplayType(hwc2_device_t * device,hwc2_display_t display,int32_t * out_type)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 
GetDozeSupport(hwc2_device_t * device,hwc2_display_t display,int32_t * out_support)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 
GetHdrCapabilities(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,int32_t * out_types,float * out_max_luminance,float * out_max_average_luminance,float * out_min_luminance)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 
GetMaxVirtualDisplayCount(hwc2_device_t * device)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 
GetReleaseFences(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)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 
PresentDisplay(hwc2_device_t * device,hwc2_display_t display,int32_t * out_retire_fence)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 
RegisterCallback(hwc2_device_t * device,int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)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 
SetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config)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 
SetClientTarget(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)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 
SetColorMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)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 
SetColorTransform(hwc2_device_t * device,hwc2_display_t display,const float * matrix,int32_t hint)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 
SetCursorPosition(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t x,int32_t y)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 
SetLayerBlendMode(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_mode)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 
SetLayerBuffer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,int32_t acquire_fence)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 
SetLayerColor(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_color_t color)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 
SetLayerCompositionType(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_type)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 
SetLayerDataspace(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)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 
SetLayerDisplayFrame(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)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 
SetLayerPlaneAlpha(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,float alpha)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 
SetLayerSourceCrop(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)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 
SetLayerSurfaceDamage(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t damage)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 
SetLayerTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_transform)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 
SetLayerVisibleRegion(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t visible)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 
SetLayerZOrder(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t z)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 
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t releaseFence)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 
SetPowerMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)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 
SetVsyncEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t int_enabled)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 
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)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 
GetFunction(struct hwc2_device * device,int32_t int_descriptor)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 
CreateVirtualDisplayObject(uint32_t width,uint32_t height,int32_t * format)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 
ConnectDisplay(int disp)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 
DisconnectDisplay(int disp)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
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)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 
HandleGetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)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 
ConfigureRefreshRate(const android::Parcel * input_parcel)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 
SetDisplayMode(const android::Parcel * input_parcel)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 
SetMaxMixerStages(const android::Parcel * input_parcel)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 
SetFrameDumpConfig(const android::Parcel * input_parcel)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 
SetMixerResolution(const android::Parcel * input_parcel)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 
SetColorModeOverride(const android::Parcel * input_parcel)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 
DynamicDebug(const android::Parcel * input_parcel)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 
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)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 
UEventHandler(const char * uevent_data,int length)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 
GetEventValue(const char * uevent_data,int length,const char * event_info)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 
ResetPanel()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 
HotPlugHandler(bool connected)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 
GetVsyncPeriod(int disp)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 
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)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 
SetStandByMode(const android::Parcel * input_parcel)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 
Refresh(hwc2_display_t display)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 
HotPlug(hwc2_display_t display,HWC2::Connection state)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