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