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 <QService.h>
21 #include <binder/Parcel.h>
22 #include <core/buffer_allocator.h>
23 #include <cutils/properties.h>
24 #include <display_config.h>
25 #include <hardware_legacy/uevent.h>
26 #include <private/color_params.h>
27 #include <qd_utils.h>
28 #include <sync/sync.h>
29 #include <sys/prctl.h>
30 #include <sys/resource.h>
31 #include <utils/String16.h>
32 #include <utils/constants.h>
33 #include <utils/debug.h>
34 #include <utils/utils.h>
35 #include <algorithm>
36 #include <bitset>
37 #include <memory>
38 #include <string>
39 #include <thread>
40 #include <vector>
41 
42 #include "hwc_buffer_allocator.h"
43 #include "hwc_buffer_sync_handler.h"
44 #include "hwc_session.h"
45 #include "hwc_debugger.h"
46 #include "hwc_display_primary.h"
47 #include "hwc_display_virtual.h"
48 #include "hwc_display_external_test.h"
49 
50 #define __CLASS__ "HWCSession"
51 
52 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
53 #define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
54 #define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
55 
56 #define MAX_BRIGHTNESS 255
57 #define BRIGHTNESS_FILE1 "/sys/class/leds/lcd-backlight/brightness"
58 #define BRIGHTNESS_FILE2 "/sys/class/backlight/panel0-backlight/brightness"
59 
60 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
61 
62 hwc_module_t HAL_MODULE_INFO_SYM = {
63   .common = {
64     .tag = HARDWARE_MODULE_TAG,
65     .version_major = 3,
66     .version_minor = 0,
67     .id = HWC_HARDWARE_MODULE_ID,
68     .name = "QTI Hardware Composer Module",
69     .author = "CodeAurora Forum",
70     .methods = &g_hwc_module_methods,
71     .dso = 0,
72     .reserved = {0},
73   }
74 };
75 
76 namespace sdm {
77 
78 static HWCUEvent g_hwc_uevent_;
79 Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
80 static const int kSolidFillDelay = 100 * 1000;
81 
UEventThread(HWCUEvent * hwc_uevent)82 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
83   const char *uevent_thread_name = "HWC_UeventThread";
84 
85   prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
86   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
87 
88   int status = uevent_init();
89   if (!status) {
90     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
91     hwc_uevent->caller_cv_.notify_one();
92     DLOGE("Failed to init uevent with err %d", status);
93     return;
94   }
95 
96   {
97     // Signal caller thread that worker thread is ready to listen to events.
98     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
99     hwc_uevent->init_done_ = true;
100     hwc_uevent->caller_cv_.notify_one();
101   }
102 
103   while (1) {
104     char uevent_data[PAGE_SIZE] = {};
105 
106     // keep last 2 zeroes to ensure double 0 termination
107     int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
108 
109     // scope of lock to this block only, so that caller is free to set event handler to nullptr;
110     {
111       std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
112       if (hwc_uevent->uevent_listener_) {
113         hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
114       } else {
115         DLOGW("UEvent dropped. No uevent listener.");
116       }
117     }
118   }
119 }
120 
HWCUEvent()121 HWCUEvent::HWCUEvent() {
122   std::unique_lock<std::mutex> caller_lock(mutex_);
123   std::thread thread(HWCUEvent::UEventThread, this);
124   thread.detach();
125   caller_cv_.wait(caller_lock);
126 }
127 
Register(HWCUEventListener * uevent_listener)128 void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
129   DLOGI("Set uevent listener = %p", uevent_listener);
130 
131   std::lock_guard<std::mutex> obj(mutex_);
132   uevent_listener_ = uevent_listener;
133 }
134 
HWCSession(const hw_module_t * module)135 HWCSession::HWCSession(const hw_module_t *module) {
136   hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
137   hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
138   hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
139   hwc2_device_t::common.close = Close;
140   hwc2_device_t::getCapabilities = GetCapabilities;
141   hwc2_device_t::getFunction = GetFunction;
142 }
143 
Init()144 int HWCSession::Init() {
145   SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
146 
147   int status = -EINVAL;
148   const char *qservice_name = "display.qservice";
149 
150   if (!g_hwc_uevent_.InitDone()) {
151     return status;
152   }
153 
154   // Start QService and connect to it.
155   qService::QService::init();
156   android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
157       android::defaultServiceManager()->getService(android::String16(qservice_name)));
158 
159   if (iqservice.get()) {
160     iqservice->connect(android::sp<qClient::IQClient>(this));
161     qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
162   } else {
163     DLOGE("Failed to acquire %s", qservice_name);
164     return -EINVAL;
165   }
166 
167   StartServices();
168 
169   g_hwc_uevent_.Register(this);
170 
171   auto error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_,
172                                     &socket_handler_, &core_intf_);
173 
174   // If HDMI display is primary display, defer display creation until hotplug event is received.
175   HWDisplayInterfaceInfo hw_disp_info = {};
176   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
177   if (error != kErrorNone) {
178     g_hwc_uevent_.Register(nullptr);
179     CoreInterface::DestroyCore();
180     DLOGE("Primary display type not recognized. Error = %d", error);
181     return -EINVAL;
182   }
183 
184   if (hw_disp_info.type == kHDMI) {
185     status = 0;
186     hdmi_is_primary_ = true;
187     // Create display if it is connected, else wait for hotplug connect event.
188     if (hw_disp_info.is_connected) {
189       status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
190     }
191   } else {
192     // Create and power on primary display
193     status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
194                                        &hwc_display_[HWC_DISPLAY_PRIMARY]);
195     color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
196     if (!color_mgr_) {
197       DLOGW("Failed to load HWCColorManager.");
198     }
199   }
200 
201   if (status) {
202     g_hwc_uevent_.Register(nullptr);
203     CoreInterface::DestroyCore();
204     return status;
205   }
206 
207   is_composer_up_ = true;
208   struct rlimit fd_limit = {};
209   getrlimit(RLIMIT_NOFILE, &fd_limit);
210   fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
211   if (fd_limit.rlim_cur < fd_limit.rlim_max) {
212     auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
213     if (err) {
214       DLOGW("Unable to increase fd limit -  err:%d, %s", errno, strerror(errno));
215     }
216   }
217 
218   char const *brightness_file;
219   if (access(BRIGHTNESS_FILE1, F_OK) == 0) {
220     brightness_file = BRIGHTNESS_FILE1;
221   } else {
222     brightness_file = BRIGHTNESS_FILE2;
223   }
224   brightness_fd_ = open(brightness_file, O_WRONLY);
225   if (brightness_fd_ == -1) {
226     DLOGW("Unable to open brightness file: [%d] %s", errno, strerror(errno));
227   }
228 
229   return 0;
230 }
231 
Deinit()232 int HWCSession::Deinit() {
233   Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
234   Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
235   Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
236 
237   HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
238   if (primary_display) {
239     if (hdmi_is_primary_) {
240       HWCDisplayExternal::Destroy(primary_display);
241     } else {
242       HWCDisplayPrimary::Destroy(primary_display);
243     }
244   }
245   hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
246 
247   if (color_mgr_) {
248     color_mgr_->DestroyColorManager();
249   }
250 
251   g_hwc_uevent_.Register(nullptr);
252 
253   DisplayError error = CoreInterface::DestroyCore();
254   if (error != kErrorNone) {
255     DLOGE("Display core de-initialization failed. Error = %d", error);
256   }
257 
258   close(brightness_fd_);
259 
260   return 0;
261 }
262 
Open(const hw_module_t * module,const char * name,hw_device_t ** device)263 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
264   if (!module || !name || !device) {
265     DLOGE("Invalid parameters.");
266     return -EINVAL;
267   }
268 
269   if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
270     HWCSession *hwc_session = new HWCSession(module);
271     if (!hwc_session) {
272       return -ENOMEM;
273     }
274 
275     int status = hwc_session->Init();
276     if (status != 0) {
277       delete hwc_session;
278       hwc_session = NULL;
279       return status;
280     }
281 
282     hwc2_device_t *composer_device = hwc_session;
283     *device = reinterpret_cast<hw_device_t *>(composer_device);
284   }
285 
286   return 0;
287 }
288 
Close(hw_device_t * device)289 int HWCSession::Close(hw_device_t *device) {
290   if (!device) {
291     return -EINVAL;
292   }
293 
294   hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
295   HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
296 
297   hwc_session->Deinit();
298 
299   return 0;
300 }
301 
GetCapabilities(struct hwc2_device * device,uint32_t * outCount,int32_t * outCapabilities)302 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
303                                  int32_t *outCapabilities) {
304   if (!outCount) {
305     return;
306   }
307 
308   int value = 0;
309   bool disable_skip_validate = false;
310   if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
311     disable_skip_validate = (value == 1);
312   }
313   uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
314 
315   if (outCapabilities != nullptr && (*outCount >= count)) {
316     outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
317     if (!disable_skip_validate) {
318       outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
319     }
320   }
321   *outCount = count;
322 }
323 
GetDisplayBrightnessSupport(hwc2_device_t * device,hwc2_display_t display,bool * out_support)324 int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display,
325                                                 bool *out_support) {
326   HWCSession *hwc_session = static_cast<HWCSession *>(device);
327   *out_support = display == HWC_DISPLAY_PRIMARY && hwc_session->brightness_fd_ != -1;
328   return INT32(HWC2::Error::None);
329 }
330 
331 template <typename PFN, typename T>
AsFP(T function)332 static hwc2_function_pointer_t AsFP(T function) {
333   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
334   return reinterpret_cast<hwc2_function_pointer_t>(function);
335 }
336 
337 // HWC2 functions returned in GetFunction
338 // Defined in the same order as in the HWC2 header
339 
AcceptDisplayChanges(hwc2_device_t * device,hwc2_display_t display)340 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
341   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
342 }
343 
CreateLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * out_layer_id)344 int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
345                                 hwc2_layer_t *out_layer_id) {
346   if (!out_layer_id) {
347     return  HWC2_ERROR_BAD_PARAMETER;
348   }
349 
350   return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
351 }
352 
CreateVirtualDisplay(hwc2_device_t * device,uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)353 int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
354                                          int32_t *format, hwc2_display_t *out_display_id) {
355   // TODO(user): Handle concurrency with HDMI
356   if (!device) {
357     return HWC2_ERROR_BAD_DISPLAY;
358   }
359 
360   if (!out_display_id || !width || !height || !format) {
361     return  HWC2_ERROR_BAD_PARAMETER;
362   }
363 
364   HWCSession *hwc_session = static_cast<HWCSession *>(device);
365   auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
366 
367   if (status == HWC2::Error::None) {
368     *out_display_id = HWC_DISPLAY_VIRTUAL;
369     DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d",
370           *out_display_id, width, height);
371   } else {
372     DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
373   }
374   return INT32(status);
375 }
376 
DestroyLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)377 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
378                                  hwc2_layer_t layer) {
379   return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
380 }
381 
DestroyVirtualDisplay(hwc2_device_t * device,hwc2_display_t display)382 int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
383   if (!device || display != HWC_DISPLAY_VIRTUAL) {
384     return HWC2_ERROR_BAD_DISPLAY;
385   }
386 
387   SCOPE_LOCK(locker_[display]);
388   DLOGI("Destroying virtual display id:%" PRIu64, display);
389   auto *hwc_session = static_cast<HWCSession *>(device);
390 
391   if (hwc_session->hwc_display_[display]) {
392     HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
393     hwc_session->hwc_display_[display] = nullptr;
394     return HWC2_ERROR_NONE;
395   } else {
396     return HWC2_ERROR_BAD_DISPLAY;
397   }
398 }
399 
Dump(hwc2_device_t * device,uint32_t * out_size,char * out_buffer)400 void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
401   if (!device || !out_size) {
402     return;
403   }
404 
405   auto *hwc_session = static_cast<HWCSession *>(device);
406   const size_t max_dump_size = 8192;
407 
408   if (out_buffer == nullptr) {
409     *out_size = max_dump_size;
410   } else {
411     std::string s {};
412     for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
413       SCOPE_LOCK(locker_[id]);
414       if (hwc_session->hwc_display_[id]) {
415         s += hwc_session->hwc_display_[id]->Dump();
416       }
417     }
418     auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
419     *out_size = UINT32(copied);
420   }
421 }
422 
GetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t * out_config)423 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
424                                hwc2_config_t *out_config) {
425   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
426 }
427 
GetChangedCompositionTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)428 static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
429                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
430                                           int32_t *out_types) {
431   // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
432   if (!out_num_elements) {
433     return  HWC2_ERROR_BAD_PARAMETER;
434   }
435   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
436                                          out_num_elements, out_layers, out_types);
437 }
438 
GetClientTargetSupport(hwc2_device_t * device,hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)439 static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
440                                       uint32_t height, int32_t format, int32_t dataspace) {
441   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
442                                          width, height, format, dataspace);
443 }
444 
GetColorModes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_modes,int32_t * int_out_modes)445 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
446                              int32_t /*ColorMode*/ *int_out_modes) {
447   auto out_modes = reinterpret_cast<ColorMode *>(int_out_modes);
448   if (out_num_modes == nullptr) {
449     return HWC2_ERROR_BAD_PARAMETER;
450   }
451   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
452                                          out_modes);
453 }
454 
GetRenderIntents(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode,uint32_t * out_num_intents,int32_t * int_out_intents)455 static int32_t GetRenderIntents(hwc2_device_t *device, hwc2_display_t display,
456                                 int32_t /*ColorMode*/ int_mode, uint32_t *out_num_intents,
457                                 int32_t /*RenderIntent*/ *int_out_intents) {
458   auto mode = static_cast<ColorMode>(int_mode);
459   auto out_intents = reinterpret_cast<RenderIntent *>(int_out_intents);
460   if (out_num_intents == nullptr) {
461     return HWC2_ERROR_BAD_PARAMETER;
462   }
463 
464   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
465     DLOGE("Invalid ColorMode: %d", mode);
466     return HWC2_ERROR_BAD_PARAMETER;
467   }
468   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetRenderIntents, mode,
469                                          out_num_intents, out_intents);
470 }
471 
GetDataspaceSaturationMatrix(hwc2_device_t * device,int32_t int_dataspace,float * out_matrix)472 static int32_t GetDataspaceSaturationMatrix(hwc2_device_t *device,
473                                             int32_t /*Dataspace*/ int_dataspace,
474                                             float *out_matrix) {
475   auto dataspace = static_cast<Dataspace>(int_dataspace);
476   if (device == nullptr || out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
477     return HWC2_ERROR_BAD_PARAMETER;
478   }
479   // We only have the matrix for sRGB
480   float saturation_matrix[kDataspaceSaturationMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
481                                                                0.0, 1.0, 0.0, 0.0, \
482                                                                0.0, 0.0, 1.0, 0.0, \
483                                                                0.0, 0.0, 0.0, 1.0 };
484 
485   // TODO(user): This value should ideally be retrieved from a QDCM configuration file
486   char value[kPropertyMax] = {};
487   if (Debug::Get()->GetProperty(DATASPACE_SATURATION_MATRIX_PROP, value) != kErrorNone) {
488     DLOGW("Undefined saturation matrix");
489     return HWC2_ERROR_BAD_CONFIG;
490   }
491   std::string value_string(value);
492   std::size_t start = 0, end = 0;
493   int index = 0;
494   while ((end = value_string.find(",", start)) != std::string::npos) {
495     saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
496     start = end + 1;
497     index++;
498     // We expect a 3x3, SF needs 4x4, keep the last row/column identity
499     if ((index + 1) % 4 == 0) {
500       index++;
501     }
502   }
503   saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
504   if (index < kDataspaceSaturationPropertyElements - 1) {
505     // The property must have kDataspaceSaturationPropertyElements delimited by commas
506     DLOGW("Invalid saturation matrix defined");
507     return HWC2_ERROR_BAD_CONFIG;
508   }
509   for (int32_t i = 0; i < kDataspaceSaturationMatrixCount; i += 4) {
510     DLOGD("%f %f %f %f", saturation_matrix[i], saturation_matrix[i + 1], saturation_matrix[i + 2],
511           saturation_matrix[i + 3]);
512   }
513   for (uint32_t i = 0; i < kDataspaceSaturationMatrixCount; i++) {
514     out_matrix[i] = saturation_matrix[i];
515   }
516   return HWC2_ERROR_NONE;
517 }
518 
GetPerFrameMetadataKeys(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_keys,int32_t * int_out_keys)519 static int32_t GetPerFrameMetadataKeys(hwc2_device_t *device, hwc2_display_t display,
520                                        uint32_t *out_num_keys, int32_t *int_out_keys) {
521   auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
522   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetPerFrameMetadataKeys,
523                                          out_num_keys, out_keys);
524 }
525 
SetLayerPerFrameMetadata(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t num_elements,const int32_t * int_keys,const float * metadata)526 static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t display,
527                                         hwc2_layer_t layer, uint32_t num_elements,
528                                         const int32_t *int_keys, const float *metadata) {
529   auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
530   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPerFrameMetadata,
531                                        num_elements, keys, metadata);
532 }
533 
SetDisplayedContentSamplingEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t enabled,uint8_t component_mask,uint64_t max_frames)534 static int32_t SetDisplayedContentSamplingEnabled(hwc2_device_t* device,
535                                                   hwc2_display_t display,
536                                                   int32_t enabled, uint8_t component_mask,
537                                                   uint64_t max_frames) {
538     static constexpr int32_t validComponentMask =
539         HWC2_FORMAT_COMPONENT_0 | HWC2_FORMAT_COMPONENT_1 |
540         HWC2_FORMAT_COMPONENT_2 | HWC2_FORMAT_COMPONENT_3;
541     if (component_mask & ~validComponentMask) return HWC2_ERROR_BAD_PARAMETER;
542     return HWCSession::CallDisplayFunction(device, display,
543                                            &HWCDisplay::SetDisplayedContentSamplingEnabled,
544                                            enabled, component_mask, max_frames);
545 }
546 
GetDisplayedContentSamplingAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace,uint8_t * supported_components)547 static int32_t GetDisplayedContentSamplingAttributes(hwc2_device_t* device,
548                                                      hwc2_display_t display,
549                                                      int32_t* format,
550                                                      int32_t* dataspace,
551                                                      uint8_t* supported_components) {
552     return HWCSession::CallDisplayFunction(device, display,
553                                            &HWCDisplay::GetDisplayedContentSamplingAttributes,
554                                            format, dataspace, supported_components);
555 }
556 
GetDisplayedContentSample(hwc2_device_t * device,hwc2_display_t display,uint64_t max_frames,uint64_t timestamp,uint64_t * numFrames,int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],uint64_t * samples[NUM_HISTOGRAM_COLOR_COMPONENTS])557 static int32_t GetDisplayedContentSample(
558     hwc2_device_t* device, hwc2_display_t display, uint64_t max_frames, uint64_t timestamp,
559     uint64_t* numFrames,
560     int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
561     uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
562 
563     return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayedContentSample,
564                                     max_frames, timestamp, numFrames, samples_size, samples);
565 }
566 
GetDisplayAttribute(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,int32_t int_attribute,int32_t * out_value)567 static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
568                                    hwc2_config_t config, int32_t int_attribute,
569                                    int32_t *out_value) {
570   if (out_value == nullptr || int_attribute < HWC2_ATTRIBUTE_INVALID ||
571       int_attribute > HWC2_ATTRIBUTE_DPI_Y) {
572     return HWC2_ERROR_BAD_PARAMETER;
573   }
574   auto attribute = static_cast<HWC2::Attribute>(int_attribute);
575   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
576                                          attribute, out_value);
577 }
578 
GetDisplayConfigs(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)579 static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
580                                  uint32_t *out_num_configs, hwc2_config_t *out_configs) {
581   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
582                                          out_num_configs, out_configs);
583 }
584 
GetDisplayName(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_size,char * out_name)585 static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
586                               char *out_name) {
587   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
588                                          out_name);
589 }
590 
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)591 static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
592                                   int32_t *out_display_requests, uint32_t *out_num_elements,
593                                   hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
594   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
595                                          out_display_requests, out_num_elements, out_layers,
596                                          out_layer_requests);
597 }
598 
GetDisplayType(hwc2_device_t * device,hwc2_display_t display,int32_t * out_type)599 static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
600   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
601 }
602 
GetDozeSupport(hwc2_device_t * device,hwc2_display_t display,int32_t * out_support)603 int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
604                                   int32_t *out_support) {
605   if (!device || !out_support) {
606     return HWC2_ERROR_BAD_PARAMETER;
607   }
608 
609   HWCSession *hwc_session = static_cast<HWCSession *>(device);
610   if (display >= HWC_NUM_DISPLAY_TYPES || (hwc_session->hwc_display_[display] == nullptr) ) {
611     return HWC2_ERROR_BAD_DISPLAY;
612   }
613 
614   if (display == HWC_DISPLAY_PRIMARY) {
615     *out_support = 1;
616   } else {
617     *out_support = 0;
618   }
619 
620   return HWC2_ERROR_NONE;
621 }
622 
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)623 static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
624                                   uint32_t* out_num_types, int32_t* out_types,
625                                   float* out_max_luminance, float* out_max_average_luminance,
626                                   float* out_min_luminance) {
627   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
628                                          out_num_types, out_types, out_max_luminance,
629                                          out_max_average_luminance, out_min_luminance);
630 }
631 
GetMaxVirtualDisplayCount(hwc2_device_t * device)632 static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
633   if (device == nullptr) {
634     return HWC2_ERROR_BAD_PARAMETER;
635   }
636 
637   return 1;
638 }
639 
GetReleaseFences(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)640 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
641                                 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
642                                 int32_t *out_fences) {
643   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
644                                          out_num_elements, out_layers, out_fences);
645 }
646 
PresentDisplay(hwc2_device_t * device,hwc2_display_t display,int32_t * out_retire_fence)647 int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
648                                    int32_t *out_retire_fence) {
649   HWCSession *hwc_session = static_cast<HWCSession *>(device);
650   bool notify_hotplug = false;
651   auto status = HWC2::Error::BadDisplay;
652   DTRACE_SCOPED();
653 
654   if (display >= HWC_NUM_DISPLAY_TYPES || (hwc_session->hwc_display_[display] == nullptr)) {
655     return HWC2_ERROR_BAD_DISPLAY;
656   }
657 
658   {
659     SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
660     if (!device) {
661       return HWC2_ERROR_BAD_DISPLAY;
662     }
663 
664     if (out_retire_fence == nullptr) {
665       return HWC2_ERROR_BAD_PARAMETER;
666     }
667 
668     // TODO(user): Handle virtual display/HDMI concurrency
669     status = hwc_session->PresentDisplayInternal(display, out_retire_fence);
670   }
671 
672   if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
673     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
674   }
675 
676   // Handle Pending external display connection
677   if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
678     Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
679     Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
680 
681     if (!hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
682       DLOGD("Process pending external display connection");
683       hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
684       hwc_session->external_pending_connect_ = false;
685       notify_hotplug = true;
686     }
687   }
688 
689   if (notify_hotplug) {
690     hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
691   }
692 
693   return INT32(status);
694 }
695 
RegisterCallback(hwc2_device_t * device,int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)696 int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
697                                      hwc2_callback_data_t callback_data,
698                                      hwc2_function_pointer_t pointer) {
699   if (!device) {
700     return HWC2_ERROR_BAD_PARAMETER;
701   }
702   HWCSession *hwc_session = static_cast<HWCSession *>(device);
703   SCOPE_LOCK(hwc_session->callbacks_lock_);
704   auto desc = static_cast<HWC2::Callback>(descriptor);
705   auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
706   DLOGD("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
707   if (descriptor == HWC2_CALLBACK_HOTPLUG) {
708     if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
709       hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
710     }
711   }
712   hwc_session->need_invalidate_ = false;
713   hwc_session->callbacks_lock_.Broadcast();
714   return INT32(error);
715 }
716 
SetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config)717 static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
718                                hwc2_config_t config) {
719   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
720 }
721 
SetClientTarget(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)722 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
723                                buffer_handle_t target, int32_t acquire_fence,
724                                int32_t dataspace, hwc_region_t damage) {
725   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
726                                          acquire_fence, dataspace, damage);
727 }
728 
SetColorMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)729 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
730                                  int32_t /*ColorMode*/ int_mode) {
731   auto mode = static_cast<ColorMode>(int_mode);
732   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
733     return HWC2_ERROR_BAD_PARAMETER;
734   }
735   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
736 }
737 
SetColorModeWithRenderIntent(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode,int32_t int_render_intent)738 int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
739                                                  int32_t /*ColorMode*/ int_mode,
740                                                  int32_t /*RenderIntent*/ int_render_intent) {
741   auto mode = static_cast<ColorMode>(int_mode);
742   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
743     return HWC2_ERROR_BAD_PARAMETER;
744   }
745   auto render_intent = static_cast<RenderIntent>(int_render_intent);
746   if ((render_intent < RenderIntent::COLORIMETRIC) ||
747       (render_intent > RenderIntent::TONE_MAP_ENHANCE)) {
748     DLOGE("Invalid RenderIntent: %d", render_intent);
749     return HWC2_ERROR_BAD_PARAMETER;
750   }
751   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent,
752                                          mode, render_intent);
753 }
754 
SetColorTransform(hwc2_device_t * device,hwc2_display_t display,const float * matrix,int32_t hint)755 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
756                                       const float *matrix,
757                                       int32_t /*android_color_transform_t*/ hint) {
758   if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
759        hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
760     return HWC2_ERROR_BAD_PARAMETER;
761   }
762   android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
763   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
764                                          transform_hint);
765 }
766 
SetCursorPosition(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t x,int32_t y)767 static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
768                                  int32_t x, int32_t y) {
769   auto status = INT32(HWC2::Error::None);
770   status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
771                                            layer, x, y);
772   if (status == INT32(HWC2::Error::None)) {
773     // Update cursor position
774     HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
775   }
776   return status;
777 }
778 
SetLayerBlendMode(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_mode)779 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
780                                  int32_t int_mode) {
781   if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
782     return HWC2_ERROR_BAD_PARAMETER;
783   }
784   auto mode = static_cast<HWC2::BlendMode>(int_mode);
785   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
786 }
787 
SetLayerBuffer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,int32_t acquire_fence)788 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
789                               buffer_handle_t buffer, int32_t acquire_fence) {
790   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
791                                        acquire_fence);
792 }
793 
SetLayerColor(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_color_t color)794 static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
795                              hwc_color_t color) {
796   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
797 }
798 
SetLayerCompositionType(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_type)799 static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
800                                        hwc2_layer_t layer, int32_t int_type) {
801   auto type = static_cast<HWC2::Composition>(int_type);
802   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
803                                        type);
804 }
805 
SetLayerDataspace(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)806 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
807                                  int32_t dataspace) {
808   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
809                                        dataspace);
810 }
811 
SetLayerDisplayFrame(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)812 static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
813                                     hwc2_layer_t layer, hwc_rect_t frame) {
814   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
815                                        frame);
816 }
817 
SetLayerPlaneAlpha(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,float alpha)818 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
819                                   float alpha) {
820   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
821                                        alpha);
822 }
823 
SetLayerSourceCrop(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)824 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
825                                   hwc_frect_t crop) {
826   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
827 }
828 
SetLayerSurfaceDamage(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t damage)829 static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
830                                      hwc2_layer_t layer, hwc_region_t damage) {
831   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
832                                        damage);
833 }
834 
SetLayerTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_transform)835 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
836                                  int32_t int_transform) {
837   auto transform = static_cast<HWC2::Transform>(int_transform);
838   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
839                                        transform);
840 }
841 
SetLayerVisibleRegion(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t visible)842 static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
843                                      hwc2_layer_t layer, hwc_region_t visible) {
844   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
845                                        visible);
846 }
847 
SetLayerZOrder(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t z)848 static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
849                               uint32_t z) {
850   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
851 }
852 
SetLayerColorTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,const float * matrix)853 static int32_t SetLayerColorTransform(hwc2_device_t *device, hwc2_display_t display,
854                                       hwc2_layer_t layer, const float *matrix) {
855   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColorTransform,
856                                        matrix);
857 }
858 
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t releaseFence)859 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
860                                     buffer_handle_t buffer, int32_t releaseFence) {
861   if (!device) {
862     return HWC2_ERROR_BAD_PARAMETER;
863   }
864 
865   if (display != HWC_DISPLAY_VIRTUAL) {
866     return HWC2_ERROR_UNSUPPORTED;
867   }
868 
869   SCOPE_LOCK(locker_[display]);
870   auto *hwc_session = static_cast<HWCSession *>(device);
871   if (hwc_session->hwc_display_[display]) {
872     auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
873     auto status = vds->SetOutputBuffer(buffer, releaseFence);
874     return INT32(status);
875   } else {
876     return HWC2_ERROR_BAD_DISPLAY;
877   }
878 }
879 
SetPowerMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)880 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
881   if (display >= HWC_NUM_DISPLAY_TYPES) {
882     return HWC2_ERROR_BAD_DISPLAY;
883   }
884 
885   //  validate device and also avoid undefined behavior in cast to HWC2::PowerMode
886   if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
887     return HWC2_ERROR_BAD_PARAMETER;
888   }
889 
890   auto mode = static_cast<HWC2::PowerMode>(int_mode);
891 
892   //  all displays support on/off. Check for doze modes
893   int support = 0;
894 
895   auto status = GetDozeSupport(device, display, &support);
896   if (status != HWC2_ERROR_NONE) {
897     return INT32(status);
898   }
899 
900   if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
901     return HWC2_ERROR_UNSUPPORTED;
902   }
903 
904   auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
905   if (error != HWC2_ERROR_NONE) {
906     return error;
907   }
908   // Reset idle pc ref count on suspend, as we enable idle pc during suspend.
909   if (mode == HWC2::PowerMode::Off) {
910     HWCSession *hwc_session = static_cast<HWCSession *>(device);
911     hwc_session->idle_pc_ref_cnt_ = 0;
912   }
913 
914   return HWC2_ERROR_NONE;
915 }
916 
SetVsyncEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t int_enabled)917 static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
918   //  avoid undefined behavior in cast to HWC2::Vsync
919   if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
920     return HWC2_ERROR_BAD_PARAMETER;
921   }
922 
923   auto enabled = static_cast<HWC2::Vsync>(int_enabled);
924   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
925 }
926 
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)927 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
928                                     uint32_t *out_num_types, uint32_t *out_num_requests) {
929   //  out_num_types and out_num_requests will be non-NULL
930   if (!device) {
931     return HWC2_ERROR_BAD_PARAMETER;
932   }
933 
934   if (display >= HWC_NUM_DISPLAY_TYPES) {
935     return HWC2_ERROR_BAD_DISPLAY;
936   }
937 
938   DTRACE_SCOPED();
939   HWCSession *hwc_session = static_cast<HWCSession *>(device);
940   // TODO(user): Handle secure session, handle QDCM solid fill
941   // Handle external_pending_connect_ in CreateVirtualDisplay
942   auto status = HWC2::Error::BadDisplay;
943   {
944     SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
945     if (hwc_session->hwc_display_[display]) {
946       status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests);
947     }
948   }
949 
950   // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
951   if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
952     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
953   }
954 
955   return INT32(status);
956 }
957 
GetDisplayCapabilities(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumCapabilities,uint32_t * outCapabilities)958 int32_t HWCSession::GetDisplayCapabilities(hwc2_device_t* device, hwc2_display_t display,
959         uint32_t* outNumCapabilities, uint32_t* outCapabilities) {
960   if (outNumCapabilities == nullptr) {
961     return INT32(HWC2::Error::None);
962   }
963 
964   bool brightness_support = false;
965   auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
966   if (status != HWC2_ERROR_NONE) {
967     DLOGE("Failed to get display brightness support Error = %d", status);
968     return INT32(status);
969   }
970   int doze_support = 0;
971   status = GetDozeSupport(device, display, &doze_support);
972   if (status != HWC2_ERROR_NONE) {
973     DLOGE("Failed to get doze support Error = %d", status);
974     return INT32(status);
975   }
976 
977   uint32_t count = 1  + static_cast<uint32_t>(doze_support) + (brightness_support ? 1 : 0);
978   int index = 0;
979   if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
980     outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
981     if (doze_support == 1) {
982       outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
983     }
984     if (brightness_support) {
985       outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
986     }
987   }
988 
989   *outNumCapabilities = count;
990   return INT32(HWC2::Error::None);
991 }
992 
SetDisplayBrightness(hwc2_device_t * device,hwc2_display_t display,float brightness)993 int32_t HWCSession::SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display,
994                                          float brightness) {
995   bool brightness_support = false;
996   auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
997   if (status != HWC2_ERROR_NONE) {
998     return INT32(status);
999   }
1000   if (!brightness_support) {
1001     return HWC2_ERROR_UNSUPPORTED;
1002   }
1003   int backlight = -1;
1004   if (brightness == -1.0f) {
1005     backlight = 0;
1006   } else if (brightness < 0.0f || brightness > 1.0f) {
1007     return INT32(HWC2::Error::BadParameter);
1008   } else {
1009     // 0 is reserved for "backlight off", so we scale the brightness from 1 to MAX_BRIGHTNESS.
1010     backlight = (int) ((MAX_BRIGHTNESS - 1.0f) * brightness + 1.0f);
1011   }
1012   char buff[20];
1013   int n = snprintf(buff, sizeof(buff), "%d\n", backlight);
1014   if (n < 0 || n >= sizeof(buff)) {
1015     return INT32(HWC2::Error::BadParameter);
1016   }
1017 
1018   HWCSession *hwc_session = static_cast<HWCSession *>(device);
1019   long error = lseek(hwc_session->brightness_fd_, 0, SEEK_SET);
1020   if (error == -1) {
1021     DLOGW("Failed to rewind brightness file: [%d] %s", errno, strerror(errno));
1022     return INT32(HWC2::Error::NoResources);
1023   }
1024   error = write(hwc_session->brightness_fd_, buff, (size_t) n);
1025   if (error == -1) {
1026     DLOGW("Failed to write to brightness file: [%d] %s", errno, strerror(errno));
1027     return INT32(HWC2::Error::NoResources);
1028   }
1029   error = fsync(hwc_session->brightness_fd_);
1030   if (error == -1) {
1031     DLOGW("Failed to flush brightness file: [%d] %s", errno, strerror(errno));
1032     return INT32(HWC2::Error::NoResources);
1033   }
1034 
1035   return INT32(HWC2::Error::None);
1036 }
1037 
GetFunction(struct hwc2_device * device,int32_t int_descriptor)1038 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
1039                                                 int32_t int_descriptor) {
1040   auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
1041 
1042   switch (descriptor) {
1043     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
1044       return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
1045     case HWC2::FunctionDescriptor::CreateLayer:
1046       return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
1047     case HWC2::FunctionDescriptor::CreateVirtualDisplay:
1048       return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
1049     case HWC2::FunctionDescriptor::DestroyLayer:
1050       return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
1051     case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
1052       return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
1053     case HWC2::FunctionDescriptor::Dump:
1054       return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
1055     case HWC2::FunctionDescriptor::GetActiveConfig:
1056       return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
1057     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
1058       return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
1059     case HWC2::FunctionDescriptor::GetClientTargetSupport:
1060       return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
1061     case HWC2::FunctionDescriptor::GetColorModes:
1062       return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
1063     case HWC2::FunctionDescriptor::GetDisplayAttribute:
1064       return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
1065     case HWC2::FunctionDescriptor::GetDisplayConfigs:
1066       return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
1067     case HWC2::FunctionDescriptor::GetDisplayName:
1068       return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
1069     case HWC2::FunctionDescriptor::GetDisplayRequests:
1070       return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
1071     case HWC2::FunctionDescriptor::GetDisplayType:
1072       return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
1073     case HWC2::FunctionDescriptor::GetHdrCapabilities:
1074       return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
1075     case HWC2::FunctionDescriptor::GetDozeSupport:
1076       return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
1077     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
1078       return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
1079     case HWC2::FunctionDescriptor::GetReleaseFences:
1080       return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
1081     case HWC2::FunctionDescriptor::PresentDisplay:
1082       return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
1083     case HWC2::FunctionDescriptor::RegisterCallback:
1084       return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
1085     case HWC2::FunctionDescriptor::SetActiveConfig:
1086       return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
1087     case HWC2::FunctionDescriptor::SetClientTarget:
1088       return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
1089     case HWC2::FunctionDescriptor::SetColorMode:
1090       return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
1091     case HWC2::FunctionDescriptor::SetColorTransform:
1092       return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
1093     case HWC2::FunctionDescriptor::SetCursorPosition:
1094       return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
1095     case HWC2::FunctionDescriptor::SetLayerBlendMode:
1096       return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
1097     case HWC2::FunctionDescriptor::SetLayerBuffer:
1098       return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
1099     case HWC2::FunctionDescriptor::SetLayerColor:
1100       return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
1101     case HWC2::FunctionDescriptor::SetLayerCompositionType:
1102       return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
1103     case HWC2::FunctionDescriptor::SetLayerDataspace:
1104       return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
1105     case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
1106       return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
1107     case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
1108       return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
1109     // Sideband stream is not supported
1110     // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
1111     case HWC2::FunctionDescriptor::SetLayerSourceCrop:
1112       return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
1113     case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
1114       return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
1115     case HWC2::FunctionDescriptor::SetLayerTransform:
1116       return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
1117     case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
1118       return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
1119     case HWC2::FunctionDescriptor::SetLayerZOrder:
1120       return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
1121     case HWC2::FunctionDescriptor::SetLayerColorTransform:
1122       return AsFP<HWC2_PFN_SET_LAYER_COLOR_TRANSFORM>(SetLayerColorTransform);
1123     case HWC2::FunctionDescriptor::SetOutputBuffer:
1124       return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
1125     case HWC2::FunctionDescriptor::SetPowerMode:
1126       return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
1127     case HWC2::FunctionDescriptor::SetVsyncEnabled:
1128       return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
1129     case HWC2::FunctionDescriptor::ValidateDisplay:
1130       return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
1131     case HWC2::FunctionDescriptor::SetReadbackBuffer:
1132       return AsFP<HWC2_PFN_SET_READBACK_BUFFER>(HWCSession::SetReadbackBuffer);
1133     case HWC2::FunctionDescriptor::GetReadbackBufferAttributes:
1134       return AsFP<HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES>(HWCSession::GetReadbackBufferAttributes);
1135     case HWC2::FunctionDescriptor::GetReadbackBufferFence:
1136       return AsFP<HWC2_PFN_GET_READBACK_BUFFER_FENCE>(HWCSession::GetReadbackBufferFence);
1137     case HWC2::FunctionDescriptor::GetRenderIntents:
1138       return AsFP<HWC2_PFN_GET_RENDER_INTENTS>(GetRenderIntents);
1139     case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
1140       return AsFP<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
1141           HWCSession::SetColorModeWithRenderIntent);
1142     case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
1143       return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
1144     case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
1145       return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
1146     case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
1147       return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
1148     case HWC2::FunctionDescriptor::SetDisplayedContentSamplingEnabled:
1149       return AsFP<HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED>(SetDisplayedContentSamplingEnabled);
1150     case HWC2::FunctionDescriptor::GetDisplayedContentSamplingAttributes:
1151       return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES>(GetDisplayedContentSamplingAttributes);
1152     case HWC2::FunctionDescriptor::GetDisplayedContentSample:
1153       return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE>(GetDisplayedContentSample);
1154     case HWC2::FunctionDescriptor::GetDisplayCapabilities:
1155       return AsFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(GetDisplayCapabilities);
1156     case HWC2::FunctionDescriptor::SetDisplayBrightness:
1157       return AsFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(SetDisplayBrightness);
1158     default:
1159       DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
1160             to_string(descriptor).c_str());
1161       return nullptr;
1162   }
1163   return nullptr;
1164 }
1165 
CreateVirtualDisplayObject(uint32_t width,uint32_t height,int32_t * format)1166 HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
1167                                                    int32_t *format) {
1168   {
1169     SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
1170     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1171       return HWC2::Error::NoResources;
1172     }
1173 
1174     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1175       auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
1176       if (error) {
1177         return HWC2::Error::NoResources;
1178       }
1179     }
1180 
1181     auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
1182                                             height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
1183     // TODO(user): validate width and height support
1184     if (status) {
1185       return HWC2::Error::NoResources;
1186     }
1187   }
1188 
1189   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1190   hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
1191 
1192   return HWC2::Error::None;
1193 }
1194 
ConnectDisplay(int disp)1195 int32_t HWCSession::ConnectDisplay(int disp) {
1196   DLOGI("Display = %d", disp);
1197 
1198   int status = 0;
1199   uint32_t primary_width = 0;
1200   uint32_t primary_height = 0;
1201 
1202   hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
1203 
1204   if (disp == HWC_DISPLAY_EXTERNAL) {
1205     status = CreateExternalDisplay(disp, primary_width, primary_height, false);
1206   } else {
1207     DLOGE("Invalid display type");
1208     return -1;
1209   }
1210 
1211   if (!status) {
1212     hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
1213   }
1214 
1215   return status;
1216 }
1217 
DisconnectDisplay(int disp)1218 int HWCSession::DisconnectDisplay(int disp) {
1219   DLOGI("Display = %d", disp);
1220 
1221   if (disp == HWC_DISPLAY_EXTERNAL) {
1222     DisplayError error = hwc_display_[disp]->Flush();
1223     if (error != kErrorNone) {
1224         DLOGW("Flush failed. Error = %d", error);
1225     }
1226     HWCDisplayExternal::Destroy(hwc_display_[disp]);
1227   } else if (disp == HWC_DISPLAY_VIRTUAL) {
1228     HWCDisplayVirtual::Destroy(hwc_display_[disp]);
1229   } else {
1230     DLOGE("Invalid display type");
1231     return -1;
1232   }
1233 
1234   hwc_display_[disp] = NULL;
1235 
1236   return 0;
1237 }
1238 
1239 // Qclient methods
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)1240 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
1241                                              android::Parcel *output_parcel) {
1242   android::status_t status = -EINVAL;
1243 
1244   switch (command) {
1245     case qService::IQService::DYNAMIC_DEBUG:
1246       if (!input_parcel) {
1247         DLOGE("QService command = %d: input_parcel needed.", command);
1248         break;
1249       }
1250       status = 0;
1251       DynamicDebug(input_parcel);
1252       break;
1253 
1254     case qService::IQService::SCREEN_REFRESH:
1255       status = refreshScreen();
1256       break;
1257 
1258     case qService::IQService::SET_IDLE_TIMEOUT:
1259       if (!input_parcel) {
1260         DLOGE("QService command = %d: input_parcel needed.", command);
1261         break;
1262       }
1263       status = setIdleTimeout(UINT32(input_parcel->readInt32()));
1264       break;
1265 
1266     case qService::IQService::SET_FRAME_DUMP_CONFIG:
1267       if (!input_parcel) {
1268         DLOGE("QService command = %d: input_parcel needed.", command);
1269         break;
1270       }
1271       status = SetFrameDumpConfig(input_parcel);
1272       break;
1273 
1274     case qService::IQService::SET_MAX_PIPES_PER_MIXER:
1275       if (!input_parcel) {
1276         DLOGE("QService command = %d: input_parcel needed.", command);
1277         break;
1278       }
1279       status = SetMaxMixerStages(input_parcel);
1280       break;
1281 
1282     case qService::IQService::SET_DISPLAY_MODE:
1283       if (!input_parcel) {
1284         DLOGE("QService command = %d: input_parcel needed.", command);
1285         break;
1286       }
1287       status = SetDisplayMode(input_parcel);
1288       break;
1289 
1290     case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
1291         if (!input_parcel || !output_parcel) {
1292           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1293           break;
1294         }
1295         int disp_id = INT(input_parcel->readInt32());
1296         HWCDisplay::DisplayStatus disp_status =
1297               static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
1298         status = SetSecondaryDisplayStatus(disp_id, disp_status);
1299         output_parcel->writeInt32(status);
1300       }
1301       break;
1302 
1303     case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
1304       if (!input_parcel) {
1305         DLOGE("QService command = %d: input_parcel needed.", command);
1306         break;
1307       }
1308       status = ConfigureRefreshRate(input_parcel);
1309       break;
1310 
1311     case qService::IQService::SET_VIEW_FRAME:
1312       status = 0;
1313       break;
1314 
1315     case qService::IQService::TOGGLE_SCREEN_UPDATES: {
1316         if (!input_parcel || !output_parcel) {
1317           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1318           break;
1319         }
1320         int32_t input = input_parcel->readInt32();
1321         status = toggleScreenUpdate(input == 1);
1322         output_parcel->writeInt32(status);
1323       }
1324       break;
1325 
1326     case qService::IQService::QDCM_SVC_CMDS:
1327       if (!input_parcel || !output_parcel) {
1328         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1329         break;
1330       }
1331       status = QdcmCMDHandler(input_parcel, output_parcel);
1332       break;
1333 
1334     case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
1335         if (!input_parcel || !output_parcel) {
1336           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1337           break;
1338         }
1339         int disp_id = input_parcel->readInt32();
1340         uint32_t min_enc_level = UINT32(input_parcel->readInt32());
1341         status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
1342         output_parcel->writeInt32(status);
1343       }
1344       break;
1345 
1346     case qService::IQService::CONTROL_PARTIAL_UPDATE: {
1347         if (!input_parcel || !output_parcel) {
1348           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1349           break;
1350         }
1351         int disp_id = input_parcel->readInt32();
1352         uint32_t enable = UINT32(input_parcel->readInt32());
1353         status = ControlPartialUpdate(disp_id, enable == 1);
1354         output_parcel->writeInt32(status);
1355       }
1356       break;
1357 
1358     case qService::IQService::SET_ACTIVE_CONFIG: {
1359         if (!input_parcel) {
1360           DLOGE("QService command = %d: input_parcel needed.", command);
1361           break;
1362         }
1363         uint32_t config = UINT32(input_parcel->readInt32());
1364         int disp_id = input_parcel->readInt32();
1365         status = SetActiveConfigIndex(disp_id, config);
1366       }
1367       break;
1368 
1369     case qService::IQService::GET_ACTIVE_CONFIG: {
1370         if (!input_parcel || !output_parcel) {
1371           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1372           break;
1373         }
1374         int disp_id = input_parcel->readInt32();
1375         uint32_t config = 0;
1376         status = GetActiveConfigIndex(disp_id, &config);
1377         output_parcel->writeInt32(INT(config));
1378       }
1379       break;
1380 
1381     case qService::IQService::GET_CONFIG_COUNT: {
1382         if (!input_parcel || !output_parcel) {
1383           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1384           break;
1385         }
1386         int disp_id = input_parcel->readInt32();
1387         uint32_t count = 0;
1388         status = GetConfigCount(disp_id, &count);
1389         output_parcel->writeInt32(INT(count));
1390       }
1391       break;
1392 
1393     case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
1394       if (!input_parcel || !output_parcel) {
1395         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1396         break;
1397       }
1398       status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
1399       break;
1400 
1401     case qService::IQService::GET_PANEL_BRIGHTNESS: {
1402         if (!output_parcel) {
1403           DLOGE("QService command = %d: output_parcel needed.", command);
1404           break;
1405         }
1406         int level = 0;
1407         status = GetPanelBrightness(&level);
1408         output_parcel->writeInt32(level);
1409       }
1410       break;
1411 
1412     case qService::IQService::SET_PANEL_BRIGHTNESS: {
1413         if (!input_parcel || !output_parcel) {
1414           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1415           break;
1416         }
1417         uint32_t level = UINT32(input_parcel->readInt32());
1418         status = setPanelBrightness(level);
1419         output_parcel->writeInt32(status);
1420       }
1421       break;
1422 
1423     case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
1424       if (!input_parcel || !output_parcel) {
1425         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1426         break;
1427       }
1428       status = GetVisibleDisplayRect(input_parcel, output_parcel);
1429       break;
1430 
1431     case qService::IQService::SET_CAMERA_STATUS: {
1432         if (!input_parcel) {
1433           DLOGE("QService command = %d: input_parcel needed.", command);
1434           break;
1435         }
1436         uint32_t camera_status = UINT32(input_parcel->readInt32());
1437         status = setCameraLaunchStatus(camera_status);
1438       }
1439       break;
1440 
1441     case qService::IQService::GET_BW_TRANSACTION_STATUS: {
1442         if (!output_parcel) {
1443           DLOGE("QService command = %d: output_parcel needed.", command);
1444           break;
1445         }
1446         bool state = true;
1447         status = DisplayBWTransactionPending(&state);
1448         output_parcel->writeInt32(state);
1449       }
1450       break;
1451 
1452     case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
1453       if (!input_parcel) {
1454         DLOGE("QService command = %d: input_parcel needed.", command);
1455         break;
1456       }
1457       status = SetMixerResolution(input_parcel);
1458       break;
1459 
1460     case qService::IQService::SET_COLOR_MODE:
1461       if (!input_parcel) {
1462         DLOGE("QService command = %d: input_parcel needed.", command);
1463         break;
1464       }
1465       status = SetColorModeOverride(input_parcel);
1466       break;
1467 
1468     case qService::IQService::SET_COLOR_MODE_WITH_RENDER_INTENT:
1469       if (!input_parcel) {
1470         DLOGE("QService command = %d: input_parcel needed.", command);
1471         break;
1472       }
1473       status = SetColorModeWithRenderIntentOverride(input_parcel);
1474       break;
1475 
1476     case qService::IQService::SET_COLOR_MODE_BY_ID:
1477       if (!input_parcel) {
1478         DLOGE("QService command = %d: input_parcel needed.", command);
1479         break;
1480       }
1481       status = SetColorModeById(input_parcel);
1482       break;
1483 
1484     case qService::IQService::GET_COMPOSER_STATUS:
1485       if (!output_parcel) {
1486         DLOGE("QService command = %d: output_parcel needed.", command);
1487         break;
1488       }
1489       status = 0;
1490       output_parcel->writeInt32(getComposerStatus());
1491       break;
1492 
1493     case qService::IQService::SET_IDLE_PC:
1494       if (!input_parcel) {
1495         DLOGE("QService command = %d: input_parcel needed.", command);
1496         break;
1497       }
1498       status = SetIdlePC(input_parcel);
1499       break;
1500 
1501     case qService::IQService::SET_COLOR_SAMPLING_ENABLED:
1502       if (!input_parcel) {
1503         DLOGE("QService command = %d: input_parcel needed.", command);
1504         break;
1505       }
1506       status = setColorSamplingEnabled(input_parcel);
1507       break;
1508 
1509     case qService::IQService::SET_WHITE_COMPENSATION:
1510       if (!input_parcel) {
1511         DLOGE("QService command = %d: input_parcel needed.", command);
1512         break;
1513       }
1514       status = SetWhiteCompensation(input_parcel);
1515       break;
1516     default:
1517       DLOGW("QService command = %d is not supported.", command);
1518       break;
1519   }
1520 
1521   return status;
1522 }
1523 
getComposerStatus()1524 android::status_t HWCSession::getComposerStatus() {
1525   return is_composer_up_;
1526 }
1527 
setColorSamplingEnabled(const android::Parcel * input_parcel)1528 android::status_t HWCSession::setColorSamplingEnabled(const android::Parcel* input_parcel)
1529 {
1530     int dpy = input_parcel->readInt32();
1531     int enabled_cmd = input_parcel->readInt32();
1532     if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES ||
1533         enabled_cmd < 0 || enabled_cmd > 1) {
1534         return android::BAD_VALUE;
1535     }
1536 
1537     SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1538     if (!hwc_display_[dpy]) {
1539         DLOGW("No display id %i active to enable histogram event", dpy);
1540         return android::BAD_VALUE;
1541     }
1542 
1543     auto error = hwc_display_[dpy]->SetDisplayedContentSamplingEnabledVndService(enabled_cmd);
1544     return (error == HWC2::Error::None) ? android::OK : android::BAD_VALUE;
1545 }
1546 
HandleGetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)1547 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
1548                                                                   *input_parcel,
1549                                                                   android::Parcel *output_parcel) {
1550   int config = input_parcel->readInt32();
1551   int dpy = input_parcel->readInt32();
1552   int error = android::BAD_VALUE;
1553   DisplayConfigVariableInfo display_attributes;
1554 
1555   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
1556     return android::BAD_VALUE;
1557   }
1558 
1559   SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1560   if (hwc_display_[dpy]) {
1561     error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
1562     if (error == 0) {
1563       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
1564       output_parcel->writeInt32(INT(display_attributes.x_pixels));
1565       output_parcel->writeInt32(INT(display_attributes.y_pixels));
1566       output_parcel->writeFloat(display_attributes.x_dpi);
1567       output_parcel->writeFloat(display_attributes.y_dpi);
1568       output_parcel->writeInt32(0);  // Panel type, unsupported.
1569     }
1570   }
1571 
1572   return error;
1573 }
1574 
ConfigureRefreshRate(const android::Parcel * input_parcel)1575 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
1576   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1577 
1578   uint32_t operation = UINT32(input_parcel->readInt32());
1579   HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
1580 
1581   if (!hwc_display) {
1582     DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1583     return -ENODEV;
1584   }
1585 
1586   switch (operation) {
1587     case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
1588       return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
1589 
1590     case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
1591       return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
1592 
1593     case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
1594       uint32_t refresh_rate = UINT32(input_parcel->readInt32());
1595       return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
1596     }
1597 
1598     default:
1599       DLOGW("Invalid operation %d", operation);
1600       return -EINVAL;
1601   }
1602 
1603   return 0;
1604 }
1605 
SetDisplayMode(const android::Parcel * input_parcel)1606 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
1607   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1608 
1609   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1610     DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1611     return -ENODEV;
1612   }
1613 
1614   uint32_t mode = UINT32(input_parcel->readInt32());
1615   return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
1616 }
1617 
SetMaxMixerStages(const android::Parcel * input_parcel)1618 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
1619   DisplayError error = kErrorNone;
1620   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1621   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
1622   android::status_t status = 0;
1623 
1624   for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
1625     if (bit_mask_display_type[disp_id]) {
1626       SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
1627       if (hwc_display_[disp_id]) {
1628         error = hwc_display_[disp_id]->SetMaxMixerStages(max_mixer_stages);
1629         if (error != kErrorNone) {
1630           status = -EINVAL;
1631           continue;
1632         }
1633       } else {
1634         DLOGW("Display = %d is not connected.", disp_id);
1635         status = (status)? status : -ENODEV;  // Return higher priority error.
1636         continue;
1637       }
1638     }
1639   }
1640 
1641   return status;
1642 }
1643 
SetFrameDumpConfig(const android::Parcel * input_parcel)1644 android::status_t HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
1645   uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
1646   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1647   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
1648   int32_t output_format = HAL_PIXEL_FORMAT_RGB_888;
1649   bool post_processed = true;
1650 
1651   // Read optional user preferences: output_format and post_processed.
1652   if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1653     // HAL Pixel Format for output buffer
1654     output_format = input_parcel->readInt32();
1655   }
1656   if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1657     // Option to dump Layer Mixer output (0) or DSPP output (1)
1658     post_processed = (input_parcel->readInt32() != 0);
1659   }
1660 
1661   android::status_t status = 0;
1662 
1663   for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
1664     if (bit_mask_display_type[disp_id]) {
1665       SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
1666       if (hwc_display_[disp_id]) {
1667         HWC2::Error error;
1668         error = hwc_display_[disp_id]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type,
1669                                                           output_format, post_processed);
1670         if (HWC2::Error::None != error) {
1671           if (HWC2::Error::NoResources == error)
1672             status = -ENOMEM;
1673           else
1674             status = -EINVAL;
1675           continue;
1676         }
1677       } else {
1678         DLOGW("Display = %d is not connected.", disp_id);
1679         status = (status)? status : -ENODEV;  // Return higher priority error.
1680         continue;
1681       }
1682     }
1683   }
1684 
1685   return status;
1686 }
1687 
SetMixerResolution(const android::Parcel * input_parcel)1688 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
1689   DisplayError error = kErrorNone;
1690   uint32_t dpy = UINT32(input_parcel->readInt32());
1691 
1692   if (dpy != HWC_DISPLAY_PRIMARY) {
1693     DLOGW("Resolution change not supported for this display = %d", dpy);
1694     return -EINVAL;
1695   }
1696 
1697   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1698   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1699     DLOGW("Primary display is not initialized");
1700     return -ENODEV;
1701   }
1702 
1703   uint32_t width = UINT32(input_parcel->readInt32());
1704   uint32_t height = UINT32(input_parcel->readInt32());
1705 
1706   error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
1707   if (error != kErrorNone) {
1708     return -EINVAL;
1709   }
1710 
1711   return 0;
1712 }
1713 
SetColorModeOverride(const android::Parcel * input_parcel)1714 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
1715   auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1716   auto mode = static_cast<ColorMode>(input_parcel->readInt32());
1717   auto device = static_cast<hwc2_device_t *>(this);
1718 
1719   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1720     DLOGE("Invalid ColorMode: %d", mode);
1721     return HWC2_ERROR_BAD_PARAMETER;
1722   }
1723 
1724   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
1725   if (err != HWC2_ERROR_NONE)
1726     return -EINVAL;
1727 
1728   return 0;
1729 }
1730 
SetWhiteCompensation(const android::Parcel * input_parcel)1731 android::status_t HWCSession::SetWhiteCompensation(const android::Parcel *input_parcel) {
1732   auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
1733   auto enabled = static_cast<bool>(input_parcel->readInt32());
1734   auto device = static_cast<hwc2_device_t *>(this);
1735 
1736   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetWhiteCompensation, enabled);
1737   if (err != HWC2_ERROR_NONE)
1738     return -EINVAL;
1739 
1740   return 0;
1741 }
1742 
SetColorModeWithRenderIntentOverride(const android::Parcel * input_parcel)1743 android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
1744     const android::Parcel *input_parcel) {
1745   auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
1746   auto mode = static_cast<ColorMode>(input_parcel->readInt32());
1747   auto intent = static_cast<RenderIntent>(input_parcel->readInt32());
1748   auto device = static_cast<hwc2_device_t *>(this);
1749 
1750   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1751     DLOGE("Invalid ColorMode: %d", mode);
1752     return HWC2_ERROR_BAD_PARAMETER;
1753   }
1754 
1755   if (intent < RenderIntent::COLORIMETRIC || intent > RenderIntent::TONE_MAP_ENHANCE) {
1756     DLOGE("Invalid RenderIntent: %d", intent);
1757     return HWC2_ERROR_BAD_PARAMETER;
1758   }
1759 
1760   auto err =
1761       CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
1762   if (err != HWC2_ERROR_NONE)
1763     return -EINVAL;
1764 
1765   return 0;
1766 }
SetColorModeById(const android::Parcel * input_parcel)1767 android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
1768   auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1769   auto mode = input_parcel->readInt32();
1770   auto device = static_cast<hwc2_device_t *>(this);
1771 
1772   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
1773   if (err != HWC2_ERROR_NONE)
1774     return -EINVAL;
1775 
1776   return 0;
1777 }
1778 
DynamicDebug(const android::Parcel * input_parcel)1779 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
1780   int type = input_parcel->readInt32();
1781   bool enable = (input_parcel->readInt32() > 0);
1782   DLOGI("type = %d enable = %d", type, enable);
1783   int verbose_level = input_parcel->readInt32();
1784 
1785   switch (type) {
1786     case qService::IQService::DEBUG_ALL:
1787       HWCDebugHandler::DebugAll(enable, verbose_level);
1788       break;
1789 
1790     case qService::IQService::DEBUG_MDPCOMP:
1791       HWCDebugHandler::DebugStrategy(enable, verbose_level);
1792       HWCDebugHandler::DebugCompManager(enable, verbose_level);
1793       break;
1794 
1795     case qService::IQService::DEBUG_PIPE_LIFECYCLE:
1796       HWCDebugHandler::DebugResources(enable, verbose_level);
1797       break;
1798 
1799     case qService::IQService::DEBUG_DRIVER_CONFIG:
1800       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1801       break;
1802 
1803     case qService::IQService::DEBUG_ROTATOR:
1804       HWCDebugHandler::DebugResources(enable, verbose_level);
1805       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1806       HWCDebugHandler::DebugRotator(enable, verbose_level);
1807       break;
1808 
1809     case qService::IQService::DEBUG_QDCM:
1810       HWCDebugHandler::DebugQdcm(enable, verbose_level);
1811       break;
1812 
1813     case qService::IQService::DEBUG_SCALAR:
1814       HWCDebugHandler::DebugScalar(enable, verbose_level);
1815       break;
1816 
1817     case qService::IQService::DEBUG_CLIENT:
1818       HWCDebugHandler::DebugClient(enable, verbose_level);
1819       break;
1820 
1821     case qService::IQService::DEBUG_DISPLAY:
1822       HWCDebugHandler::DebugDisplay(enable, verbose_level);
1823       break;
1824 
1825     default:
1826       DLOGW("type = %d is not supported", type);
1827   }
1828 }
1829 
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)1830 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
1831                                              android::Parcel *output_parcel) {
1832   int ret = 0;
1833   int32_t *brightness_value = NULL;
1834   uint32_t display_id(0);
1835   PPPendingParams pending_action;
1836   PPDisplayAPIPayload resp_payload, req_payload;
1837 
1838   if (!color_mgr_) {
1839     DLOGW("color_mgr_ not initialized.");
1840     return -ENOENT;
1841   }
1842 
1843   pending_action.action = kNoAction;
1844   pending_action.params = NULL;
1845 
1846   // Read display_id, payload_size and payload from in_parcel.
1847   ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
1848   if (!ret) {
1849     if ((display_id >= HWC_NUM_DISPLAY_TYPES) || !hwc_display_[display_id]) {
1850       DLOGW("Invalid display id or display = %d is not connected.", display_id);
1851       ret = -ENODEV;
1852     }
1853   }
1854 
1855   if (!ret) {
1856     if ((HWC_DISPLAY_PRIMARY == display_id) || (HWC_DISPLAY_EXTERNAL == display_id)) {
1857       ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, &resp_payload,
1858                                                            &pending_action);
1859     } else {
1860       // Virtual, Tertiary etc. not supported.
1861       DLOGW("Operation not supported on display = %d.", display_id);
1862       ret = -EINVAL;
1863     }
1864   }
1865 
1866   if (ret) {
1867     output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
1868     req_payload.DestroyPayload();
1869     resp_payload.DestroyPayload();
1870     return ret;
1871   }
1872 
1873   if (kNoAction != pending_action.action) {
1874     // Restrict pending actions to primary display.
1875     if (HWC_DISPLAY_PRIMARY != display_id) {
1876       DLOGW("Skipping pending action %d on display = %d.", pending_action.action, display_id);
1877       pending_action.action = kNoAction;
1878     }
1879 
1880     int32_t action = pending_action.action;
1881     int count = -1;
1882     while (action > 0) {
1883       count++;
1884       int32_t bit = (action & 1);
1885       action = action >> 1;
1886 
1887       if (!bit)
1888         continue;
1889 
1890       DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
1891       switch (BITMAP(count)) {
1892         case kInvalidating:
1893           Refresh(HWC_DISPLAY_PRIMARY);
1894           break;
1895         case kEnterQDCMMode:
1896           ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1897           break;
1898         case kExitQDCMMode:
1899           ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1900           break;
1901         case kApplySolidFill:
1902           {
1903             SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1904             ret = color_mgr_->SetSolidFill(pending_action.params,
1905                                             true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1906           }
1907           Refresh(HWC_DISPLAY_PRIMARY);
1908           usleep(kSolidFillDelay);
1909           break;
1910         case kDisableSolidFill:
1911           {
1912             SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1913             ret = color_mgr_->SetSolidFill(pending_action.params,
1914                                             false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1915           }
1916           Refresh(HWC_DISPLAY_PRIMARY);
1917           usleep(kSolidFillDelay);
1918           break;
1919         case kSetPanelBrightness:
1920           brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
1921           if (brightness_value == NULL) {
1922             DLOGE("Brightness value is Null");
1923             ret = -EINVAL;
1924           } else {
1925             ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
1926           }
1927           break;
1928         case kEnableFrameCapture:
1929           ret = color_mgr_->SetFrameCapture(pending_action.params, true,
1930                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
1931           Refresh(HWC_DISPLAY_PRIMARY);
1932           break;
1933         case kDisableFrameCapture:
1934           ret = color_mgr_->SetFrameCapture(pending_action.params, false,
1935                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
1936           break;
1937         case kConfigureDetailedEnhancer:
1938           ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
1939                                             hwc_display_[HWC_DISPLAY_PRIMARY]);
1940           Refresh(HWC_DISPLAY_PRIMARY);
1941           break;
1942         case kModeSet:
1943           ret = static_cast<int>
1944                  (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
1945           Refresh(HWC_DISPLAY_PRIMARY);
1946           break;
1947         case kNoAction:
1948           break;
1949         default:
1950           DLOGW("Invalid pending action = %d!", pending_action.action);
1951           break;
1952       }
1953     }
1954   }
1955   // for display API getter case, marshall returned params into out_parcel.
1956   output_parcel->writeInt32(ret);
1957   HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
1958   req_payload.DestroyPayload();
1959   resp_payload.DestroyPayload();
1960   hwc_display_[display_id]->ResetValidation();
1961 
1962   return ret;
1963 }
1964 
UEventHandler(const char * uevent_data,int length)1965 void HWCSession::UEventHandler(const char *uevent_data, int length) {
1966   if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
1967     DLOGI("Uevent HDMI = %s", uevent_data);
1968     int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
1969     if (connected >= 0) {
1970       DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
1971       if (HotPlugHandler(connected) == -1) {
1972         DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
1973       }
1974     }
1975   } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
1976     DLOGI("Uevent FB0 = %s", uevent_data);
1977     int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
1978     if (panel_reset == 0) {
1979       Refresh(0);
1980       reset_panel_ = true;
1981     }
1982   } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
1983     HandleExtHPD(uevent_data, length);
1984   }
1985 }
1986 
GetTokenValue(const char * uevent_data,int length,const char * token)1987 const char *GetTokenValue(const char *uevent_data, int length, const char *token) {
1988   const char *iterator_str = uevent_data;
1989   const char *pstr = NULL;
1990   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
1991     pstr = strstr(iterator_str, token);
1992     if (pstr) {
1993       break;
1994     }
1995     iterator_str += strlen(iterator_str) + 1;
1996   }
1997 
1998   if (pstr)
1999     pstr = pstr+strlen(token);
2000 
2001   return pstr;
2002 }
2003 
HandleExtHPD(const char * uevent_data,int length)2004 void HWCSession::HandleExtHPD(const char *uevent_data, int length) {
2005   const char *pstr = GetTokenValue(uevent_data, length, "name=");
2006   if (!pstr || (strncmp(pstr, "DP-1", strlen("DP-1")) != 0)) {
2007     return;
2008   }
2009 
2010   pstr = GetTokenValue(uevent_data, length, "status=");
2011   if (pstr) {
2012     bool connected = false;
2013     hpd_bpp_ = 0;
2014     hpd_pattern_ = 0;
2015     if (strncmp(pstr, "connected", strlen("connected")) == 0) {
2016       connected = true;
2017     }
2018     int bpp = GetEventValue(uevent_data, length, "bpp=");
2019     int pattern = GetEventValue(uevent_data, length, "pattern=");
2020     if (bpp >=0 && pattern >= 0) {
2021       hpd_bpp_ = bpp;
2022       hpd_pattern_ = pattern;
2023     }
2024 
2025     DLOGI("Recived Ext HPD, connected:%d  status=%s  bpp = %d pattern =%d ",
2026           connected, pstr, hpd_bpp_, hpd_pattern_);
2027     HotPlugHandler(connected);
2028   }
2029 }
2030 
GetEventValue(const char * uevent_data,int length,const char * event_info)2031 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
2032   const char *iterator_str = uevent_data;
2033   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2034     const char *pstr = strstr(iterator_str, event_info);
2035     if (pstr != NULL) {
2036       return (atoi(iterator_str + strlen(event_info)));
2037     }
2038     iterator_str += strlen(iterator_str) + 1;
2039   }
2040 
2041   return -1;
2042 }
2043 
ResetPanel()2044 void HWCSession::ResetPanel() {
2045   HWC2::Error status;
2046 
2047   DLOGI("Powering off primary");
2048   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
2049   if (status != HWC2::Error::None) {
2050     DLOGE("power-off on primary failed with error = %d", status);
2051   }
2052 
2053   DLOGI("Restoring power mode on primary");
2054   HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
2055   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
2056   if (status != HWC2::Error::None) {
2057     DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
2058   }
2059 
2060   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
2061   if (status != HWC2::Error::None) {
2062     DLOGE("enabling vsync failed for primary with error = %d", status);
2063   }
2064 
2065   reset_panel_ = false;
2066 }
2067 
HotPlugHandler(bool connected)2068 int HWCSession::HotPlugHandler(bool connected) {
2069   int status = 0;
2070   bool notify_hotplug = false;
2071 
2072   // To prevent sending events to client while a lock is held, acquire scope locks only within
2073   // below scope so that those get automatically unlocked after the scope ends.
2074   do {
2075     // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
2076     //    if it is already created, but got disconnected/connected again,
2077     //    just toggle display status and do not notify surfaceflinger.
2078     // If HDMI is not primary, create/destroy external display normally.
2079     if (hdmi_is_primary_) {
2080       SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2081       if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2082         status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
2083       } else {
2084         status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
2085         notify_hotplug = true;
2086       }
2087 
2088       break;
2089     }
2090 
2091     {
2092       SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2093       // Primary display must be connected for HDMI as secondary cases.
2094       if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2095         DLOGE("Primary display is not connected.");
2096         return -1;
2097       }
2098 
2099       hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
2100     }
2101 
2102     if (connected) {
2103       SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2104       Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
2105       // Connect external display if virtual display is not connected.
2106       // Else, defer external display connection and process it when virtual display
2107       // tears down; Do not notify SurfaceFlinger since connection is deferred now.
2108       if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
2109         status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
2110         if (status) {
2111           return status;
2112         }
2113         notify_hotplug = true;
2114       } else {
2115         DLOGI("Virtual display is connected, pending connection");
2116         external_pending_connect_ = true;
2117       }
2118     } else {
2119       SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2120       if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
2121         notify_hotplug = true;
2122       }
2123       external_pending_connect_ = false;
2124     }
2125   } while (0);
2126 
2127   if (connected) {
2128     // In connect case, we send hotplug after we create display
2129     Refresh(0);
2130 
2131     if (!hdmi_is_primary_) {
2132       // wait for sufficient time to ensure sufficient resources are available to process new
2133       // new display connection.
2134       uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
2135       usleep(vsync_period * 2 / 1000);
2136     }
2137     if (notify_hotplug) {
2138       HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
2139               HWC2::Connection::Connected);
2140     }
2141   } else {
2142     // In disconnect case, we notify hotplug first to let the listener state update happen first
2143     // Then we can destroy the underlying display object
2144     if (notify_hotplug) {
2145       HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
2146               HWC2::Connection::Disconnected);
2147     }
2148     Refresh(0);
2149     if (!hdmi_is_primary_) {
2150       uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
2151       usleep(vsync_period * 2 / 1000);
2152     }
2153     // Now disconnect the display
2154     {
2155       SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2156       // Do not return error if external display is not in connected status.
2157       // Due to virtual display concurrency, external display connection might be still pending
2158       // but hdmi got disconnected before pending connection could be processed.
2159       if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
2160         status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
2161       }
2162     }
2163   }
2164 
2165   // notify client
2166 
2167   qservice_->onHdmiHotplug(INT(connected));
2168 
2169   return 0;
2170 }
2171 
GetVsyncPeriod(int disp)2172 int HWCSession::GetVsyncPeriod(int disp) {
2173   SCOPE_LOCK(locker_[disp]);
2174   // default value
2175   int32_t vsync_period = 1000000000l / 60;
2176   auto attribute = HWC2::Attribute::VsyncPeriod;
2177 
2178   if (hwc_display_[disp]) {
2179     hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
2180   }
2181 
2182   return vsync_period;
2183 }
2184 
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)2185 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
2186                                                     android::Parcel *output_parcel) {
2187   int dpy = input_parcel->readInt32();
2188   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
2189     return android::BAD_VALUE;
2190   }
2191 
2192   SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
2193   if (!hwc_display_[dpy]) {
2194     return android::NO_INIT;
2195   }
2196 
2197   hwc_rect_t visible_rect = {0, 0, 0, 0};
2198   int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
2199   if (error < 0) {
2200     return error;
2201   }
2202 
2203   output_parcel->writeInt32(visible_rect.left);
2204   output_parcel->writeInt32(visible_rect.top);
2205   output_parcel->writeInt32(visible_rect.right);
2206   output_parcel->writeInt32(visible_rect.bottom);
2207 
2208   return android::NO_ERROR;
2209 }
2210 
Refresh(hwc2_display_t display)2211 void HWCSession::Refresh(hwc2_display_t display) {
2212   SCOPE_LOCK(callbacks_lock_);
2213   HWC2::Error err = callbacks_.Refresh(display);
2214   while (err != HWC2::Error::None) {
2215     callbacks_lock_.Wait();
2216     err = callbacks_.Refresh(display);
2217   }
2218 }
2219 
HotPlug(hwc2_display_t display,HWC2::Connection state)2220 void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
2221   SCOPE_LOCK(callbacks_lock_);
2222   HWC2::Error err = callbacks_.Hotplug(display, state);
2223   while (err != HWC2::Error::None) {
2224     callbacks_lock_.Wait();
2225     err = callbacks_.Hotplug(display, state);
2226   }
2227 }
2228 
CreateExternalDisplay(int disp_id,uint32_t primary_width,uint32_t primary_height,bool use_primary_res)2229 int HWCSession::CreateExternalDisplay(int disp_id, uint32_t primary_width,
2230                                       uint32_t primary_height, bool use_primary_res) {
2231   uint32_t panel_bpp = 0;
2232   uint32_t pattern_type = 0;
2233 
2234   if (GetDriverType() == DriverType::FB) {
2235     qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
2236   } else {
2237     panel_bpp = static_cast<uint32_t>(hpd_bpp_);
2238     pattern_type = static_cast<uint32_t>(hpd_pattern_);
2239   }
2240 
2241   if (panel_bpp && pattern_type) {
2242     return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
2243                                           qservice_, panel_bpp, pattern_type,
2244                                           &hwc_display_[disp_id]);
2245   }
2246 
2247   return  HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
2248                                      primary_width, primary_height, qservice_,
2249                                      use_primary_res, &hwc_display_[disp_id]);
2250 }
2251 
ValidateDisplayInternal(hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)2252 HWC2::Error HWCSession::ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
2253                                                 uint32_t *out_num_requests) {
2254   HWCDisplay *hwc_display = hwc_display_[display];
2255   if (hwc_display->IsInternalValidateState()) {
2256     // Internal Validation has already been done on display, get the Output params.
2257     return hwc_display->GetValidateDisplayOutput(out_num_types, out_num_requests);
2258   }
2259 
2260   if (display == HWC_DISPLAY_PRIMARY) {
2261     // TODO(user): This can be moved to HWCDisplayPrimary
2262     if (reset_panel_) {
2263       DLOGW("panel is in bad state, resetting the panel");
2264       ResetPanel();
2265     }
2266 
2267     if (need_invalidate_) {
2268       Refresh(display);
2269       need_invalidate_ = false;
2270     }
2271 
2272     if (color_mgr_) {
2273       color_mgr_->SetColorModeDetailEnhancer(hwc_display_[display]);
2274     }
2275   }
2276 
2277   return hwc_display->Validate(out_num_types, out_num_requests);
2278 }
2279 
PresentDisplayInternal(hwc2_display_t display,int32_t * out_retire_fence)2280 HWC2::Error HWCSession::PresentDisplayInternal(hwc2_display_t display, int32_t *out_retire_fence) {
2281   HWCDisplay *hwc_display = hwc_display_[display];
2282   // If display is in Skip-Validate state and Validate cannot be skipped, do Internal
2283   // Validation to optimize for the frames which don't require the Client composition.
2284   if (hwc_display->IsSkipValidateState() && !hwc_display->CanSkipValidate()) {
2285     uint32_t out_num_types = 0, out_num_requests = 0;
2286     HWC2::Error error = ValidateDisplayInternal(display, &out_num_types, &out_num_requests);
2287     if ((error != HWC2::Error::None) || hwc_display->HasClientComposition()) {
2288       hwc_display->SetValidationState(HWCDisplay::kInternalValidate);
2289       return HWC2::Error::NotValidated;
2290     }
2291   }
2292 
2293   return hwc_display->Present(out_retire_fence);
2294 }
2295 
GetReadbackBufferAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace)2296 int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
2297                                                 int32_t *format, int32_t *dataspace) {
2298   if (!device || !format || !dataspace) {
2299     return HWC2_ERROR_BAD_PARAMETER;
2300   }
2301 
2302   if (display != HWC_DISPLAY_PRIMARY) {
2303     return HWC2_ERROR_BAD_DISPLAY;
2304   }
2305 
2306   HWCSession *hwc_session = static_cast<HWCSession *>(device);
2307   HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
2308 
2309   if (hwc_display) {
2310     *format = HAL_PIXEL_FORMAT_RGB_888;
2311     *dataspace = GetDataspace(hwc_display->GetCurrentColorMode());
2312     return HWC2_ERROR_NONE;
2313   }
2314 
2315   return HWC2_ERROR_BAD_DISPLAY;
2316 }
2317 
SetReadbackBuffer(hwc2_device_t * device,hwc2_display_t display,const native_handle_t * buffer,int32_t acquire_fence)2318 int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display,
2319                                       const native_handle_t *buffer, int32_t acquire_fence) {
2320   if (!buffer) {
2321     return HWC2_ERROR_BAD_PARAMETER;
2322   }
2323 
2324   if (display != HWC_DISPLAY_PRIMARY) {
2325     return HWC2_ERROR_BAD_DISPLAY;
2326   }
2327 
2328   HWCSession *hwc_session = static_cast<HWCSession *>(device);
2329   if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
2330       hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
2331     return HWC2_ERROR_UNSUPPORTED;
2332   }
2333 
2334   return CallDisplayFunction(device, display, &HWCDisplay::SetReadbackBuffer,
2335                              buffer, acquire_fence, false);
2336 }
2337 
GetReadbackBufferFence(hwc2_device_t * device,hwc2_display_t display,int32_t * release_fence)2338 int32_t HWCSession::GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
2339                                            int32_t *release_fence) {
2340   if (!release_fence) {
2341     return HWC2_ERROR_BAD_PARAMETER;
2342   }
2343 
2344   if (display != HWC_DISPLAY_PRIMARY) {
2345     return HWC2_ERROR_BAD_DISPLAY;
2346   }
2347 
2348   return CallDisplayFunction(device, display, &HWCDisplay::GetReadbackBufferFence, release_fence);
2349 }
2350 
SetIdlePC(const android::Parcel * input_parcel)2351 android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) {
2352   auto enable = input_parcel->readInt32();
2353   auto synchronous = input_parcel->readInt32();
2354 
2355 #ifdef DISPLAY_CONFIG_1_3
2356   return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous));
2357 #else
2358   {
2359     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2360     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2361       DLOGE("Primary display is not ready");
2362       return -EINVAL;
2363     }
2364     auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
2365     if (error != HWC2::Error::None) {
2366       return -EINVAL;
2367     }
2368     if (!enable) {
2369       Refresh(HWC_DISPLAY_PRIMARY);
2370       int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
2371       if (error == ETIMEDOUT) {
2372         DLOGE("Timed out!! Next frame commit done event not received!!");
2373         return error;
2374       }
2375     }
2376     DLOGI("Idle PC %s!!", enable ? "enabled" : "disabled");
2377   }
2378   return 0;
2379 #endif
2380 }
2381 
2382 }  // namespace sdm
2383