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