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