• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2014-2021, 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 /*
21  * Changes from Qualcomm Innovation Center are provided under the following license:
22  *
23  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted (subject to the limitations in the
27  * disclaimer below) provided that the following conditions are met:
28  *
29  *    * Redistributions of source code must retain the above copyright
30  *      notice, this list of conditions and the following disclaimer.
31  *
32  *    * Redistributions in binary form must reproduce the above
33  *      copyright notice, this list of conditions and the following
34  *      disclaimer in the documentation and/or other materials provided
35  *      with the distribution.
36  *
37  *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
38  *      contributors may be used to endorse or promote products derived
39  *      from this software without specific prior written permission.
40  *
41  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
42  * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
43  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
44  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
45  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
47  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
49  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
51  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
52  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
53  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54  */
55 
56 #include <QService.h>
57 #include <binder/Parcel.h>
58 #include <core/buffer_allocator.h>
59 #include <cutils/properties.h>
60 #include <display_config.h>
61 #include <hardware_legacy/uevent.h>
62 #include <private/color_params.h>
63 #include <qd_utils.h>
64 #include <sync/sync.h>
65 #include <sys/prctl.h>
66 #include <sys/resource.h>
67 #include <utils/String16.h>
68 #include <utils/constants.h>
69 #include <utils/debug.h>
70 #include <QService.h>
71 #include <utils/utils.h>
72 #include <algorithm>
73 #include <utility>
74 #include <bitset>
75 #include <iterator>
76 #include <memory>
77 #include <string>
78 #include <thread>
79 #include <vector>
80 #include <cutils/sockets.h>
81 
82 #include "hwc_buffer_allocator.h"
83 #include "hwc_session.h"
84 #include "hwc_debugger.h"
85 
86 #define __CLASS__ "HWCSession"
87 
88 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
89 #define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
90 
91 using HwcAttribute = composer_V2_4::IComposerClient::Attribute;
92 extern void DisplayInit(sdm::HWCSession *hwc_session);
93 
94 namespace sdm {
95 
96 static HWCUEvent g_hwc_uevent_;
97 Locker HWCSession::locker_[HWCCallbacks::kNumDisplays];
98 bool HWCSession::pending_power_mode_[HWCCallbacks::kNumDisplays];
99 Locker HWCSession::power_state_[HWCCallbacks::kNumDisplays];
100 Locker HWCSession::hdr_locker_[HWCCallbacks::kNumDisplays];
101 Locker HWCSession::display_config_locker_;
102 Locker HWCSession::system_locker_;
103 static const int kSolidFillDelay = 100 * 1000;
104 int HWCSession::null_display_mode_ = 0;
105 static const uint32_t kBrightnessScaleMax = 100;
106 static const uint32_t kSvBlScaleMax = 65535;
107 
108 // Map the known color modes to dataspace.
GetDataspaceFromColorMode(ColorMode mode)109 int32_t GetDataspaceFromColorMode(ColorMode mode) {
110   switch (mode) {
111     case ColorMode::SRGB:
112     case ColorMode::NATIVE:
113       return HAL_DATASPACE_V0_SRGB;
114     case ColorMode::DCI_P3:
115       return HAL_DATASPACE_DCI_P3;
116     case ColorMode::DISPLAY_P3:
117       return HAL_DATASPACE_DISPLAY_P3;
118     case ColorMode::BT2100_PQ:
119       return HAL_DATASPACE_BT2020_PQ;
120     case ColorMode::BT2100_HLG:
121       return HAL_DATASPACE_BT2020_HLG;
122     case ColorMode::DISPLAY_BT2020:
123       return HAL_DATASPACE_DISPLAY_BT2020;
124     default:
125       return HAL_DATASPACE_UNKNOWN;
126   }
127 }
128 
UEventThread(HWCUEvent * hwc_uevent)129 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
130   const char *uevent_thread_name = "HWC_UeventThread";
131 
132   prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
133   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
134 
135   int status = uevent_init();
136   if (!status) {
137     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
138     hwc_uevent->caller_cv_.notify_one();
139     ALOGE("Failed to init uevent with err %d", status);
140     return;
141   }
142 
143   {
144     // Signal caller thread that worker thread is ready to listen to events.
145     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
146     hwc_uevent->init_done_ = true;
147     hwc_uevent->caller_cv_.notify_one();
148   }
149 
150   while (1) {
151     char uevent_data[PAGE_SIZE] = {};
152 
153     // keep last 2 zeros to ensure double 0 termination
154     int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
155 
156     // scope of lock to this block only, so that caller is free to set event handler to nullptr;
157     {
158       std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
159       if (hwc_uevent->uevent_listener_) {
160         hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
161       } else {
162         DLOGW("UEvent dropped. No uevent listener.");
163       }
164     }
165   }
166 }
167 
HWCUEvent()168 HWCUEvent::HWCUEvent() {
169   std::unique_lock<std::mutex> caller_lock(mutex_);
170   std::thread thread(HWCUEvent::UEventThread, this);
171   thread.detach();
172   caller_cv_.wait(caller_lock);
173 }
174 
Register(HWCUEventListener * uevent_listener)175 void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
176   DLOGI("Set uevent listener = %p", uevent_listener);
177 
178   std::lock_guard<std::mutex> obj(mutex_);
179   uevent_listener_ = uevent_listener;
180 }
181 
HWCSession()182 HWCSession::HWCSession() : cwb_(this) {}
183 
GetInstance()184 HWCSession *HWCSession::GetInstance() {
185   // executed only once for the very first call.
186   // GetInstance called multiple times from Composer and ComposerClient
187   static HWCSession *hwc_session = new HWCSession();
188   return hwc_session;
189 }
190 
Init()191 int HWCSession::Init() {
192   SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
193 
194   int status = -EINVAL;
195   const char *qservice_name = "display.qservice";
196 
197   if (!g_hwc_uevent_.InitDone()) {
198     return status;
199   }
200 
201 
202   // Start QService and connect to it.
203   qService::QService::init();
204   android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
205       android::defaultServiceManager()->getService(android::String16(qservice_name)));
206 
207   if (iqservice.get()) {
208     iqservice->connect(android::sp<qClient::IQClient>(this));
209     qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
210   } else {
211     DLOGE("Failed to acquire %s", qservice_name);
212     return -EINVAL;
213   }
214 
215   DisplayInit(this);
216 
217   HWCDebugHandler::Get()->GetProperty(ENABLE_NULL_DISPLAY_PROP, &null_display_mode_);
218   HWCDebugHandler::Get()->GetProperty(DISABLE_HOTPLUG_BWCHECK, &disable_hotplug_bwcheck_);
219   HWCDebugHandler::Get()->GetProperty(DISABLE_MASK_LAYER_HINT, &disable_mask_layer_hint_);
220   HWCDebugHandler::Get()->GetProperty(LBE_SUPPORTED, &is_lbe_supported_);
221 
222   if (!null_display_mode_) {
223     g_hwc_uevent_.Register(this);
224   }
225 
226   int value = 0;  // Default value when property is not present.
227   Debug::Get()->GetProperty(ENABLE_ASYNC_POWERMODE, &value);
228   async_powermode_ = (value == 1);
229   DLOGI("builtin_powermode_override: %d", async_powermode_);
230 
231   value = 0;
232   Debug::Get()->GetProperty(ENABLE_ASYNC_VDS_CREATION, &value);
233   async_vds_creation_ = (value == 1);
234   DLOGI("async_vds_creation: %d", async_vds_creation_);
235 
236   InitSupportedDisplaySlots();
237   // Create primary display here. Remaining builtin displays will be created after client has set
238   // display indexes which may happen sometime before callback is registered.
239   status = CreatePrimaryDisplay();
240   if (status) {
241     Deinit();
242     return status;
243   }
244 
245   is_composer_up_ = true;
246   StartServices();
247 
248   PostInit();
249 
250   return 0;
251 }
252 
PostInit()253 void HWCSession::PostInit() {
254   if (null_display_mode_) {
255     return;
256   }
257 
258   // Start services which need IDisplayConfig to be up.
259   // This avoids deadlock between composer and its clients.
260   auto hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
261   hwc_display->PostInit();
262 }
263 
Deinit()264 int HWCSession::Deinit() {
265   if (pps_socket_ >= 0)
266     close(pps_socket_);
267 
268   // Destroy all connected displays
269   DestroyDisplay(&map_info_primary_);
270 
271   for (auto &map_info : map_info_builtin_) {
272     DestroyDisplay(&map_info);
273   }
274 
275   for (auto &map_info : map_info_pluggable_) {
276     DestroyDisplay(&map_info);
277   }
278 
279   for (auto &map_info : map_info_virtual_) {
280     DestroyDisplay(&map_info);
281   }
282 
283   if (color_mgr_) {
284     color_mgr_->DestroyColorManager();
285   }
286 
287   if (!null_display_mode_) {
288     g_hwc_uevent_.Register(nullptr);
289 
290     DisplayError error = CoreInterface::DestroyCore();
291     if (error != kErrorNone) {
292       DLOGE("Display core de-initialization failed. Error = %d", error);
293     }
294   }
295 
296   return 0;
297 }
298 
InitSupportedDisplaySlots()299 void HWCSession::InitSupportedDisplaySlots() {
300   // Default slots:
301   //    Primary = 0, External = 1
302   //    Additional external displays 2,3,...max_pluggable_count.
303   //    Additional builtin displays max_pluggable_count + 1, max_pluggable_count + 2,...
304   //    Last slots for virtual displays.
305   // Virtual display id is only for SF <--> HWC communication.
306   // It need not align with hwccomposer_defs
307 
308   map_info_primary_.client_id = qdutils::DISPLAY_PRIMARY;
309 
310   if (null_display_mode_) {
311     InitSupportedNullDisplaySlots();
312     return;
313   }
314 
315   DisplayError error = CoreInterface::CreateCore(&buffer_allocator_, nullptr,
316                                                  &socket_handler_, &core_intf_);
317   if (error != kErrorNone) {
318     DLOGE("Failed to create CoreInterface");
319     return;
320   }
321 
322   HWDisplayInterfaceInfo hw_disp_info = {};
323   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
324   if (error != kErrorNone) {
325     CoreInterface::DestroyCore();
326     DLOGE("Primary display type not recognized. Error = %d", error);
327     return;
328   }
329 
330   int max_builtin = 0;
331   int max_pluggable = 0;
332   int max_virtual = 0;
333 
334   error = core_intf_->GetMaxDisplaysSupported(kBuiltIn, &max_builtin);
335   if (error != kErrorNone) {
336     CoreInterface::DestroyCore();
337     DLOGE("Could not find maximum built-in displays supported. Error = %d", error);
338     return;
339   }
340 
341   error = core_intf_->GetMaxDisplaysSupported(kPluggable, &max_pluggable);
342   if (error != kErrorNone) {
343     CoreInterface::DestroyCore();
344     DLOGE("Could not find maximum pluggable displays supported. Error = %d", error);
345     return;
346   }
347 
348   error = core_intf_->GetMaxDisplaysSupported(kVirtual, &max_virtual);
349   if (error != kErrorNone) {
350     CoreInterface::DestroyCore();
351     DLOGE("Could not find maximum virtual displays supported. Error = %d", error);
352     return;
353   }
354 
355   if (max_virtual == 0) {
356     // Check if WB using GPU is supported.
357     max_virtual += virtual_display_factory_.IsGPUColorConvertSupported() ? 1 : 0;
358   }
359 
360   if (kPluggable == hw_disp_info.type) {
361     // If primary is a pluggable display, we have already used one pluggable display interface.
362     max_pluggable--;
363   } else {
364     max_builtin--;
365   }
366 
367   // Init slots in accordance to h/w capability.
368   uint32_t disp_count = UINT32(std::min(max_pluggable, HWCCallbacks::kNumPluggable));
369   hwc2_display_t base_id = qdutils::DISPLAY_EXTERNAL;
370   map_info_pluggable_.resize(disp_count);
371   for (auto &map_info : map_info_pluggable_) {
372     map_info.client_id = base_id++;
373   }
374 
375   disp_count = UINT32(std::min(max_builtin, HWCCallbacks::kNumBuiltIn));
376   map_info_builtin_.resize(disp_count);
377   for (auto &map_info : map_info_builtin_) {
378     map_info.client_id = base_id++;
379   }
380 
381   disp_count = UINT32(std::min(max_virtual, HWCCallbacks::kNumVirtual));
382   map_info_virtual_.resize(disp_count);
383   for (auto &map_info : map_info_virtual_) {
384     map_info.client_id = base_id++;
385   }
386 
387   // resize HDR supported map to total number of displays.
388   is_hdr_display_.resize(UINT32(base_id));
389 
390   if (!async_powermode_) {
391     return;
392   }
393 
394   int start_index = HWCCallbacks::kNumRealDisplays;
395   std::vector<DisplayMapInfo> map_info = {map_info_primary_};
396   std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
397   std::copy(map_info_pluggable_.begin(), map_info_pluggable_.end(), std::back_inserter(map_info));
398   for (auto &map : map_info) {
399     DLOGI("Display Pairs: map.client_id: %d, start_index: %d", INT32(map.client_id),
400           INT32(start_index));
401     map_hwc_display_.insert(std::make_pair(map.client_id, start_index++));
402   }
403 }
404 
InitSupportedNullDisplaySlots()405 void HWCSession::InitSupportedNullDisplaySlots() {
406   if (!null_display_mode_) {
407     DLOGE("Should only be invoked during null display");
408     return;
409   }
410 
411   map_info_primary_.client_id = 0;
412   // Resize HDR supported map to total number of displays
413   is_hdr_display_.resize(1);
414 
415   if (!async_powermode_) {
416     return;
417   }
418 
419   DLOGI("Display Pairs: map.client_id: %d, start_index: %d", INT32(map_info_primary_.client_id),
420                                                              HWCCallbacks::kNumRealDisplays);
421   map_hwc_display_.insert(std::make_pair(map_info_primary_.client_id,
422                                          HWCCallbacks::kNumRealDisplays));
423 }
424 
GetDisplayIndex(int dpy)425 int HWCSession::GetDisplayIndex(int dpy) {
426   DisplayMapInfo *map_info = nullptr;
427   switch (dpy) {
428     case qdutils::DISPLAY_PRIMARY:
429       map_info = &map_info_primary_;
430       break;
431     case qdutils::DISPLAY_EXTERNAL:
432       map_info = map_info_pluggable_.size() ? &map_info_pluggable_[0] : nullptr;
433       break;
434     case qdutils::DISPLAY_EXTERNAL_2:
435       map_info = (map_info_pluggable_.size() > 1) ? &map_info_pluggable_[1] : nullptr;
436       break;
437     case qdutils::DISPLAY_VIRTUAL:
438       map_info = map_info_virtual_.size() ? &map_info_virtual_[0] : nullptr;
439       break;
440     case qdutils::DISPLAY_BUILTIN_2:
441       map_info = map_info_builtin_.size() ? &map_info_builtin_[0] : nullptr;
442       break;
443     default:
444       DLOGW("Unknown display %d.", dpy);
445       break;
446   }
447 
448   if (!map_info) {
449     DLOGE("Display index not found for display %d.", dpy);
450     return -1;
451   }
452 
453   return INT(map_info->client_id);
454 }
455 
GetCapabilities(uint32_t * outCount,int32_t * outCapabilities)456 void HWCSession::GetCapabilities(uint32_t *outCount, int32_t *outCapabilities) {
457   if (!outCount) {
458     return;
459   }
460 
461   int value = 0;
462   bool disable_skip_validate = false;
463   if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
464     disable_skip_validate = (value == 1);
465   }
466   uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
467 
468   if (outCapabilities != nullptr && (*outCount >= count)) {
469     outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
470     if (!disable_skip_validate) {
471       outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
472     }
473   }
474   *outCount = count;
475 }
476 
477 template <typename PFN, typename T>
AsFP(T function)478 static hwc2_function_pointer_t AsFP(T function) {
479   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
480   return reinterpret_cast<hwc2_function_pointer_t>(function);
481 }
482 
483 // HWC2 functions returned in GetFunction
484 // Defined in the same order as in the HWC2 header
485 
AcceptDisplayChanges(hwc2_display_t display)486 int32_t HWCSession::AcceptDisplayChanges(hwc2_display_t display) {
487   return CallDisplayFunction(display, &HWCDisplay::AcceptDisplayChanges);
488 }
489 
CreateLayer(hwc2_display_t display,hwc2_layer_t * out_layer_id)490 int32_t HWCSession::CreateLayer(hwc2_display_t display,
491                                 hwc2_layer_t *out_layer_id) {
492   if (!out_layer_id) {
493     return  HWC2_ERROR_BAD_PARAMETER;
494   }
495 
496   return CallDisplayFunction(display, &HWCDisplay::CreateLayer, out_layer_id);
497 }
498 
CreateVirtualDisplay(uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)499 int32_t HWCSession::CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format,
500                                          hwc2_display_t *out_display_id) {
501   // TODO(user): Handle concurrency with HDMI
502 
503   if (!out_display_id || !width || !height || !format) {
504     return  HWC2_ERROR_BAD_PARAMETER;
505   }
506 
507   if (null_display_mode_) {
508     return 0;
509   }
510 
511   if (async_vds_creation_ && virtual_id_ != HWCCallbacks::kNumDisplays) {
512     *out_display_id = virtual_id_;
513     return HWC2_ERROR_NONE;
514   }
515 
516   auto status = CreateVirtualDisplayObj(width, height, format, out_display_id);
517   if (status == HWC2::Error::None) {
518     DLOGI("Created virtual display id:%" PRIu64 ", res: %dx%d", *out_display_id, width, height);
519   } else {
520     DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
521   }
522   return INT32(status);
523 }
524 
DestroyLayer(hwc2_display_t display,hwc2_layer_t layer)525 int32_t HWCSession::DestroyLayer(hwc2_display_t display, hwc2_layer_t layer) {
526   return CallDisplayFunction(display, &HWCDisplay::DestroyLayer, layer);
527 }
528 
DestroyVirtualDisplay(hwc2_display_t display)529 int32_t HWCSession::DestroyVirtualDisplay(hwc2_display_t display) {
530   if (display >= HWCCallbacks::kNumDisplays) {
531     return HWC2_ERROR_BAD_DISPLAY;
532   }
533 
534   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
535 
536   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
537     Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
538     std::bitset<kSecureMax> secure_sessions = 0;
539     hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
540     if (secure_sessions.any()) {
541       DLOGW("Secure session is active, defer destruction of virtual display id:%" PRIu64, display);
542       destroy_virtual_disp_pending_ = true;
543       return HWC2_ERROR_NONE;
544     }
545   }
546 
547   for (auto &map_info : map_info_virtual_) {
548     if (map_info.client_id == display) {
549       DLOGI("Destroying virtual display id:%" PRIu64, display);
550       DestroyDisplay(&map_info);
551       break;
552     }
553   }
554   virtual_id_ = HWCCallbacks::kNumDisplays;
555 
556   return HWC2_ERROR_NONE;
557 }
558 
GetVirtualDisplayId()559 int32_t HWCSession::GetVirtualDisplayId() {
560   HWDisplaysInfo hw_displays_info = {};
561   core_intf_->GetDisplaysStatus(&hw_displays_info);
562   for (auto &iter : hw_displays_info) {
563     auto &info = iter.second;
564     if (info.display_type != kVirtual) {
565       continue;
566     }
567 
568     return info.display_id;
569   }
570 
571   return -1;
572 }
573 
Dump(uint32_t * out_size,char * out_buffer)574 void HWCSession::Dump(uint32_t *out_size, char *out_buffer) {
575   if (!out_size) {
576     return;
577   }
578 
579   const size_t max_dump_size = 16384;  // 16 kB
580 
581   if (out_buffer == nullptr) {
582     *out_size = max_dump_size;
583   } else {
584     std::ostringstream os;
585     for (int id = 0; id < HWCCallbacks::kNumRealDisplays; id++) {
586       SCOPE_LOCK(locker_[id]);
587       if (hwc_display_[id]) {
588         hwc_display_[id]->Dump(&os);
589       }
590     }
591     Fence::Dump(&os);
592 
593     std::string s = os.str();
594     auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
595     *out_size = UINT32(copied);
596   }
597 }
598 
GetMaxVirtualDisplayCount()599 uint32_t HWCSession::GetMaxVirtualDisplayCount() {
600   return map_info_virtual_.size();
601 }
602 
GetActiveConfig(hwc2_display_t display,hwc2_config_t * out_config)603 int32_t HWCSession::GetActiveConfig(hwc2_display_t display, hwc2_config_t *out_config) {
604   return CallDisplayFunction(display, &HWCDisplay::GetActiveConfig, out_config);
605 }
606 
GetChangedCompositionTypes(hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)607 int32_t HWCSession::GetChangedCompositionTypes(hwc2_display_t display, uint32_t *out_num_elements,
608                                                hwc2_layer_t *out_layers, int32_t *out_types) {
609   // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
610   if (!out_num_elements) {
611     return  HWC2_ERROR_BAD_PARAMETER;
612   }
613   return CallDisplayFunction(display, &HWCDisplay::GetChangedCompositionTypes, out_num_elements,
614                              out_layers, out_types);
615 }
616 
GetClientTargetSupport(hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)617 int32_t HWCSession::GetClientTargetSupport(hwc2_display_t display, uint32_t width, uint32_t height,
618                                            int32_t format, int32_t dataspace) {
619   return CallDisplayFunction(display, &HWCDisplay::GetClientTargetSupport, width, height, format,
620                              dataspace);
621 }
622 
GetColorModes(hwc2_display_t display,uint32_t * out_num_modes,int32_t * int_out_modes)623 int32_t HWCSession::GetColorModes(hwc2_display_t display, uint32_t *out_num_modes,
624                                   int32_t /*ColorMode*/ *int_out_modes) {
625   auto out_modes = reinterpret_cast<ColorMode *>(int_out_modes);
626   if (out_num_modes == nullptr) {
627     return HWC2_ERROR_BAD_PARAMETER;
628   }
629   return CallDisplayFunction(display, &HWCDisplay::GetColorModes, out_num_modes, out_modes);
630 }
631 
GetRenderIntents(hwc2_display_t display,int32_t int_mode,uint32_t * out_num_intents,int32_t * int_out_intents)632 int32_t HWCSession::GetRenderIntents(hwc2_display_t display, int32_t /*ColorMode*/ int_mode,
633                                      uint32_t *out_num_intents,
634                                      int32_t /*RenderIntent*/ *int_out_intents) {
635   auto mode = static_cast<ColorMode>(int_mode);
636   auto out_intents = reinterpret_cast<RenderIntent *>(int_out_intents);
637   if (out_num_intents == nullptr) {
638     return HWC2_ERROR_BAD_PARAMETER;
639   }
640 
641   if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
642     DLOGE("Invalid ColorMode: %d", mode);
643     return HWC2_ERROR_BAD_PARAMETER;
644   }
645   return CallDisplayFunction(display, &HWCDisplay::GetRenderIntents, mode, out_num_intents,
646                              out_intents);
647 }
648 
GetDataspaceSaturationMatrix(int32_t int_dataspace,float * out_matrix)649 int32_t HWCSession::GetDataspaceSaturationMatrix(int32_t /*Dataspace*/ int_dataspace,
650                                                  float *out_matrix) {
651   auto dataspace = static_cast<Dataspace>(int_dataspace);
652   if (out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
653     return HWC2_ERROR_BAD_PARAMETER;
654   }
655   // We only have the matrix for sRGB
656   float saturation_matrix[kDataspaceSaturationMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
657                                                                0.0, 1.0, 0.0, 0.0, \
658                                                                0.0, 0.0, 1.0, 0.0, \
659                                                                0.0, 0.0, 0.0, 1.0 };
660 
661   for (int32_t i = 0; i < kDataspaceSaturationMatrixCount; i += 4) {
662     DLOGD("%f %f %f %f", saturation_matrix[i], saturation_matrix[i + 1], saturation_matrix[i + 2],
663           saturation_matrix[i + 3]);
664   }
665   for (uint32_t i = 0; i < kDataspaceSaturationMatrixCount; i++) {
666     out_matrix[i] = saturation_matrix[i];
667   }
668   return HWC2_ERROR_NONE;
669 }
670 
GetPerFrameMetadataKeys(hwc2_display_t display,uint32_t * out_num_keys,int32_t * int_out_keys)671 int32_t HWCSession::GetPerFrameMetadataKeys(hwc2_display_t display, uint32_t *out_num_keys,
672                                             int32_t *int_out_keys) {
673   auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
674   return CallDisplayFunction(display, &HWCDisplay::GetPerFrameMetadataKeys, out_num_keys,
675                              out_keys);
676 }
677 
SetLayerPerFrameMetadata(hwc2_display_t display,hwc2_layer_t layer,uint32_t num_elements,const int32_t * int_keys,const float * metadata)678 int32_t HWCSession::SetLayerPerFrameMetadata(hwc2_display_t display, hwc2_layer_t layer,
679                                              uint32_t num_elements, const int32_t *int_keys,
680                                              const float *metadata) {
681   auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
682   return CallLayerFunction(display, layer, &HWCLayer::SetLayerPerFrameMetadata, num_elements,
683                            keys, metadata);
684 }
685 
SetLayerPerFrameMetadataBlobs(hwc2_display_t display,hwc2_layer_t layer,uint32_t num_elements,const int32_t * int_keys,const uint32_t * sizes,const uint8_t * metadata)686 int32_t HWCSession:: SetLayerPerFrameMetadataBlobs(hwc2_display_t display,
687                                                    hwc2_layer_t layer, uint32_t num_elements,
688                                                    const int32_t *int_keys, const uint32_t *sizes,
689                                                    const uint8_t *metadata) {
690   auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
691   return CallLayerFunction(display, layer, &HWCLayer::SetLayerPerFrameMetadataBlobs,
692                            num_elements, keys, sizes, metadata);
693 }
694 
SetDisplayedContentSamplingEnabled(hwc2_display_t display,int32_t enabled,uint8_t component_mask,uint64_t max_frames)695 int32_t HWCSession::SetDisplayedContentSamplingEnabled(hwc2_display_t display, int32_t enabled,
696                                                        uint8_t component_mask,
697                                                        uint64_t max_frames) {
698   static constexpr int32_t validComponentMask = HWC2_FORMAT_COMPONENT_0 | HWC2_FORMAT_COMPONENT_1 |
699                                                 HWC2_FORMAT_COMPONENT_2 | HWC2_FORMAT_COMPONENT_3;
700   if (component_mask & ~validComponentMask)
701     return HWC2_ERROR_BAD_PARAMETER;
702   return CallDisplayFunction(display, &HWCDisplay::SetDisplayedContentSamplingEnabled, enabled,
703                              component_mask, max_frames);
704 }
705 
GetDisplayedContentSamplingAttributes(hwc2_display_t display,int32_t * format,int32_t * dataspace,uint8_t * supported_components)706 int32_t HWCSession::GetDisplayedContentSamplingAttributes(hwc2_display_t display, int32_t *format,
707                                                           int32_t *dataspace,
708                                                           uint8_t *supported_components) {
709   return CallDisplayFunction(display, &HWCDisplay::GetDisplayedContentSamplingAttributes, format,
710                              dataspace, supported_components);
711 }
712 
GetDisplayedContentSample(hwc2_display_t display,uint64_t max_frames,uint64_t timestamp,uint64_t * numFrames,int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],uint64_t * samples[NUM_HISTOGRAM_COLOR_COMPONENTS])713 int32_t HWCSession::GetDisplayedContentSample(hwc2_display_t display, uint64_t max_frames,
714                                               uint64_t timestamp, uint64_t *numFrames,
715                                               int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
716                                               uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
717   return CallDisplayFunction(display, &HWCDisplay::GetDisplayedContentSample, max_frames, timestamp,
718                              numFrames, samples_size, samples);
719 }
720 
GetDisplayAttribute(hwc2_display_t display,hwc2_config_t config,HwcAttribute attribute,int32_t * out_value)721 int32_t HWCSession::GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
722                                         HwcAttribute attribute, int32_t *out_value) {
723   if (out_value == nullptr) {
724     return HWC2_ERROR_BAD_PARAMETER;
725   }
726   return CallDisplayFunction(display, &HWCDisplay::GetDisplayAttribute, config, attribute,
727                              out_value);
728 }
729 
GetDisplayConfigs(hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)730 int32_t HWCSession::GetDisplayConfigs(hwc2_display_t display, uint32_t *out_num_configs,
731                                       hwc2_config_t *out_configs) {
732   return CallDisplayFunction(display, &HWCDisplay::GetDisplayConfigs, out_num_configs,
733                              out_configs);
734 }
735 
GetDisplayName(hwc2_display_t display,uint32_t * out_size,char * out_name)736 int32_t HWCSession::GetDisplayName(hwc2_display_t display, uint32_t *out_size, char *out_name) {
737   return CallDisplayFunction(display, &HWCDisplay::GetDisplayName, out_size, out_name);
738 }
739 
GetDisplayRequests(hwc2_display_t display,int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_layer_requests)740 int32_t HWCSession::GetDisplayRequests(hwc2_display_t display, int32_t *out_display_requests,
741                                        uint32_t *out_num_elements, hwc2_layer_t *out_layers,
742                                        int32_t *out_layer_requests) {
743   return CallDisplayFunction(display, &HWCDisplay::GetDisplayRequests, out_display_requests,
744                              out_num_elements, out_layers, out_layer_requests);
745 }
746 
GetDisplayType(hwc2_display_t display,int32_t * out_type)747 int32_t HWCSession::GetDisplayType(hwc2_display_t display, int32_t *out_type) {
748   return CallDisplayFunction(display, &HWCDisplay::GetDisplayType, out_type);
749 }
750 
751 
GetHdrCapabilities(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)752 int32_t HWCSession::GetHdrCapabilities(hwc2_display_t display, uint32_t* out_num_types,
753                                        int32_t* out_types, float* out_max_luminance,
754                                        float* out_max_average_luminance,
755                                        float* out_min_luminance) {
756   return CallDisplayFunction(display, &HWCDisplay::GetHdrCapabilities, out_num_types, out_types,
757                              out_max_luminance, out_max_average_luminance, out_min_luminance);
758 }
759 
760 
GetReleaseFences(hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,std::vector<shared_ptr<Fence>> * out_fences)761 int32_t HWCSession::GetReleaseFences(hwc2_display_t display, uint32_t *out_num_elements,
762                                      hwc2_layer_t *out_layers,
763                                      std::vector<shared_ptr<Fence>> *out_fences) {
764   return CallDisplayFunction(display, &HWCDisplay::GetReleaseFences, out_num_elements, out_layers,
765                              out_fences);
766 }
767 
PerformQsyncCallback(hwc2_display_t display)768 void HWCSession::PerformQsyncCallback(hwc2_display_t display) {
769   std::shared_ptr<DisplayConfig::ConfigCallback> callback = qsync_callback_.lock();
770   if (!callback) {
771     return;
772   }
773 
774   bool qsync_enabled = 0;
775   int32_t refresh_rate = 0, qsync_refresh_rate = 0;
776   if (hwc_display_[display]->IsQsyncCallbackNeeded(&qsync_enabled,
777       &refresh_rate, &qsync_refresh_rate)) {
778     callback->NotifyQsyncChange(qsync_enabled, refresh_rate, qsync_refresh_rate);
779   }
780 }
781 
PerformIdleStatusCallback(hwc2_display_t display)782 void HWCSession::PerformIdleStatusCallback(hwc2_display_t display) {
783   std::shared_ptr<DisplayConfig::ConfigCallback> callback = idle_callback_.lock();
784   if (!callback) {
785     return;
786   }
787 
788   if (hwc_display_[display]->IsDisplayIdle()) {
789     DTRACE_SCOPED();
790     callback->NotifyIdleStatus(true);
791   }
792 }
793 
PresentDisplay(hwc2_display_t display,shared_ptr<Fence> * out_retire_fence)794 int32_t HWCSession::PresentDisplay(hwc2_display_t display, shared_ptr<Fence> *out_retire_fence) {
795   auto status = HWC2::Error::BadDisplay;
796   DTRACE_SCOPED();
797 
798   SCOPE_LOCK(system_locker_);
799   if (display >= HWCCallbacks::kNumDisplays) {
800     DLOGW("Invalid Display : display = %" PRIu64, display);
801     return HWC2_ERROR_BAD_DISPLAY;
802   }
803 
804   HandleSecureSession();
805 
806 
807   hwc2_display_t target_display = display;
808 
809   {
810     SCOPE_LOCK(power_state_[display]);
811     if (power_state_transition_[display]) {
812       // Route all interactions with client to dummy display.
813       target_display = map_hwc_display_.find(display)->second;
814     }
815   }
816 
817   {
818     SEQUENCE_EXIT_SCOPE_LOCK(locker_[target_display]);
819     if (!hwc_display_[target_display]) {
820       DLOGW("Removed Display : display = %" PRIu64, target_display);
821       return HWC2_ERROR_BAD_DISPLAY;
822     }
823 
824     if (out_retire_fence == nullptr) {
825       return HWC2_ERROR_BAD_PARAMETER;
826     }
827 
828     if (pending_power_mode_[display]) {
829       status = HWC2::Error::None;
830     } else {
831       hwc_display_[target_display]->ProcessActiveConfigChange();
832       status = PresentDisplayInternal(target_display);
833       if (status == HWC2::Error::None) {
834         // Check if hwc's refresh trigger is getting exercised.
835         if (callbacks_.NeedsRefresh(display)) {
836           hwc_display_[target_display]->SetPendingRefresh();
837           callbacks_.ResetRefresh(display);
838         }
839         status = hwc_display_[target_display]->Present(out_retire_fence);
840         if (status == HWC2::Error::None) {
841           PerformQsyncCallback(target_display);
842           PerformIdleStatusCallback(target_display);
843         }
844       }
845     }
846   }
847 
848   if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
849     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[target_display]);
850   }
851 
852   HandlePendingPowerMode(display, *out_retire_fence);
853   HandlePendingHotplug(display, *out_retire_fence);
854   HandlePendingRefresh();
855   if (status != HWC2::Error::NotValidated) {
856     cwb_.PresentDisplayDone(display);
857   }
858   display_ready_.set(UINT32(display));
859   {
860     std::unique_lock<std::mutex> caller_lock(hotplug_mutex_);
861     hotplug_cv_.notify_one();
862   }
863 
864   return INT32(status);
865 }
866 
HandlePendingRefresh()867 void HWCSession::HandlePendingRefresh() {
868   if (pending_refresh_.none()) {
869     return;
870   }
871 
872   for (size_t i = 0; i < pending_refresh_.size(); i++) {
873     if (pending_refresh_.test(i)) {
874       callbacks_.Refresh(i);
875       break;
876     }
877   }
878 
879   pending_refresh_.reset();
880 }
881 
RegisterCallback(int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)882 void HWCSession::RegisterCallback(int32_t descriptor, hwc2_callback_data_t callback_data,
883                                   hwc2_function_pointer_t pointer) {
884   auto desc = static_cast<HWC2::Callback>(descriptor);
885 
886   // Detect if client died and now is back
887   bool already_connected = false;
888   vector<hwc2_display_t> pending_hotplugs;
889   if (descriptor == HWC2_CALLBACK_HOTPLUG && pointer) {
890     already_connected = callbacks_.IsClientConnected();
891     if (already_connected) {
892       for (auto& map_info : map_info_builtin_) {
893         SCOPE_LOCK(locker_[map_info.client_id]);
894         if (hwc_display_[map_info.client_id]) {
895           pending_hotplugs.push_back(static_cast<hwc2_display_t>(map_info.client_id));
896         }
897       }
898       for (auto& map_info : map_info_pluggable_) {
899         SCOPE_LOCK(locker_[map_info.client_id]);
900         if (hwc_display_[map_info.client_id]) {
901           pending_hotplugs.push_back(static_cast<hwc2_display_t>(map_info.client_id));
902         }
903       }
904     }
905   }
906 
907   auto error = callbacks_.Register(desc, callback_data, pointer);
908   if (error != HWC2::Error::None) {
909     return;
910   }
911 
912   DLOGI("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
913   if (descriptor == HWC2_CALLBACK_HOTPLUG && pointer) {
914     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
915       DLOGI("Hotplugging primary...");
916       callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
917     }
918     // Create displays since they should now have their final display indices set.
919     DLOGI("Handling built-in displays...");
920     if (HandleBuiltInDisplays()) {
921       DLOGW("Failed handling built-in displays.");
922     }
923     DLOGI("Handling pluggable displays...");
924     int32_t err = HandlePluggableDisplays(false);
925     if (err) {
926       DLOGW("All displays could not be created. Error %d '%s'. Hotplug handling %s.", err,
927             strerror(abs(err)), pending_hotplug_event_ == kHotPlugEvent ? "deferred" :
928             "dropped");
929     }
930 
931     // If previously registered, call hotplug for all connected displays to refresh
932     if (already_connected) {
933       std::vector<hwc2_display_t> updated_pending_hotplugs;
934       for (auto client_id : pending_hotplugs) {
935         SCOPE_LOCK(locker_[client_id]);
936         // check if the display is unregistered
937         if (hwc_display_[client_id]) {
938           updated_pending_hotplugs.push_back(client_id);
939         }
940       }
941       for (auto client_id : updated_pending_hotplugs) {
942         DLOGI("Re-hotplug display connected: client id = %d", UINT32(client_id));
943         callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
944       }
945     }
946   }
947 
948   if (descriptor == HWC2_CALLBACK_HOTPLUG) {
949     client_connected_ = !!pointer;
950     // Notfify all displays.
951     NotifyClientStatus(client_connected_);
952   }
953 
954   // On SF stop, disable the idle time.
955   if (!pointer && is_idle_time_up_ && hwc_display_[HWC_DISPLAY_PRIMARY]) { // De-registering…
956     DLOGI("disable idle time");
957     hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(0,0);
958     is_idle_time_up_ = false;
959   }
960 
961   need_invalidate_ = false;
962 }
963 
SetActiveConfig(hwc2_display_t display,hwc2_config_t config)964 int32_t HWCSession::SetActiveConfig(hwc2_display_t display, hwc2_config_t config) {
965   return CallDisplayFunction(display, &HWCDisplay::SetActiveConfig, config);
966 }
967 
SetClientTarget(hwc2_display_t display,buffer_handle_t target,const shared_ptr<Fence> acquire_fence,int32_t dataspace,hwc_region_t damage)968 int32_t HWCSession::SetClientTarget(hwc2_display_t display, buffer_handle_t target,
969                                     const shared_ptr<Fence> acquire_fence, int32_t dataspace,
970                                     hwc_region_t damage) {
971   return CallDisplayFunction(display, &HWCDisplay::SetClientTarget, target, acquire_fence,
972                              dataspace, damage);
973 }
974 
SetColorMode(hwc2_display_t display,int32_t int_mode)975 int32_t HWCSession::SetColorMode(hwc2_display_t display, int32_t /*ColorMode*/ int_mode) {
976   auto mode = static_cast<ColorMode>(int_mode);
977   if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
978     return HWC2_ERROR_BAD_PARAMETER;
979   }
980   return CallDisplayFunction(display, &HWCDisplay::SetColorMode, mode);
981 }
982 
SetColorModeWithRenderIntent(hwc2_display_t display,int32_t int_mode,int32_t int_render_intent)983 int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_display_t display,
984                                                  int32_t /*ColorMode*/ int_mode,
985                                                  int32_t /*RenderIntent*/ int_render_intent) {
986   auto mode = static_cast<ColorMode>(int_mode);
987   if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
988     return HWC2_ERROR_BAD_PARAMETER;
989   }
990 
991   if ((int_render_intent < 0) || (int_render_intent > MAX_EXTENDED_RENDER_INTENT)) {
992     DLOGE("Invalid RenderIntent: %d", int_render_intent);
993     return HWC2_ERROR_BAD_PARAMETER;
994   }
995 
996   auto render_intent = static_cast<RenderIntent>(int_render_intent);
997   return CallDisplayFunction(display, &HWCDisplay::SetColorModeWithRenderIntent, mode,
998                              render_intent);
999 }
1000 
SetColorTransform(hwc2_display_t display,const float * matrix,int32_t hint)1001 int32_t HWCSession::SetColorTransform(hwc2_display_t display, const float *matrix,
1002                                       int32_t /*android_color_transform_t*/ hint) {
1003   if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
1004        hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
1005     return HWC2_ERROR_BAD_PARAMETER;
1006   }
1007   android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
1008   return CallDisplayFunction(display, &HWCDisplay::SetColorTransform, matrix, transform_hint);
1009 }
1010 
SetCursorPosition(hwc2_display_t display,hwc2_layer_t layer,int32_t x,int32_t y)1011 int32_t HWCSession::SetCursorPosition(hwc2_display_t display, hwc2_layer_t layer, int32_t x,
1012                                       int32_t y) {
1013   auto status = INT32(HWC2::Error::None);
1014   status = CallDisplayFunction(display, &HWCDisplay::SetCursorPosition, layer, x, y);
1015   if (status == INT32(HWC2::Error::None)) {
1016     // Update cursor position
1017     CallLayerFunction(display, layer, &HWCLayer::SetCursorPosition, x, y);
1018   }
1019   return status;
1020 }
1021 
SetLayerBlendMode(hwc2_display_t display,hwc2_layer_t layer,int32_t int_mode)1022 int32_t HWCSession::SetLayerBlendMode(hwc2_display_t display, hwc2_layer_t layer,
1023                                       int32_t int_mode) {
1024   if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
1025     return HWC2_ERROR_BAD_PARAMETER;
1026   }
1027   auto mode = static_cast<HWC2::BlendMode>(int_mode);
1028   return CallLayerFunction(display, layer, &HWCLayer::SetLayerBlendMode, mode);
1029 }
1030 
SetLayerBuffer(hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,const shared_ptr<Fence> & acquire_fence)1031 int32_t HWCSession::SetLayerBuffer(hwc2_display_t display, hwc2_layer_t layer,
1032                                    buffer_handle_t buffer,
1033                                    const shared_ptr<Fence> &acquire_fence) {
1034   return CallLayerFunction(display, layer, &HWCLayer::SetLayerBuffer, buffer, acquire_fence);
1035 }
1036 
SetLayerColor(hwc2_display_t display,hwc2_layer_t layer,hwc_color_t color)1037 int32_t HWCSession::SetLayerColor(hwc2_display_t display, hwc2_layer_t layer, hwc_color_t color) {
1038   return CallLayerFunction(display, layer, &HWCLayer::SetLayerColor, color);
1039 }
1040 
SetLayerCompositionType(hwc2_display_t display,hwc2_layer_t layer,int32_t int_type)1041 int32_t HWCSession::SetLayerCompositionType(hwc2_display_t display, hwc2_layer_t layer,
1042                                             int32_t int_type) {
1043   auto type = static_cast<HWC2::Composition>(int_type);
1044   return CallLayerFunction(display, layer, &HWCLayer::SetLayerCompositionType, type);
1045 }
1046 
SetLayerDataspace(hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)1047 int32_t HWCSession::SetLayerDataspace(hwc2_display_t display, hwc2_layer_t layer,
1048                                       int32_t dataspace) {
1049   return CallLayerFunction(display, layer, &HWCLayer::SetLayerDataspace, dataspace);
1050 }
1051 
SetLayerDisplayFrame(hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)1052 int32_t HWCSession::SetLayerDisplayFrame(hwc2_display_t display, hwc2_layer_t layer,
1053                                          hwc_rect_t frame) {
1054   return CallLayerFunction(display, layer, &HWCLayer::SetLayerDisplayFrame, frame);
1055 }
1056 
SetLayerPlaneAlpha(hwc2_display_t display,hwc2_layer_t layer,float alpha)1057 int32_t HWCSession::SetLayerPlaneAlpha(hwc2_display_t display, hwc2_layer_t layer, float alpha) {
1058   return CallLayerFunction(display, layer, &HWCLayer::SetLayerPlaneAlpha, alpha);
1059 }
1060 
SetLayerSourceCrop(hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)1061 int32_t HWCSession::SetLayerSourceCrop(hwc2_display_t display, hwc2_layer_t layer,
1062                                        hwc_frect_t crop) {
1063   return HWCSession::CallLayerFunction(display, layer, &HWCLayer::SetLayerSourceCrop, crop);
1064 }
1065 
SetLayerSurfaceDamage(hwc2_display_t display,hwc2_layer_t layer,hwc_region_t damage)1066 int32_t HWCSession::SetLayerSurfaceDamage(hwc2_display_t display, hwc2_layer_t layer,
1067                                           hwc_region_t damage) {
1068   return CallLayerFunction(display, layer, &HWCLayer::SetLayerSurfaceDamage, damage);
1069 }
1070 
SetLayerTransform(hwc2_display_t display,hwc2_layer_t layer,int32_t int_transform)1071 int32_t HWCSession::SetLayerTransform(hwc2_display_t display, hwc2_layer_t layer,
1072                                       int32_t int_transform) {
1073   auto transform = static_cast<HWC2::Transform>(int_transform);
1074   return CallLayerFunction(display, layer, &HWCLayer::SetLayerTransform, transform);
1075 }
1076 
SetLayerVisibleRegion(hwc2_display_t display,hwc2_layer_t layer,hwc_region_t visible)1077 int32_t HWCSession::SetLayerVisibleRegion(hwc2_display_t display, hwc2_layer_t layer,
1078                                           hwc_region_t visible) {
1079   return CallLayerFunction(display, layer, &HWCLayer::SetLayerVisibleRegion, visible);
1080 }
1081 
SetLayerZOrder(hwc2_display_t display,hwc2_layer_t layer,uint32_t z)1082 int32_t HWCSession::SetLayerZOrder(hwc2_display_t display, hwc2_layer_t layer, uint32_t z) {
1083   return CallDisplayFunction(display, &HWCDisplay::SetLayerZOrder, layer, z);
1084 }
1085 
SetLayerType(hwc2_display_t display,hwc2_layer_t layer,IQtiComposerClient::LayerType type)1086 int32_t HWCSession::SetLayerType(hwc2_display_t display, hwc2_layer_t layer,
1087                                  IQtiComposerClient::LayerType type) {
1088   return CallDisplayFunction(display, &HWCDisplay::SetLayerType, layer, type);
1089 }
1090 
SetLayerColorTransform(hwc2_display_t display,hwc2_layer_t layer,const float * matrix)1091 int32_t HWCSession::SetLayerColorTransform(hwc2_display_t display, hwc2_layer_t layer,
1092                                            const float *matrix) {
1093   return CallLayerFunction(display, layer, &HWCLayer::SetLayerColorTransform, matrix);
1094 }
1095 
SetDisplayElapseTime(hwc2_display_t display,uint64_t time)1096 int32_t HWCSession::SetDisplayElapseTime(hwc2_display_t display, uint64_t time) {
1097   return CallDisplayFunction(display, &HWCDisplay::SetDisplayElapseTime, time);
1098 }
1099 
SetOutputBuffer(hwc2_display_t display,buffer_handle_t buffer,const shared_ptr<Fence> & release_fence)1100 int32_t HWCSession::SetOutputBuffer(hwc2_display_t display, buffer_handle_t buffer,
1101                                     const shared_ptr<Fence> &release_fence) {
1102   if (INT32(display) != GetDisplayIndex(qdutils::DISPLAY_VIRTUAL)) {
1103     return HWC2_ERROR_UNSUPPORTED;
1104   }
1105 
1106   SCOPE_LOCK(locker_[display]);
1107   if (hwc_display_[display]) {
1108     auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_display_[display]);
1109     auto status = vds->SetOutputBuffer(buffer, release_fence);
1110     return INT32(status);
1111   } else {
1112     return HWC2_ERROR_BAD_DISPLAY;
1113   }
1114 }
1115 
SetPowerMode(hwc2_display_t display,int32_t int_mode)1116 int32_t HWCSession::SetPowerMode(hwc2_display_t display, int32_t int_mode) {
1117   if (display >= HWCCallbacks::kNumDisplays) {
1118     return HWC2_ERROR_BAD_DISPLAY;
1119   }
1120 
1121   //  validate device and also avoid undefined behavior in cast to HWC2::PowerMode
1122   if (int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
1123     return HWC2_ERROR_BAD_PARAMETER;
1124   }
1125 
1126   auto mode = static_cast<HWC2::PowerMode>(int_mode);
1127 
1128   // When secure session going on primary, if power request comes on second built-in, cache it and
1129   // process once secure session ends.
1130   // Allow power off transition during secure session.
1131   bool is_builtin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
1132   bool is_power_off = (hwc_display_[display]->GetCurrentPowerMode() == HWC2::PowerMode::Off);
1133   if (secure_session_active_ && is_builtin && is_power_off) {
1134     if (GetActiveBuiltinDisplay() != HWCCallbacks::kNumDisplays) {
1135       DLOGI("Secure session in progress, defer power state change");
1136       hwc_display_[display]->SetPendingPowerMode(mode);
1137       return HWC2_ERROR_NONE;
1138     }
1139   }
1140 
1141   if (pending_power_mode_[display]) {
1142     DLOGW("Set power mode is not allowed during secure display session");
1143     return HWC2_ERROR_UNSUPPORTED;
1144   }
1145 
1146   //  all displays support on/off. Check for doze modes
1147   int support = 0;
1148   auto status = GetDozeSupport(display, &support);
1149   if (status != HWC2_ERROR_NONE) {
1150     DLOGE("Failed to get doze support Error = %d", status);
1151     return INT32(status);
1152   }
1153 
1154   if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
1155     return HWC2_ERROR_UNSUPPORTED;
1156   }
1157 
1158   // async_powermode supported for power on and off
1159   bool override_mode = async_powermode_ && display_ready_.test(UINT32(display)) &&
1160                        async_power_mode_triggered_;
1161   HWC2::PowerMode last_power_mode = hwc_display_[display]->GetCurrentPowerMode();
1162 
1163   if (last_power_mode == mode) {
1164     return HWC2_ERROR_NONE;
1165   }
1166 
1167   // 1. For power transition cases other than Off->On or On->Off, async power mode
1168   // will not be used. Hence, set override_mode to false for them.
1169   // 2. When SF requests Doze mode transition on panels where Doze mode is not supported
1170   // (like video mode), HWComposer.cpp will override the request to "On". Handle such cases
1171   // in main thread path.
1172   if (!((last_power_mode == HWC2::PowerMode::Off && mode == HWC2::PowerMode::On) ||
1173      (last_power_mode == HWC2::PowerMode::On && mode == HWC2::PowerMode::Off)) ||
1174      (last_power_mode == HWC2::PowerMode::Off && mode == HWC2::PowerMode::On)) {
1175     override_mode = false;
1176   }
1177 
1178   if (!override_mode) {
1179     auto error = CallDisplayFunction(display, &HWCDisplay::SetPowerMode, mode,
1180                                      false /* teardown */);
1181     if (INT32(error) != HWC2_ERROR_NONE) {
1182       return INT32(error);
1183     }
1184   } else {
1185     Locker::ScopeLock lock_disp(locker_[display]);
1186     // Update hwc state for now. Actual poweron will handled through DisplayConfig.
1187     hwc_display_[display]->UpdatePowerMode(mode);
1188   }
1189   // Reset idle pc ref count on suspend, as we enable idle pc during suspend.
1190   if (mode == HWC2::PowerMode::Off) {
1191     idle_pc_ref_cnt_ = 0;
1192   }
1193 
1194 
1195   UpdateThrottlingRate();
1196 
1197   if (mode == HWC2::PowerMode::Doze) {
1198     // Trigger one more refresh for PP features to take effect.
1199     pending_refresh_.set(UINT32(display));
1200   }
1201 
1202   return HWC2_ERROR_NONE;
1203 }
1204 
SetVsyncEnabled(hwc2_display_t display,int32_t int_enabled)1205 int32_t HWCSession::SetVsyncEnabled(hwc2_display_t display, int32_t int_enabled) {
1206   //  avoid undefined behavior in cast to HWC2::Vsync
1207   if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
1208     return HWC2_ERROR_BAD_PARAMETER;
1209   }
1210 
1211   auto enabled = static_cast<HWC2::Vsync>(int_enabled);
1212 
1213   if (int_enabled == HWC2_VSYNC_ENABLE) {
1214     callbacks_.UpdateVsyncSource(display);
1215   }
1216 
1217   return CallDisplayFunction(display, &HWCDisplay::SetVsyncEnabled, enabled);
1218 }
1219 
GetDozeSupport(hwc2_display_t display,int32_t * out_support)1220 int32_t HWCSession::GetDozeSupport(hwc2_display_t display, int32_t *out_support) {
1221   if (!out_support) {
1222     return HWC2_ERROR_BAD_PARAMETER;
1223   }
1224 
1225   if (display >= HWCCallbacks::kNumDisplays || (hwc_display_[display] == nullptr)) {
1226     // display may come as -1  from VTS test case
1227     DLOGE("Invalid Display %d ", UINT32(display));
1228     return HWC2_ERROR_BAD_DISPLAY;
1229   }
1230 
1231   *out_support = 0;
1232 
1233   SCOPE_LOCK(locker_[display]);
1234   if (!hwc_display_[display]) {
1235     DLOGE("Display %d is not created yet.", INT32(display));
1236     return HWC2_ERROR_BAD_DISPLAY;
1237   }
1238 
1239   if (hwc_display_[display]->GetDisplayClass() != DISPLAY_CLASS_BUILTIN) {
1240     return HWC2_ERROR_NONE;
1241   }
1242 
1243   *out_support = hwc_display_[display]->HasSmartPanelConfig() ? 1 : 0;
1244 
1245   return HWC2_ERROR_NONE;
1246 }
1247 
isSmartPanelConfig(uint32_t disp_id,uint32_t config_id)1248 bool HWCSession::isSmartPanelConfig(uint32_t disp_id, uint32_t config_id) {
1249   if (disp_id != qdutils::DISPLAY_PRIMARY) {
1250     return false;
1251   }
1252 
1253   SCOPE_LOCK(locker_[disp_id]);
1254   if (!hwc_display_[disp_id]) {
1255     DLOGE("Display %d is not created yet.", disp_id);
1256     return false;
1257   }
1258 
1259   return hwc_display_[disp_id]->IsSmartPanelConfig(config_id);
1260 }
1261 
ValidateDisplay(hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)1262 int32_t HWCSession::ValidateDisplay(hwc2_display_t display, uint32_t *out_num_types,
1263                                     uint32_t *out_num_requests) {
1264   //  out_num_types and out_num_requests will be non-NULL
1265 
1266   if (display >= HWCCallbacks::kNumDisplays) {
1267     return HWC2_ERROR_BAD_DISPLAY;
1268   }
1269 
1270   hwc2_display_t target_display = display;
1271 
1272   {
1273     SCOPE_LOCK(power_state_[display]);
1274     if (power_state_transition_[display]) {
1275       // Route all interactions with client to dummy display.
1276       target_display = map_hwc_display_.find(display)->second;
1277     }
1278   }
1279   DTRACE_SCOPED();
1280   // TODO(user): Handle secure session, handle QDCM solid fill
1281   auto status = HWC2::Error::BadDisplay;
1282   HandleSecureSession();
1283   {
1284     SEQUENCE_ENTRY_SCOPE_LOCK(locker_[target_display]);
1285     if (pending_power_mode_[display]) {
1286       status = HWC2::Error::None;
1287     } else if (hwc_display_[target_display]) {
1288       hwc_display_[target_display]->ProcessActiveConfigChange();
1289       hwc_display_[target_display]->SetFastPathComposition(false);
1290       status = ValidateDisplayInternal(target_display, out_num_types, out_num_requests);
1291     }
1292   }
1293 
1294   // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
1295   if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
1296     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[target_display]);
1297   }
1298 
1299   if (display != target_display) {
1300     // Validate done on a dummy display. Assume present is complete.
1301     SEQUENCE_EXIT_SCOPE_LOCK(locker_[target_display]);
1302   }
1303 
1304   return INT32(status);
1305 }
1306 
CreateVirtualDisplayObj(uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)1307 HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
1308                                                 hwc2_display_t *out_display_id) {
1309   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
1310   hwc2_display_t client_id = HWCCallbacks::kNumDisplays;
1311   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
1312     SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
1313     std::bitset<kSecureMax> secure_sessions = 0;
1314     if (hwc_display_[active_builtin_disp_id]) {
1315       hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
1316     }
1317     if (secure_sessions.any()) {
1318       DLOGE("Secure session is active, cannot create virtual display.");
1319       return HWC2::Error::Unsupported;
1320     } else if (IsPluggableDisplayConnected()) {
1321       DLOGE("External session is active, cannot create virtual display.");
1322       return HWC2::Error::Unsupported;
1323     }
1324   }
1325 
1326   if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1327     DisplayError error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
1328     if (error) {
1329       return HWC2::Error::NoResources;
1330     }
1331   }
1332 
1333   // Lock confined to this scope
1334   int status = -EINVAL;
1335   for (auto &map_info : map_info_virtual_) {
1336     client_id = map_info.client_id;
1337     {
1338       SCOPE_LOCK(locker_[client_id]);
1339       auto &hwc_display = hwc_display_[client_id];
1340       if (hwc_display) {
1341         continue;
1342       }
1343 
1344       int32_t display_id = GetVirtualDisplayId();
1345       status = virtual_display_factory_.Create(core_intf_, &buffer_allocator_, &callbacks_,
1346                                                client_id, display_id, width, height,
1347                                                format, set_min_lum_, set_max_lum_, &hwc_display);
1348       // TODO(user): validate width and height support
1349       if (status) {
1350         return HWC2::Error::NoResources;
1351       }
1352 
1353       {
1354         SCOPE_LOCK(hdr_locker_[client_id]);
1355         is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display);
1356       }
1357 
1358       DLOGI("Created virtual display id:%" PRIu64 " with res: %dx%d", client_id, width, height);
1359 
1360       *out_display_id = client_id;
1361       map_info.disp_type = kVirtual;
1362       map_info.sdm_id = display_id;
1363       break;
1364     }
1365   }
1366 
1367   // Active builtin display needs revalidation
1368   if (!async_vds_creation_ && active_builtin_disp_id < HWCCallbacks::kNumRealDisplays) {
1369     SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
1370     hwc_display_[active_builtin_disp_id]->ResetValidation();
1371   }
1372 
1373   return HWC2::Error::None;
1374 }
1375 
IsPluggableDisplayConnected()1376 bool HWCSession::IsPluggableDisplayConnected() {
1377   for (auto &map_info : map_info_pluggable_) {
1378     if (hwc_display_[map_info.client_id]) {
1379       return true;
1380     }
1381   }
1382   return false;
1383 }
1384 
1385 // Qclient methods
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)1386 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
1387                                              android::Parcel *output_parcel) {
1388   android::status_t status = -EINVAL;
1389 
1390   switch (command) {
1391     case qService::IQService::DYNAMIC_DEBUG:
1392       if (!input_parcel) {
1393         DLOGE("QService command = %d: input_parcel needed.", command);
1394         break;
1395       }
1396       status = 0;
1397       DynamicDebug(input_parcel);
1398       break;
1399 
1400     case qService::IQService::SCREEN_REFRESH:
1401       if (!input_parcel) {
1402         DLOGE("QService command = %d: input_parcel needed.", command);
1403         break;
1404       }
1405       status = RefreshScreen(input_parcel);
1406       break;
1407 
1408     case qService::IQService::SET_IDLE_TIMEOUT:
1409       if (!input_parcel) {
1410         DLOGE("QService command = %d: input_parcel needed.", command);
1411         break;
1412       }
1413       status = SetIdleTimeout(UINT32(input_parcel->readInt32()));
1414       break;
1415 
1416     case qService::IQService::SET_FRAME_DUMP_CONFIG:
1417       if (!input_parcel) {
1418         DLOGE("QService command = %d: input_parcel needed.", command);
1419         break;
1420       }
1421       status = SetFrameDumpConfig(input_parcel);
1422       break;
1423 
1424     case qService::IQService::SET_MAX_PIPES_PER_MIXER:
1425       if (!input_parcel) {
1426         DLOGE("QService command = %d: input_parcel needed.", command);
1427         break;
1428       }
1429       status = SetMaxMixerStages(input_parcel);
1430       break;
1431 
1432     case qService::IQService::SET_DISPLAY_MODE:
1433       if (!input_parcel) {
1434         DLOGE("QService command = %d: input_parcel needed.", command);
1435         break;
1436       }
1437       status = SetDisplayMode(input_parcel);
1438       break;
1439 
1440     case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
1441         if (!input_parcel || !output_parcel) {
1442           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1443           break;
1444         }
1445         int disp_id = INT(input_parcel->readInt32());
1446         HWCDisplay::DisplayStatus disp_status =
1447               static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
1448         status = SetDisplayStatus(disp_id, disp_status);
1449         output_parcel->writeInt32(status);
1450       }
1451       break;
1452 
1453     case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
1454       if (!input_parcel) {
1455         DLOGE("QService command = %d: input_parcel needed.", command);
1456         break;
1457       }
1458       status = ConfigureRefreshRate(input_parcel);
1459       break;
1460 
1461     case qService::IQService::TOGGLE_SCREEN_UPDATES: {
1462         if (!input_parcel || !output_parcel) {
1463           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1464           break;
1465         }
1466         int32_t input = input_parcel->readInt32();
1467         status = ToggleScreenUpdate(input == 1);
1468         output_parcel->writeInt32(status);
1469       }
1470       break;
1471 
1472     case qService::IQService::QDCM_SVC_CMDS:
1473       if (!input_parcel || !output_parcel) {
1474         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1475         break;
1476       }
1477       status = QdcmCMDHandler(input_parcel, output_parcel);
1478       break;
1479 
1480     case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
1481         if (!input_parcel || !output_parcel) {
1482           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1483           break;
1484         }
1485         int disp_id = input_parcel->readInt32();
1486         uint32_t min_enc_level = UINT32(input_parcel->readInt32());
1487         status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
1488         output_parcel->writeInt32(status);
1489       }
1490       break;
1491 
1492     case qService::IQService::CONTROL_PARTIAL_UPDATE: {
1493         if (!input_parcel || !output_parcel) {
1494           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1495           break;
1496         }
1497         int disp_id = input_parcel->readInt32();
1498         uint32_t enable = UINT32(input_parcel->readInt32());
1499         status = ControlPartialUpdate(disp_id, enable == 1);
1500         output_parcel->writeInt32(status);
1501       }
1502       break;
1503 
1504     case qService::IQService::SET_ACTIVE_CONFIG: {
1505         if (!input_parcel) {
1506           DLOGE("QService command = %d: input_parcel needed.", command);
1507           break;
1508         }
1509         uint32_t config = UINT32(input_parcel->readInt32());
1510         int disp_id = input_parcel->readInt32();
1511         status = SetActiveConfigIndex(disp_id, config);
1512       }
1513       break;
1514 
1515     case qService::IQService::GET_ACTIVE_CONFIG: {
1516         if (!input_parcel || !output_parcel) {
1517           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1518           break;
1519         }
1520         int disp_id = input_parcel->readInt32();
1521         uint32_t config = 0;
1522         status = GetActiveConfigIndex(disp_id, &config);
1523         output_parcel->writeInt32(INT(config));
1524       }
1525       break;
1526 
1527     case qService::IQService::GET_CONFIG_COUNT: {
1528         if (!input_parcel || !output_parcel) {
1529           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1530           break;
1531         }
1532         int disp_id = input_parcel->readInt32();
1533         uint32_t count = 0;
1534         status = GetConfigCount(disp_id, &count);
1535         output_parcel->writeInt32(INT(count));
1536       }
1537       break;
1538 
1539     case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
1540       if (!input_parcel || !output_parcel) {
1541         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1542         break;
1543       }
1544       status = GetDisplayAttributesForConfig(input_parcel, output_parcel);
1545       break;
1546 
1547     case qService::IQService::GET_PANEL_BRIGHTNESS: {
1548         if (!output_parcel) {
1549           DLOGE("QService command = %d: output_parcel needed.", command);
1550           break;
1551         }
1552 
1553         uint32_t display = input_parcel->readUint32();
1554         uint32_t max_brightness_level = 0;
1555         status = getDisplayMaxBrightness(display, &max_brightness_level);
1556         if (status || !max_brightness_level) {
1557           output_parcel->writeInt32(max_brightness_level);
1558           DLOGE("Failed to get max brightness %u,  status %d", max_brightness_level, status);
1559           break;
1560         }
1561         DLOGV("Panel Max brightness is %u", max_brightness_level);
1562 
1563         float brightness_precent = -1.0f;
1564         status = getDisplayBrightness(display, &brightness_precent);
1565         if (brightness_precent == -1.0f) {
1566           output_parcel->writeInt32(0);
1567         } else {
1568           output_parcel->writeInt32(INT32(brightness_precent*(max_brightness_level - 1) + 1));
1569         }
1570       }
1571       break;
1572 
1573     case qService::IQService::SET_PANEL_BRIGHTNESS: {
1574         if (!input_parcel || !output_parcel) {
1575           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1576           break;
1577         }
1578 
1579         uint32_t max_brightness_level = 0;
1580         uint32_t display = HWC_DISPLAY_PRIMARY;
1581         status = getDisplayMaxBrightness(display, &max_brightness_level);
1582         if (status || max_brightness_level <= 1) {
1583           output_parcel->writeInt32(max_brightness_level);
1584           DLOGE("Failed to get max brightness %u, status %d", max_brightness_level, status);
1585           break;
1586         }
1587         DLOGV("Panel Max brightness is %u", max_brightness_level);
1588 
1589         int level = input_parcel->readInt32();
1590         if (level == 0) {
1591           status = SetDisplayBrightness(display, -1.0f);
1592         } else {
1593           status = SetDisplayBrightness(display,
1594                     (level - 1)/(static_cast<float>(max_brightness_level - 1)));
1595         }
1596         output_parcel->writeInt32(status);
1597       }
1598       break;
1599 
1600     case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
1601       if (!input_parcel || !output_parcel) {
1602         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1603         break;
1604       }
1605       status = GetVisibleDisplayRect(input_parcel, output_parcel);
1606       break;
1607 
1608     case qService::IQService::SET_CAMERA_STATUS: {
1609         if (!input_parcel) {
1610           DLOGE("QService command = %d: input_parcel needed.", command);
1611           break;
1612         }
1613         uint32_t camera_status = UINT32(input_parcel->readInt32());
1614         status = SetCameraLaunchStatus(camera_status);
1615       }
1616       break;
1617 
1618     case qService::IQService::GET_BW_TRANSACTION_STATUS: {
1619         if (!output_parcel) {
1620           DLOGE("QService command = %d: output_parcel needed.", command);
1621           break;
1622         }
1623         bool state = true;
1624         status = DisplayBWTransactionPending(&state);
1625         output_parcel->writeInt32(state);
1626       }
1627       break;
1628 
1629     case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
1630       if (!input_parcel) {
1631         DLOGE("QService command = %d: input_parcel needed.", command);
1632         break;
1633       }
1634       status = SetMixerResolution(input_parcel);
1635       break;
1636 
1637     case qService::IQService::SET_COLOR_MODE:
1638       if (!input_parcel) {
1639         DLOGE("QService command = %d: input_parcel needed.", command);
1640         break;
1641       }
1642       status = SetColorModeOverride(input_parcel);
1643       break;
1644 
1645     case qService::IQService::SET_COLOR_MODE_WITH_RENDER_INTENT:
1646       if (!input_parcel) {
1647         DLOGE("QService command = %d: input_parcel needed.", command);
1648         break;
1649       }
1650       status = SetColorModeWithRenderIntentOverride(input_parcel);
1651       break;
1652 
1653     case qService::IQService::SET_COLOR_MODE_BY_ID:
1654       if (!input_parcel) {
1655         DLOGE("QService command = %d: input_parcel needed.", command);
1656         break;
1657       }
1658       status = SetColorModeById(input_parcel);
1659       break;
1660 
1661     case qService::IQService::GET_COMPOSER_STATUS:
1662       if (!output_parcel) {
1663         DLOGE("QService command = %d: output_parcel needed.", command);
1664         break;
1665       }
1666       status = 0;
1667       output_parcel->writeInt32(getComposerStatus());
1668       break;
1669 
1670     case qService::IQService::SET_QSYNC_MODE:
1671       if (!input_parcel) {
1672         DLOGE("QService command = %d: input_parcel needed.", command);
1673         break;
1674       }
1675       status = SetQSyncMode(input_parcel);
1676       break;
1677 
1678     case qService::IQService::SET_COLOR_SAMPLING_ENABLED:
1679       if (!input_parcel) {
1680         DLOGE("QService command = %d: input_parcel needed.", command);
1681         break;
1682       }
1683       status = setColorSamplingEnabled(input_parcel);
1684       break;
1685 
1686     case qService::IQService::SET_IDLE_PC:
1687       if (!input_parcel) {
1688         DLOGE("QService command = %d: input_parcel needed.", command);
1689         break;
1690       }
1691       status = SetIdlePC(input_parcel);
1692       break;
1693 
1694     case qService::IQService::SET_DISPLAY_DEVICE_STATUS:
1695       if (!input_parcel) {
1696         DLOGE("QService command = %d: input_parcel needed.", command);
1697         break;
1698       }
1699       status = SetDisplayDeviceStatus(input_parcel);
1700       break;
1701 
1702     case qService::IQService::SET_PANEL_GAMMA_TABLE_SOURCE:
1703       if (!input_parcel || !output_parcel) {
1704         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1705         break;
1706       }
1707       status = SetPanelGammaTableSource(input_parcel);
1708       output_parcel->writeInt32(status);
1709       break;
1710 
1711     case qService::IQService::SET_DPPS_AD4_ROI_CONFIG:
1712       if (!input_parcel) {
1713         DLOGE("QService command = %d: input_parcel needed.", command);
1714         break;
1715       }
1716       status = SetAd4RoiConfig(input_parcel);
1717       break;
1718 
1719     case qService::IQService::SET_DSI_CLK:
1720       if (!input_parcel) {
1721         DLOGE("QService command = %d: input_parcel needed.", command);
1722         break;
1723       }
1724       status = SetDsiClk(input_parcel);
1725       break;
1726 
1727     case qService::IQService::GET_DSI_CLK:
1728       if (!input_parcel || !output_parcel) {
1729         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1730         break;
1731       }
1732       status = GetDsiClk(input_parcel, output_parcel);
1733       break;
1734 
1735     case qService::IQService::GET_SUPPORTED_DSI_CLK:
1736       if (!input_parcel || !output_parcel) {
1737         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1738         break;
1739       }
1740       status = GetSupportedDsiClk(input_parcel, output_parcel);
1741       break;
1742 
1743     case qService::IQService::SET_PANEL_LUMINANCE:
1744       if (!input_parcel) {
1745         DLOGE("QService command = %d: input_parcel needed.", command);
1746         break;
1747       }
1748       status = SetPanelLuminanceAttributes(input_parcel);
1749       break;
1750 
1751     case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:
1752       if (!input_parcel) {
1753         DLOGE("QService command = %d: input_parcel needed.", command);
1754         break;
1755       }
1756       status = SetColorModeFromClient(input_parcel);
1757       break;
1758 
1759     case qService::IQService::SET_FRAME_TRIGGER_MODE:
1760       if (!input_parcel) {
1761         DLOGE("QService command = %d: input_parcel needed.", command);
1762         break;
1763       }
1764       status = SetFrameTriggerMode(input_parcel);
1765       break;
1766 
1767     case qService::IQService::SET_BRIGHTNESS_SCALE:
1768       if (!input_parcel) {
1769         DLOGE("QService command = %d: input_parcel needed.", command);
1770         break;
1771       }
1772       status = SetDisplayBrightnessScale(input_parcel);
1773       break;
1774 
1775     case qService::IQService::SET_STAND_BY_MODE:
1776       if (!input_parcel) {
1777         DLOGE("QService command = %d: input_parcel needed.", command);
1778         break;
1779       }
1780       status = SetStandByMode(input_parcel);
1781       break;
1782 
1783     case qService::IQService::GET_PANEL_RESOLUTION:
1784       if (!input_parcel || !output_parcel) {
1785         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1786         break;
1787       }
1788       status = GetPanelResolution(input_parcel, output_parcel);
1789       break;
1790 
1791     case qService::IQService::DELAY_FIRST_COMMIT:
1792       status = DelayFirstCommit();
1793       break;
1794 
1795     default:
1796       DLOGW("QService command = %d is not supported.", command);
1797       break;
1798   }
1799 
1800   return status;
1801 }
1802 
SetDisplayDeviceStatus(const android::Parcel * input_parcel)1803 android::status_t HWCSession::SetDisplayDeviceStatus(const android::Parcel *input_parcel) {
1804   int dpy = input_parcel->readInt32();
1805   int error = android::BAD_VALUE;
1806   auto disp_status = static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
1807 
1808   int disp_idx = GetDisplayIndex(dpy);
1809   if (disp_idx == -1) {
1810     DLOGE("Invalid display = %d", dpy);
1811     return android::BAD_VALUE;
1812   }
1813 
1814   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
1815   if (hwc_display_[disp_idx]) {
1816     error = hwc_display_[disp_idx]->SetDisplayStatus(disp_status);
1817     if (error != android::OK)
1818       DLOGW("Set display %d status to %d failed with error %d", dpy, disp_status, error);
1819   } else {
1820     DLOGW("No display %d active", dpy);
1821   }
1822 
1823   return error;
1824 }
1825 
SetPanelGammaTableSource(const android::Parcel * input_parcel)1826 android::status_t HWCSession::SetPanelGammaTableSource(const android::Parcel *input_parcel) {
1827   int dpy = input_parcel->readInt32();
1828   int error = android::BAD_VALUE;
1829   auto source = static_cast<HWCDisplay::PanelGammaSource>(input_parcel->readInt32());
1830 
1831   int disp_idx = GetDisplayIndex(dpy);
1832   if (disp_idx == -1) {
1833     DLOGE("Invalid display = %d", dpy);
1834     return android::BAD_VALUE;
1835   }
1836 
1837   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
1838   if (hwc_display_[disp_idx]) {
1839     error = hwc_display_[disp_idx]->SetCurrentPanelGammaSource(source);
1840     if (error != android::OK)
1841       DLOGW("Set display %d gamma source to %d failed with error %d", dpy, source, error);
1842   } else {
1843     DLOGW("No display %d active", dpy);
1844   }
1845 
1846   return error;
1847 }
1848 
getComposerStatus()1849 android::status_t HWCSession::getComposerStatus() {
1850   return is_composer_up_;
1851 }
1852 
GetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)1853 android::status_t HWCSession::GetDisplayAttributesForConfig(const android::Parcel *input_parcel,
1854                                                             android::Parcel *output_parcel) {
1855   int config = input_parcel->readInt32();
1856   int dpy = input_parcel->readInt32();
1857   int error = android::BAD_VALUE;
1858   DisplayConfigVariableInfo display_attributes;
1859 
1860   int disp_idx = GetDisplayIndex(dpy);
1861   if (disp_idx == -1 || config < 0) {
1862     DLOGE("Invalid display = %d, or config = %d", dpy, config);
1863     return android::BAD_VALUE;
1864   }
1865 
1866   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
1867   if (hwc_display_[disp_idx]) {
1868     error = hwc_display_[disp_idx]->GetDisplayAttributesForConfig(config, &display_attributes);
1869     if (error == 0) {
1870       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
1871       output_parcel->writeInt32(INT(display_attributes.x_pixels));
1872       output_parcel->writeInt32(INT(display_attributes.y_pixels));
1873       output_parcel->writeFloat(display_attributes.x_dpi);
1874       output_parcel->writeFloat(display_attributes.y_dpi);
1875       output_parcel->writeInt32(0);  // Panel type, unsupported.
1876     }
1877   }
1878 
1879   return error;
1880 }
1881 
setColorSamplingEnabled(const android::Parcel * input_parcel)1882 android::status_t HWCSession::setColorSamplingEnabled(const android::Parcel *input_parcel) {
1883   int dpy = input_parcel->readInt32();
1884   int enabled_cmd = input_parcel->readInt32();
1885   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || enabled_cmd < 0 ||
1886       enabled_cmd > 1) {
1887     return android::BAD_VALUE;
1888   }
1889 
1890   SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1891   if (!hwc_display_[dpy]) {
1892     DLOGW("No display id %i active to enable histogram event", dpy);
1893     return android::BAD_VALUE;
1894   }
1895 
1896   auto error = hwc_display_[dpy]->SetDisplayedContentSamplingEnabledVndService(enabled_cmd);
1897   return (error == HWC2::Error::None) ? android::OK : android::BAD_VALUE;
1898 }
1899 
ConfigureRefreshRate(const android::Parcel * input_parcel)1900 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
1901   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1902 
1903   uint32_t operation = UINT32(input_parcel->readInt32());
1904   HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
1905 
1906   if (!hwc_display) {
1907     DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1908     return -ENODEV;
1909   }
1910 
1911   switch (operation) {
1912     case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
1913       return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, false);
1914 
1915     case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
1916       return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, true);
1917 
1918     case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
1919       uint32_t refresh_rate = UINT32(input_parcel->readInt32());
1920       return hwc_display->Perform(HWCDisplayBuiltIn::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
1921     }
1922 
1923     default:
1924       DLOGW("Invalid operation %d", operation);
1925       return -EINVAL;
1926   }
1927 
1928   return 0;
1929 }
1930 
SetDisplayMode(const android::Parcel * input_parcel)1931 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
1932   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1933 
1934   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1935     DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1936     return -ENODEV;
1937   }
1938 
1939   uint32_t mode = UINT32(input_parcel->readInt32());
1940   return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayBuiltIn::SET_DISPLAY_MODE, mode);
1941 }
1942 
SetMaxMixerStages(const android::Parcel * input_parcel)1943 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
1944   DisplayError error = kErrorNone;
1945   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1946   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
1947   android::status_t status = 0;
1948 
1949   for (uint32_t i = 0; i < 32 && bit_mask_display_type[i]; i++) {
1950     int disp_idx = GetDisplayIndex(INT(i));
1951     if (disp_idx == -1) {
1952       continue;
1953     }
1954     SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
1955     auto &hwc_display = hwc_display_[disp_idx];
1956     if (!hwc_display) {
1957       DLOGW("Display = %d is not connected.", disp_idx);
1958       status = (status)? status : -ENODEV;  // Return higher priority error.
1959       continue;
1960     }
1961 
1962     error = hwc_display->SetMaxMixerStages(max_mixer_stages);
1963     if (error != kErrorNone) {
1964       status = -EINVAL;
1965     }
1966   }
1967 
1968   return status;
1969 }
1970 
SetFrameDumpConfig(const android::Parcel * input_parcel)1971 android::status_t HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
1972   uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
1973   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1974   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
1975   int32_t output_format = HAL_PIXEL_FORMAT_RGB_888;
1976   bool post_processed = true;
1977 
1978   // Output buffer dump is not supported, if External or Virtual display is present.
1979   bool output_buffer_dump = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
1980   if (output_buffer_dump) {
1981     int external_dpy_index = GetDisplayIndex(qdutils::DISPLAY_EXTERNAL);
1982     int virtual_dpy_index = GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
1983     if (((external_dpy_index != -1) && hwc_display_[external_dpy_index]) ||
1984         ((virtual_dpy_index != -1) && hwc_display_[virtual_dpy_index])) {
1985       DLOGW("Output buffer dump is not supported with External or Virtual display!");
1986       return -EINVAL;
1987     }
1988   }
1989 
1990   // Read optional user preferences: output_format and post_processed.
1991   if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1992     // HAL Pixel Format for output buffer
1993     output_format = input_parcel->readInt32();
1994   }
1995   if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1996     // Option to dump Layer Mixer output (0) or DSPP output (1)
1997     post_processed = (input_parcel->readInt32() != 0);
1998   }
1999 
2000   android::status_t status = 0;
2001 
2002   for (uint32_t i = 0; i < bit_mask_display_type.size(); i++) {
2003     if (!bit_mask_display_type[i]) {
2004       continue;
2005     }
2006     int disp_idx = GetDisplayIndex(INT(i));
2007     if (disp_idx == -1) {
2008       continue;
2009     }
2010     SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2011     auto &hwc_display = hwc_display_[disp_idx];
2012     if (!hwc_display) {
2013       DLOGW("Display = %d is not connected.", disp_idx);
2014       status = (status)? status : -ENODEV;  // Return higher priority error.
2015       continue;
2016     }
2017 
2018     HWC2::Error error = hwc_display->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type,
2019                                                         output_format, post_processed);
2020     if (error != HWC2::Error::None) {
2021       status = (HWC2::Error::NoResources == error) ? -ENOMEM : -EINVAL;
2022     }
2023   }
2024 
2025   return status;
2026 }
2027 
SetMixerResolution(const android::Parcel * input_parcel)2028 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
2029   DisplayError error = kErrorNone;
2030   uint32_t dpy = UINT32(input_parcel->readInt32());
2031 
2032   if (dpy != HWC_DISPLAY_PRIMARY) {
2033     DLOGW("Resolution change not supported for this display = %d", dpy);
2034     return -EINVAL;
2035   }
2036 
2037   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2038   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2039     DLOGW("Primary display is not initialized");
2040     return -ENODEV;
2041   }
2042 
2043   uint32_t width = UINT32(input_parcel->readInt32());
2044   uint32_t height = UINT32(input_parcel->readInt32());
2045 
2046   error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
2047   if (error != kErrorNone) {
2048     return -EINVAL;
2049   }
2050 
2051   return 0;
2052 }
2053 
SetColorModeOverride(const android::Parcel * input_parcel)2054 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
2055   int display = static_cast<int>(input_parcel->readInt32());
2056   auto mode = static_cast<ColorMode>(input_parcel->readInt32());
2057 
2058   int disp_idx = GetDisplayIndex(display);
2059   if (disp_idx == -1) {
2060     DLOGE("Invalid display = %d", display);
2061     return -EINVAL;
2062   }
2063 
2064   if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
2065     DLOGE("Invalid ColorMode: %d", mode);
2066     return HWC2_ERROR_BAD_PARAMETER;
2067   }
2068   auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx), &HWCDisplay::SetColorMode,
2069                                  mode);
2070   if (err != HWC2_ERROR_NONE)
2071     return -EINVAL;
2072 
2073   return 0;
2074 }
2075 
SetAd4RoiConfig(const android::Parcel * input_parcel)2076 android::status_t HWCSession::SetAd4RoiConfig(const android::Parcel *input_parcel) {
2077   auto display_id = static_cast<uint32_t>(input_parcel->readInt32());
2078   auto h_s = static_cast<uint32_t>(input_parcel->readInt32());
2079   auto h_e = static_cast<uint32_t>(input_parcel->readInt32());
2080   auto v_s = static_cast<uint32_t>(input_parcel->readInt32());
2081   auto v_e = static_cast<uint32_t>(input_parcel->readInt32());
2082   auto f_in = static_cast<uint32_t>(input_parcel->readInt32());
2083   auto f_out = static_cast<uint32_t>(input_parcel->readInt32());
2084 
2085   return static_cast<android::status_t>(SetDisplayDppsAdROI(display_id, h_s, h_e, v_s,
2086                                                             v_e, f_in, f_out));
2087 }
2088 
SetFrameTriggerMode(const android::Parcel * input_parcel)2089 android::status_t HWCSession::SetFrameTriggerMode(const android::Parcel *input_parcel) {
2090   auto display_id = static_cast<int>(input_parcel->readInt32());
2091   auto mode = static_cast<uint32_t>(input_parcel->readInt32());
2092 
2093   int disp_idx = GetDisplayIndex(display_id);
2094   if (disp_idx == -1) {
2095     DLOGE("Invalid display = %d", display_id);
2096     return -EINVAL;
2097   }
2098 
2099   auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx),
2100                                  &HWCDisplay::SetFrameTriggerMode, mode);
2101   if (err != HWC2_ERROR_NONE)
2102     return -EINVAL;
2103 
2104   return 0;
2105 }
2106 
SetColorModeWithRenderIntentOverride(const android::Parcel * input_parcel)2107 android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
2108     const android::Parcel *input_parcel) {
2109   auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
2110   auto mode = static_cast<ColorMode>(input_parcel->readInt32());
2111   auto int_intent = static_cast<int>(input_parcel->readInt32());
2112 
2113   if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
2114     DLOGE("Invalid ColorMode: %d", mode);
2115     return HWC2_ERROR_BAD_PARAMETER;
2116   }
2117 
2118   if ((int_intent < 0) || (int_intent > MAX_EXTENDED_RENDER_INTENT)) {
2119     DLOGE("Invalid RenderIntent: %d", int_intent);
2120     return HWC2_ERROR_BAD_PARAMETER;
2121   }
2122 
2123   auto intent = static_cast<RenderIntent>(int_intent);
2124   auto err =
2125       CallDisplayFunction(display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
2126   if (err != HWC2_ERROR_NONE)
2127     return -EINVAL;
2128 
2129   return 0;
2130 }
SetColorModeById(const android::Parcel * input_parcel)2131 android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
2132   int display = input_parcel->readInt32();
2133   auto mode = input_parcel->readInt32();
2134 
2135   int disp_idx = GetDisplayIndex(display);
2136   if (disp_idx == -1) {
2137     DLOGE("Invalid display = %d", display);
2138     return -EINVAL;
2139   }
2140 
2141   auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx),
2142                                  &HWCDisplay::SetColorModeById, mode);
2143   if (err != HWC2_ERROR_NONE)
2144     return -EINVAL;
2145 
2146   return 0;
2147 }
2148 
SetColorModeFromClient(const android::Parcel * input_parcel)2149 android::status_t HWCSession::SetColorModeFromClient(const android::Parcel *input_parcel) {
2150   int display = input_parcel->readInt32();
2151   auto mode = input_parcel->readInt32();
2152 
2153   int disp_idx = GetDisplayIndex(display);
2154   if (disp_idx == -1) {
2155     DLOGE("Invalid display = %d", display);
2156     return -EINVAL;
2157   }
2158 
2159   auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx),
2160                                  &HWCDisplay::SetColorModeFromClientApi, mode);
2161   if (err != HWC2_ERROR_NONE)
2162     return -EINVAL;
2163 
2164   callbacks_.Refresh(static_cast<hwc2_display_t>(disp_idx));
2165 
2166   return 0;
2167 }
2168 
RefreshScreen(const android::Parcel * input_parcel)2169 android::status_t HWCSession::RefreshScreen(const android::Parcel *input_parcel) {
2170   int display = input_parcel->readInt32();
2171 
2172   int disp_idx = GetDisplayIndex(display);
2173   if (disp_idx == -1) {
2174     DLOGE("Invalid display = %d", display);
2175     return -EINVAL;
2176   }
2177 
2178   callbacks_.Refresh(static_cast<hwc2_display_t>(disp_idx));
2179 
2180   return 0;
2181 }
2182 
DynamicDebug(const android::Parcel * input_parcel)2183 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
2184   int type = input_parcel->readInt32();
2185   bool enable = (input_parcel->readInt32() > 0);
2186   DLOGI("type = %d enable = %d", type, enable);
2187   int verbose_level = input_parcel->readInt32();
2188 
2189   switch (type) {
2190     case qService::IQService::DEBUG_ALL:
2191       HWCDebugHandler::DebugAll(enable, verbose_level);
2192       break;
2193 
2194     case qService::IQService::DEBUG_MDPCOMP:
2195       HWCDebugHandler::DebugStrategy(enable, verbose_level);
2196       HWCDebugHandler::DebugCompManager(enable, verbose_level);
2197       break;
2198 
2199     case qService::IQService::DEBUG_PIPE_LIFECYCLE:
2200       HWCDebugHandler::DebugResources(enable, verbose_level);
2201       HWCDebugHandler::DebugQos(enable, verbose_level);
2202       break;
2203 
2204     case qService::IQService::DEBUG_DRIVER_CONFIG:
2205       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
2206       break;
2207 
2208     case qService::IQService::DEBUG_ROTATOR:
2209       HWCDebugHandler::DebugResources(enable, verbose_level);
2210       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
2211       HWCDebugHandler::DebugRotator(enable, verbose_level);
2212       HWCDebugHandler::DebugQos(enable, verbose_level);
2213       break;
2214 
2215     case qService::IQService::DEBUG_QDCM:
2216       HWCDebugHandler::DebugQdcm(enable, verbose_level);
2217       break;
2218 
2219     case qService::IQService::DEBUG_SCALAR:
2220       HWCDebugHandler::DebugScalar(enable, verbose_level);
2221       break;
2222 
2223     case qService::IQService::DEBUG_CLIENT:
2224       HWCDebugHandler::DebugClient(enable, verbose_level);
2225       break;
2226 
2227     case qService::IQService::DEBUG_DISPLAY:
2228       HWCDebugHandler::DebugDisplay(enable, verbose_level);
2229       break;
2230 
2231     default:
2232       DLOGW("type = %d is not supported", type);
2233   }
2234 }
2235 
QdcmCMDDispatch(uint32_t display_id,const PPDisplayAPIPayload & req_payload,PPDisplayAPIPayload * resp_payload,PPPendingParams * pending_action)2236 android::status_t HWCSession::QdcmCMDDispatch(uint32_t display_id,
2237                                               const PPDisplayAPIPayload &req_payload,
2238                                               PPDisplayAPIPayload *resp_payload,
2239                                               PPPendingParams *pending_action) {
2240   int ret = 0;
2241   bool is_physical_display = false;
2242 
2243   if (display_id >= HWCCallbacks::kNumDisplays || !hwc_display_[display_id]) {
2244       DLOGW("Invalid display id or display = %d is not connected.", display_id);
2245       return -ENODEV;
2246   }
2247 
2248   if (display_id == map_info_primary_.client_id) {
2249     is_physical_display = true;
2250   } else {
2251     for (auto &map_info : map_info_builtin_) {
2252       if (map_info.client_id == display_id) {
2253         is_physical_display = true;
2254         break;
2255      }
2256     }
2257   }
2258 
2259   if (!is_physical_display) {
2260     DLOGW("Skipping QDCM command dispatch on display = %d", display_id);
2261     return ret;
2262   }
2263 
2264   ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, resp_payload, pending_action);
2265 
2266   return ret;
2267 }
2268 
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)2269 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
2270                                              android::Parcel *output_parcel) {
2271   int ret = 0;
2272   float *brightness = NULL;
2273   uint32_t display_id(0);
2274   PPPendingParams pending_action;
2275   PPDisplayAPIPayload resp_payload, req_payload;
2276   uint8_t *disp_id = NULL;
2277   int32_t *mode_id = NULL;
2278 
2279   if (!color_mgr_) {
2280     DLOGW("color_mgr_ not initialized.");
2281     return -ENOENT;
2282   }
2283 
2284   pending_action.action = kNoAction;
2285   pending_action.params = NULL;
2286 
2287   // Read display_id, payload_size and payload from in_parcel.
2288   ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
2289   if (!ret) {
2290     ret = QdcmCMDDispatch(display_id, req_payload, &resp_payload, &pending_action);
2291   }
2292 
2293   if (ret) {
2294     output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
2295     req_payload.DestroyPayload();
2296     resp_payload.DestroyPayload();
2297     return ret;
2298   }
2299 
2300   if (kNoAction != pending_action.action) {
2301     int32_t action = pending_action.action;
2302     int count = -1;
2303     while (action > 0) {
2304       count++;
2305       int32_t bit = (action & 1);
2306       action = action >> 1;
2307 
2308       if (!bit)
2309         continue;
2310 
2311       DLOGV_IF(kTagQDCM, "pending action = %d, display_id = %d", BITMAP(count), display_id);
2312       switch (BITMAP(count)) {
2313         case kInvalidating:
2314           callbacks_.Refresh(display_id);
2315           break;
2316         case kEnterQDCMMode:
2317           ret = color_mgr_->EnableQDCMMode(true, hwc_display_[display_id]);
2318           break;
2319         case kExitQDCMMode:
2320           ret = color_mgr_->EnableQDCMMode(false, hwc_display_[display_id]);
2321           break;
2322         case kApplySolidFill:
2323           {
2324             SCOPE_LOCK(locker_[display_id]);
2325             ret = color_mgr_->SetSolidFill(pending_action.params,
2326                                            true, hwc_display_[display_id]);
2327           }
2328           callbacks_.Refresh(display_id);
2329           usleep(kSolidFillDelay);
2330           break;
2331         case kDisableSolidFill:
2332           {
2333             SCOPE_LOCK(locker_[display_id]);
2334             ret = color_mgr_->SetSolidFill(pending_action.params,
2335                                            false, hwc_display_[display_id]);
2336           }
2337           callbacks_.Refresh(display_id);
2338           usleep(kSolidFillDelay);
2339           break;
2340         case kSetPanelBrightness:
2341           ret = -EINVAL;
2342           brightness = reinterpret_cast<float *>(resp_payload.payload);
2343           if (brightness == NULL) {
2344             DLOGE("Brightness payload is Null");
2345           } else {
2346             ret = INT(SetDisplayBrightness(static_cast<hwc2_display_t>(display_id), *brightness));
2347           }
2348           break;
2349         case kEnableFrameCapture:
2350           ret = color_mgr_->SetFrameCapture(pending_action.params, true, hwc_display_[display_id]);
2351           callbacks_.Refresh(display_id);
2352           break;
2353         case kDisableFrameCapture:
2354           ret = color_mgr_->SetFrameCapture(pending_action.params, false,
2355                                             hwc_display_[display_id]);
2356           break;
2357         case kConfigureDetailedEnhancer:
2358           ret = color_mgr_->SetDetailedEnhancer(pending_action.params, hwc_display_[display_id]);
2359           callbacks_.Refresh(display_id);
2360           break;
2361         case kModeSet:
2362           ret = static_cast<int>
2363                   (hwc_display_[display_id]->RestoreColorTransform());
2364           callbacks_.Refresh(display_id);
2365           break;
2366         case kNoAction:
2367           break;
2368         case kMultiDispProc:
2369           for (auto &map_info : map_info_builtin_) {
2370             uint32_t id = UINT32(map_info.client_id);
2371             if (id < HWCCallbacks::kNumDisplays && hwc_display_[id]) {
2372               int result = 0;
2373               resp_payload.DestroyPayload();
2374               result = hwc_display_[id]->ColorSVCRequestRoute(req_payload, &resp_payload,
2375                                                               &pending_action);
2376               if (result) {
2377                 DLOGW("Failed to dispatch action to disp %d ret %d", id, result);
2378                 ret = result;
2379               }
2380             }
2381           }
2382           break;
2383         case kMultiDispGetId:
2384           ret = resp_payload.CreatePayloadBytes(HWCCallbacks::kNumDisplays, &disp_id);
2385           if (ret) {
2386             DLOGW("Unable to create response payload!");
2387           } else {
2388             for (int i = 0; i < HWCCallbacks::kNumDisplays; i++) {
2389               disp_id[i] = HWCCallbacks::kNumDisplays;
2390             }
2391             if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2392               disp_id[HWC_DISPLAY_PRIMARY] = HWC_DISPLAY_PRIMARY;
2393             }
2394             for (auto &map_info : map_info_builtin_) {
2395               uint64_t id = map_info.client_id;
2396               if (id < HWCCallbacks::kNumDisplays && hwc_display_[id]) {
2397                 disp_id[id] = (uint8_t)id;
2398               }
2399             }
2400           }
2401           break;
2402         case kSetModeFromClient:
2403           {
2404             SCOPE_LOCK(locker_[display_id]);
2405             mode_id = reinterpret_cast<int32_t *>(resp_payload.payload);
2406             if (mode_id) {
2407               ret = static_cast<int>(hwc_display_[display_id]->SetColorModeFromClientApi(*mode_id));
2408             } else {
2409               DLOGE("mode_id is Null");
2410               ret = -EINVAL;
2411             }
2412           }
2413           if (!ret) {
2414             callbacks_.Refresh(display_id);
2415           }
2416           break;
2417         default:
2418           DLOGW("Invalid pending action = %d!", pending_action.action);
2419           break;
2420       }
2421     }
2422   }
2423   // for display API getter case, marshall returned params into out_parcel.
2424   output_parcel->writeInt32(ret);
2425   HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
2426   req_payload.DestroyPayload();
2427   resp_payload.DestroyPayload();
2428 
2429   SEQUENCE_WAIT_SCOPE_LOCK(locker_[display_id]);
2430   hwc_display_[display_id]->ResetValidation();
2431 
2432   return ret;
2433 }
2434 
GetEventValue(const char * uevent_data,int length,const char * event_info)2435 int GetEventValue(const char *uevent_data, int length, const char *event_info) {
2436   const char *iterator_str = uevent_data;
2437   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2438     const char *pstr = strstr(iterator_str, event_info);
2439     if (pstr != NULL) {
2440       return (atoi(iterator_str + strlen(event_info)));
2441     }
2442     iterator_str += strlen(iterator_str) + 1;
2443   }
2444 
2445   return -1;
2446 }
2447 
GetTokenValue(const char * uevent_data,int length,const char * token)2448 const char *GetTokenValue(const char *uevent_data, int length, const char *token) {
2449   const char *iterator_str = uevent_data;
2450   const char *pstr = NULL;
2451   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2452     pstr = strstr(iterator_str, token);
2453     if (pstr) {
2454       break;
2455     }
2456     iterator_str += strlen(iterator_str) + 1;
2457   }
2458 
2459   if (pstr)
2460     pstr = pstr+strlen(token);
2461 
2462   return pstr;
2463 }
2464 
SetDsiClk(const android::Parcel * input_parcel)2465 android::status_t HWCSession::SetDsiClk(const android::Parcel *input_parcel) {
2466   int disp_id = input_parcel->readInt32();
2467   uint64_t clk = UINT64(input_parcel->readInt64());
2468   if (disp_id != HWC_DISPLAY_PRIMARY) {
2469     return -EINVAL;
2470   }
2471 
2472   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
2473   if (!hwc_display_[disp_id]) {
2474     return -EINVAL;
2475   }
2476 
2477   return hwc_display_[disp_id]->SetDynamicDSIClock(clk);
2478 }
2479 
GetDsiClk(const android::Parcel * input_parcel,android::Parcel * output_parcel)2480 android::status_t HWCSession::GetDsiClk(const android::Parcel *input_parcel,
2481                                         android::Parcel *output_parcel) {
2482   int disp_id = input_parcel->readInt32();
2483   if (disp_id != HWC_DISPLAY_PRIMARY) {
2484     return -EINVAL;
2485   }
2486 
2487   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
2488   if (!hwc_display_[disp_id]) {
2489     return -EINVAL;
2490   }
2491 
2492   uint64_t bitrate = 0;
2493   hwc_display_[disp_id]->GetDynamicDSIClock(&bitrate);
2494   output_parcel->writeUint64(bitrate);
2495 
2496   return 0;
2497 }
2498 
GetSupportedDsiClk(const android::Parcel * input_parcel,android::Parcel * output_parcel)2499 android::status_t HWCSession::GetSupportedDsiClk(const android::Parcel *input_parcel,
2500                                                  android::Parcel *output_parcel) {
2501   int disp_id = input_parcel->readInt32();
2502   if (disp_id != HWC_DISPLAY_PRIMARY) {
2503     return -EINVAL;
2504   }
2505 
2506   SCOPE_LOCK(locker_[disp_id]);
2507   if (!hwc_display_[disp_id]) {
2508     return -EINVAL;
2509   }
2510 
2511   std::vector<uint64_t> bit_rates;
2512   hwc_display_[disp_id]->GetSupportedDSIClock(&bit_rates);
2513   output_parcel->writeInt32(INT32(bit_rates.size()));
2514   for (auto &bit_rate : bit_rates) {
2515     output_parcel->writeUint64(bit_rate);
2516   }
2517 
2518   return 0;
2519 }
2520 
SetPanelLuminanceAttributes(const android::Parcel * input_parcel)2521 android::status_t HWCSession::SetPanelLuminanceAttributes(const android::Parcel *input_parcel) {
2522   int disp_id = input_parcel->readInt32();
2523 
2524   // currently doing only for virtual display
2525   if (disp_id != qdutils::DISPLAY_VIRTUAL) {
2526     return -EINVAL;
2527   }
2528 
2529   float min_lum = input_parcel->readFloat();
2530   float max_lum = input_parcel->readFloat();
2531 
2532   // check for out of range luminance values
2533   if (min_lum <= 0.0f || min_lum >= 1.0f || max_lum <= 100.0f || max_lum >= 1000.0f) {
2534     return -EINVAL;
2535   }
2536 
2537   std::lock_guard<std::mutex> obj(mutex_lum_);
2538   set_min_lum_ = min_lum;
2539   set_max_lum_ = max_lum;
2540   DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_);
2541 
2542   return 0;
2543 }
2544 
UEventHandler(const char * uevent_data,int length)2545 void HWCSession::UEventHandler(const char *uevent_data, int length) {
2546   // Drop hotplug uevents until SurfaceFlinger (the client) is connected. The equivalent of hotplug
2547   // uevent handling will be done once when SurfaceFlinger connects, at RegisterCallback(). Since
2548   // HandlePluggableDisplays() reads the latest connection states of all displays, no uevent is
2549   // lost.
2550   if (callbacks_.IsClientConnected() && strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
2551     // MST hotplug will not carry connection status/test pattern etc.
2552     // Pluggable display handler will check all connection status' and take action accordingly.
2553     const char *str_status = GetTokenValue(uevent_data, length, "status=");
2554     const char *str_mst = GetTokenValue(uevent_data, length, "MST_HOTPLUG=");
2555     if (!str_status && !str_mst) {
2556       return;
2557     }
2558 
2559     hpd_bpp_ = GetEventValue(uevent_data, length, "bpp=");
2560     hpd_pattern_ = GetEventValue(uevent_data, length, "pattern=");
2561     DLOGI("Uevent = %s, status = %s, MST_HOTPLUG = %s, bpp = %d, pattern = %d", uevent_data,
2562           str_status ? str_status : "NULL", str_mst ? str_mst : "NULL", hpd_bpp_, hpd_pattern_);
2563 
2564     hwc2_display_t virtual_display_index =
2565         (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
2566 
2567     std::bitset<kSecureMax> secure_sessions = 0;
2568     hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
2569     if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
2570       Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
2571       hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
2572     }
2573     if (secure_sessions[kSecureDisplay] || hwc_display_[virtual_display_index]) {
2574       // Defer hotplug handling.
2575       SCOPE_LOCK(pluggable_handler_lock_);
2576       DLOGI("Marking hotplug pending...");
2577       pending_hotplug_event_ = kHotPlugEvent;
2578     } else {
2579       // Handle hotplug.
2580       int32_t err = HandlePluggableDisplays(true);
2581       if (err) {
2582         DLOGW("Hotplug handling failed. Error %d '%s'. Hotplug handling %s.", err,
2583               strerror(abs(err)), (pending_hotplug_event_ == kHotPlugEvent) ?
2584               "deferred" : "dropped");
2585       }
2586     }
2587 
2588     if (str_status) {
2589       bool connected = (strncmp(str_status, "connected", strlen("connected")) == 0);
2590       DLOGI("Connected = %d", connected);
2591       // Pass on legacy HDMI hot-plug event.
2592       qservice_->onHdmiHotplug(INT(connected));
2593     }
2594   }
2595 }
2596 
GetVsyncPeriod(hwc2_display_t disp,uint32_t * vsync_period)2597 int32_t HWCSession::GetVsyncPeriod(hwc2_display_t disp, uint32_t *vsync_period) {
2598   if (disp >= HWCCallbacks::kNumDisplays) {
2599     DLOGW("Invalid Display : display = %" PRIu64, disp);
2600     return HWC2_ERROR_BAD_DISPLAY;
2601   }
2602 
2603   SCOPE_LOCK(locker_[(int)disp]);
2604   // default value
2605   *vsync_period = 1000000000ul / 60;
2606 
2607   if (hwc_display_[disp]) {
2608     hwc_display_[disp]->GetDisplayAttribute(0, HwcAttribute::VSYNC_PERIOD, (int32_t *)vsync_period);
2609   }
2610 
2611   return HWC2_ERROR_NONE;
2612 }
2613 
Refresh(hwc2_display_t display)2614 void HWCSession::Refresh(hwc2_display_t display) {
2615   callbacks_.Refresh(display);
2616 }
2617 
GetPanelResolution(const android::Parcel * input_parcel,android::Parcel * output_parcel)2618 android::status_t HWCSession::GetPanelResolution(const android::Parcel *input_parcel,
2619                                                  android::Parcel *output_parcel) {
2620   SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2621 
2622   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2623     DLOGI("Primary display is not initialized");
2624     return -EINVAL;
2625   }
2626   auto panel_width = 0u;
2627   auto panel_height = 0u;
2628 
2629   hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelResolution(&panel_width, &panel_height);
2630   output_parcel->writeInt32(INT32(panel_width));
2631   output_parcel->writeInt32(INT32(panel_height));
2632 
2633   return android::NO_ERROR;
2634 }
2635 
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)2636 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
2637                                                     android::Parcel *output_parcel) {
2638   int disp_idx = GetDisplayIndex(input_parcel->readInt32());
2639   if (disp_idx == -1) {
2640     DLOGE("Invalid display = %d", disp_idx);
2641     return android::BAD_VALUE;
2642   }
2643 
2644   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2645   if (!hwc_display_[disp_idx]) {
2646     return android::NO_INIT;
2647   }
2648 
2649   hwc_rect_t visible_rect = {0, 0, 0, 0};
2650   int error = hwc_display_[disp_idx]->GetVisibleDisplayRect(&visible_rect);
2651   if (error < 0) {
2652     return error;
2653   }
2654 
2655   output_parcel->writeInt32(visible_rect.left);
2656   output_parcel->writeInt32(visible_rect.top);
2657   output_parcel->writeInt32(visible_rect.right);
2658   output_parcel->writeInt32(visible_rect.bottom);
2659 
2660   return android::NO_ERROR;
2661 }
2662 
SetStandByMode(const android::Parcel * input_parcel)2663 android::status_t HWCSession::SetStandByMode(const android::Parcel *input_parcel) {
2664   SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2665 
2666   bool enable = (input_parcel->readInt32() > 0);
2667   bool is_twm = (input_parcel->readInt32() > 0);
2668 
2669   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2670     DLOGI("Primary display is not initialized");
2671     return -EINVAL;
2672   }
2673 
2674   DisplayError error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetStandByMode(enable, is_twm);
2675   if (error != kErrorNone) {
2676     DLOGE("SetStandByMode failed. Error = %d", error);
2677     return -EINVAL;
2678   }
2679 
2680   return android::NO_ERROR;
2681 }
2682 
DelayFirstCommit()2683 android::status_t HWCSession::DelayFirstCommit() {
2684   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2685     DLOGI("Primary display is not initialized");
2686     return -EINVAL;
2687   }
2688 
2689   return hwc_display_[HWC_DISPLAY_PRIMARY]->DelayFirstCommit();
2690 }
2691 
CreatePrimaryDisplay()2692 int HWCSession::CreatePrimaryDisplay() {
2693   int status = -EINVAL;
2694   HWDisplaysInfo hw_displays_info = {};
2695 
2696   if (null_display_mode_) {
2697     HWDisplayInfo hw_info = {};
2698     hw_info.display_type = kBuiltIn;
2699     hw_info.is_connected = 1;
2700     hw_info.is_primary = 1;
2701     hw_info.is_wb_ubwc_supported = 0;
2702     hw_info.display_id = 1;
2703     hw_displays_info[hw_info.display_id] = hw_info;
2704   } else {
2705     DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
2706     if (error != kErrorNone) {
2707       DLOGE("Failed to get connected display list. Error = %d", error);
2708       return status;
2709     }
2710   }
2711 
2712   for (auto &iter : hw_displays_info) {
2713     auto &info = iter.second;
2714     if (!info.is_primary) {
2715       continue;
2716     }
2717 
2718     // todo (user): If primary display is not connected (e.g. hdmi as primary), a NULL display
2719     // need to be created. SF expects primary display hotplug during callback registration unlike
2720     // previous implementation where first hotplug could be notified anytime.
2721     if (!info.is_connected) {
2722       DLOGE("Primary display is not connected. Not supported at present.");
2723       break;
2724     }
2725 
2726     auto hwc_display = &hwc_display_[HWC_DISPLAY_PRIMARY];
2727     hwc2_display_t client_id = map_info_primary_.client_id;
2728 
2729     if (info.display_type == kBuiltIn) {
2730       status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
2731                                          qservice_, client_id, info.display_id, hwc_display);
2732     } else if (info.display_type == kPluggable) {
2733       status = HWCDisplayPluggable::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
2734                                            qservice_, client_id, info.display_id, 0, 0, false,
2735                                            hwc_display);
2736     } else {
2737       DLOGE("Spurious primary display type = %d", info.display_type);
2738       break;
2739     }
2740 
2741     if (!status) {
2742       DLOGI("Created primary display type = %d, sdm id = %d, client id = %d", info.display_type,
2743              info.display_id, UINT32(client_id));
2744       {
2745          SCOPE_LOCK(hdr_locker_[client_id]);
2746          is_hdr_display_[UINT32(client_id)] = HasHDRSupport(*hwc_display);
2747       }
2748 
2749       map_info_primary_.disp_type = info.display_type;
2750       map_info_primary_.sdm_id = info.display_id;
2751       CreateDummyDisplay(HWC_DISPLAY_PRIMARY);
2752       color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
2753       if (!color_mgr_) {
2754         DLOGW("Failed to load HWCColorManager.");
2755       }
2756     } else {
2757       DLOGE("Primary display creation has failed! status = %d", status);
2758     }
2759 
2760     // Primary display is found, no need to parse more.
2761     break;
2762   }
2763 
2764   return status;
2765 }
2766 
CreateDummyDisplay(hwc2_display_t client_id)2767 void HWCSession::CreateDummyDisplay(hwc2_display_t client_id) {
2768   if (!async_powermode_) {
2769     return;
2770   }
2771 
2772   hwc2_display_t dummy_disp_id = map_hwc_display_.find(client_id)->second;
2773   auto hwc_display_dummy = &hwc_display_[dummy_disp_id];
2774   HWCDisplayDummy::Create(core_intf_, &buffer_allocator_, &callbacks_, this, qservice_,
2775                     0, 0, hwc_display_dummy);
2776   if (!*hwc_display_dummy) {
2777     DLOGE("Dummy display creation failed for %d display\n", UINT32(client_id));
2778   }
2779 }
2780 
HandleBuiltInDisplays()2781 int HWCSession::HandleBuiltInDisplays() {
2782   if (null_display_mode_) {
2783     DLOGW("Skipped BuiltIn display handling in null-display mode");
2784     return 0;
2785   }
2786 
2787   HWDisplaysInfo hw_displays_info = {};
2788   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
2789   if (error != kErrorNone) {
2790     DLOGE("Failed to get connected display list. Error = %d", error);
2791     return -EINVAL;
2792   }
2793 
2794   int status = 0;
2795   for (auto &iter : hw_displays_info) {
2796     auto &info = iter.second;
2797 
2798     // Do not recreate primary display.
2799     if (info.is_primary || info.display_type != kBuiltIn) {
2800       continue;
2801     }
2802 
2803     for (auto &map_info : map_info_builtin_) {
2804       hwc2_display_t client_id = map_info.client_id;
2805 
2806       {
2807         SCOPE_LOCK(locker_[client_id]);
2808         // Lock confined to this scope
2809         if (hwc_display_[client_id]) {
2810           continue;
2811         }
2812 
2813         DLOGI("Create builtin display, sdm id = %d, client id = %d", info.display_id,
2814               UINT32(client_id));
2815         status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
2816                                            qservice_, client_id, info.display_id,
2817                                            &hwc_display_[client_id]);
2818         if (status) {
2819           DLOGE("Builtin display creation failed.");
2820           break;
2821         }
2822 
2823         {
2824           SCOPE_LOCK(hdr_locker_[client_id]);
2825           is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display_[client_id]);
2826         }
2827 
2828         DLOGI("Builtin display created: sdm id = %d, client id = %d", info.display_id,
2829               UINT32(client_id));
2830         map_info.disp_type = info.display_type;
2831         map_info.sdm_id = info.display_id;
2832         CreateDummyDisplay(client_id);
2833       }
2834 
2835       DLOGI("Hotplugging builtin display, sdm id = %d, client id = %d", info.display_id,
2836             UINT32(client_id));
2837       callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
2838       break;
2839     }
2840   }
2841 
2842   return status;
2843 }
2844 
HandlePluggableDisplays(bool delay_hotplug)2845 int HWCSession::HandlePluggableDisplays(bool delay_hotplug) {
2846   SCOPE_LOCK(pluggable_handler_lock_);
2847   if (null_display_mode_) {
2848     DLOGW("Skipped pluggable display handling in null-display mode");
2849     return 0;
2850   }
2851 
2852   DLOGI("Handling hotplug...");
2853   HWDisplaysInfo hw_displays_info = {};
2854   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
2855   if (error != kErrorNone) {
2856     DLOGE("Failed to get connected display list. Error = %d", error);
2857     return -EINVAL;
2858   }
2859 
2860   int status = HandleDisconnectedDisplays(&hw_displays_info);
2861   if (status) {
2862     DLOGE("All displays could not be disconnected.");
2863     return status;
2864   }
2865 
2866   status = HandleConnectedDisplays(&hw_displays_info, delay_hotplug);
2867   if (status) {
2868     switch (status) {
2869       case -EAGAIN:
2870       case -ENODEV:
2871         // Errors like device removal or deferral for which we want to try another hotplug handling.
2872         pending_hotplug_event_ = kHotPlugEvent;
2873         status = 0;
2874         break;
2875       default:
2876         // Real errors we want to flag and stop hotplug handling.
2877         pending_hotplug_event_ = kHotPlugNone;
2878         DLOGE("All displays could not be connected. Error %d '%s'.", status, strerror(abs(status)));
2879     }
2880     DLOGI("Handling hotplug... %s", (kHotPlugNone == pending_hotplug_event_) ?
2881           "Stopped." : "Done. Hotplug events pending.");
2882     return status;
2883   }
2884 
2885   pending_hotplug_event_ = kHotPlugNone;
2886 
2887   DLOGI("Handling hotplug... Done.");
2888   return 0;
2889 }
2890 
HandleConnectedDisplays(HWDisplaysInfo * hw_displays_info,bool delay_hotplug)2891 int HWCSession::HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool delay_hotplug) {
2892   int status = 0;
2893   std::vector<hwc2_display_t> pending_hotplugs = {};
2894   hwc2_display_t client_id = 0;
2895 
2896   for (auto &iter : *hw_displays_info) {
2897     auto &info = iter.second;
2898 
2899     // Do not recreate primary display or if display is not connected.
2900     if (info.is_primary || info.display_type != kPluggable || !info.is_connected) {
2901       continue;
2902     }
2903 
2904     // Check if we are already using the display.
2905     auto display_used = std::find_if(map_info_pluggable_.begin(), map_info_pluggable_.end(),
2906                                      [&](auto &p) {
2907                                        return (p.sdm_id == info.display_id);
2908                                      });
2909     if (display_used != map_info_pluggable_.end()) {
2910       // Display is already used in a slot.
2911       continue;
2912     }
2913 
2914     // Count active pluggable display slots and slots with no commits.
2915     bool first_commit_pending = false;
2916     std::for_each(map_info_pluggable_.begin(), map_info_pluggable_.end(),
2917                    [&](auto &p) {
2918                      SCOPE_LOCK(locker_[p.client_id]);
2919                      if (hwc_display_[p.client_id]) {
2920                        if (!hwc_display_[p.client_id]->IsFirstCommitDone()) {
2921                          DLOGI("Display commit pending on display %d-1", p.sdm_id);
2922                          first_commit_pending = true;
2923                        }
2924                      }
2925                    });
2926 
2927     if (!disable_hotplug_bwcheck_ && first_commit_pending) {
2928       // Hotplug bandwidth check is accomplished by creating and hotplugging a new display after
2929       // a display commit has happened on previous hotplugged displays. This allows the driver to
2930       // return updated modes for the new display based on available link bandwidth.
2931       DLOGI("Pending display commit on one of the displays. Deferring display creation.");
2932       status = -EAGAIN;
2933       if (callbacks_.IsClientConnected()) {
2934         // Trigger a display refresh since we depend on PresentDisplay() to handle pending hotplugs.
2935         hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
2936         if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
2937           active_builtin_disp_id = HWC_DISPLAY_PRIMARY;
2938         }
2939         callbacks_.Refresh(active_builtin_disp_id);
2940       }
2941       break;
2942     }
2943 
2944     // find an empty slot to create display.
2945     for (auto &map_info : map_info_pluggable_) {
2946       client_id = map_info.client_id;
2947 
2948       // Lock confined to this scope
2949       {
2950         SCOPE_LOCK(locker_[client_id]);
2951         auto &hwc_display = hwc_display_[client_id];
2952         if (hwc_display) {
2953           // Display slot is already used.
2954           continue;
2955         }
2956 
2957         DLOGI("Create pluggable display, sdm id = %d, client id = %d", info.display_id,
2958               UINT32(client_id));
2959 
2960         // Test pattern generation ?
2961         map_info.test_pattern = (hpd_bpp_ > 0) && (hpd_pattern_ > 0);
2962         int err = 0;
2963         if (!map_info.test_pattern) {
2964           err = HWCDisplayPluggable::Create(core_intf_, &buffer_allocator_,
2965                                             &callbacks_, this, qservice_, client_id,
2966                                             info.display_id, 0, 0, false, &hwc_display);
2967         } else {
2968           err = HWCDisplayPluggableTest::Create(core_intf_, &buffer_allocator_,
2969                                                 &callbacks_, this, qservice_, client_id,
2970                                                 info.display_id, UINT32(hpd_bpp_),
2971                                                 UINT32(hpd_pattern_), &hwc_display);
2972         }
2973 
2974         if (err) {
2975           DLOGW("Pluggable display creation failed/aborted. Error %d '%s'.", err,
2976                 strerror(abs(err)));
2977           status = err;
2978           // Attempt creating remaining pluggable displays.
2979           break;
2980         }
2981 
2982         {
2983           SCOPE_LOCK(hdr_locker_[client_id]);
2984           is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display);
2985         }
2986 
2987         DLOGI("Created pluggable display successfully: sdm id = %d, client id = %d",
2988               info.display_id, UINT32(client_id));
2989         CreateDummyDisplay(client_id);
2990       }
2991 
2992       map_info.disp_type = info.display_type;
2993       map_info.sdm_id = info.display_id;
2994 
2995       pending_hotplugs.push_back((hwc2_display_t)client_id);
2996 
2997       // Display is created for this sdm id, move to next connected display.
2998       break;
2999     }
3000   }
3001 
3002   // No display was created.
3003   if (!pending_hotplugs.size()) {
3004     return status;
3005   }
3006 
3007   // Active builtin display needs revalidation
3008   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3009   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
3010     WaitForResources(delay_hotplug, active_builtin_disp_id, client_id);
3011   }
3012 
3013   for (auto client_id : pending_hotplugs) {
3014     DLOGI("Notify hotplug display connected: client id = %d", UINT32(client_id));
3015     callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
3016   }
3017 
3018   return status;
3019 }
3020 
HasHDRSupport(HWCDisplay * hwc_display)3021 bool HWCSession::HasHDRSupport(HWCDisplay *hwc_display) {
3022   // query number of hdr types
3023   uint32_t out_num_types = 0;
3024   float out_max_luminance = 0.0f;
3025   float out_max_average_luminance = 0.0f;
3026   float out_min_luminance = 0.0f;
3027   if (hwc_display->GetHdrCapabilities(&out_num_types, nullptr, &out_max_luminance,
3028                                       &out_max_average_luminance, &out_min_luminance)
3029                                       != HWC2::Error::None) {
3030     return false;
3031   }
3032 
3033   return (out_num_types > 0);
3034 }
3035 
HandleDisconnectedDisplays(HWDisplaysInfo * hw_displays_info)3036 int HWCSession::HandleDisconnectedDisplays(HWDisplaysInfo *hw_displays_info) {
3037   // Destroy pluggable displays which were connected earlier but got disconnected now.
3038   for (auto &map_info : map_info_pluggable_) {
3039     bool disconnect = true;   // disconnect in case display id is not found in list.
3040 
3041     for (auto &iter : *hw_displays_info) {
3042       auto &info = iter.second;
3043       if (info.display_id != map_info.sdm_id) {
3044         continue;
3045       }
3046       if (info.is_connected) {
3047         disconnect = false;
3048       }
3049       break;
3050     }
3051 
3052     if (disconnect) {
3053       DestroyDisplay(&map_info);
3054     }
3055   }
3056 
3057   return 0;
3058 }
3059 
DestroyDisplay(DisplayMapInfo * map_info)3060 void HWCSession::DestroyDisplay(DisplayMapInfo *map_info) {
3061   switch (map_info->disp_type) {
3062     case kPluggable:
3063       DestroyPluggableDisplay(map_info);
3064       break;
3065     default:
3066       DestroyNonPluggableDisplay(map_info);
3067       break;
3068     }
3069 }
3070 
DestroyPluggableDisplay(DisplayMapInfo * map_info)3071 void HWCSession::DestroyPluggableDisplay(DisplayMapInfo *map_info) {
3072   hwc2_display_t client_id = map_info->client_id;
3073 
3074   DLOGI("Notify hotplug display disconnected: client id = %d", UINT32(client_id));
3075   callbacks_.Hotplug(client_id, HWC2::Connection::Disconnected);
3076 
3077   SCOPE_LOCK(system_locker_);
3078   {
3079     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[client_id]);
3080     auto &hwc_display = hwc_display_[client_id];
3081     if (!hwc_display) {
3082       return;
3083     }
3084     DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type,
3085          UINT32(client_id));
3086     {
3087       SCOPE_LOCK(hdr_locker_[client_id]);
3088       is_hdr_display_[UINT32(client_id)] = false;
3089     }
3090 
3091     if (!map_info->test_pattern) {
3092       HWCDisplayPluggable::Destroy(hwc_display);
3093     } else {
3094       HWCDisplayPluggableTest::Destroy(hwc_display);
3095     }
3096 
3097     if (async_powermode_) {
3098       hwc2_display_t dummy_disp_id = map_hwc_display_.find(client_id)->second;
3099       auto &hwc_display_dummy = hwc_display_[dummy_disp_id];
3100       display_ready_.reset(UINT32(dummy_disp_id));
3101       if (hwc_display_dummy) {
3102         HWCDisplayDummy::Destroy(hwc_display_dummy);
3103         hwc_display_dummy = nullptr;
3104       }
3105     }
3106     display_ready_.reset(UINT32(client_id));
3107     pending_power_mode_[client_id] = false;
3108     hwc_display = nullptr;
3109     map_info->Reset();
3110   }
3111 }
3112 
DestroyNonPluggableDisplay(DisplayMapInfo * map_info)3113 void HWCSession::DestroyNonPluggableDisplay(DisplayMapInfo *map_info) {
3114   hwc2_display_t client_id = map_info->client_id;
3115 
3116   SCOPE_LOCK(locker_[client_id]);
3117   auto &hwc_display = hwc_display_[client_id];
3118   if (!hwc_display) {
3119     return;
3120   }
3121   DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type,
3122         UINT32(client_id));
3123   {
3124     SCOPE_LOCK(hdr_locker_[client_id]);
3125     is_hdr_display_[UINT32(client_id)] = false;
3126   }
3127 
3128   switch (map_info->disp_type) {
3129     case kBuiltIn:
3130       HWCDisplayBuiltIn::Destroy(hwc_display);
3131       break;
3132     default:
3133       virtual_display_factory_.Destroy(hwc_display);
3134       break;
3135     }
3136 
3137     if (async_powermode_ && map_info->disp_type == kBuiltIn) {
3138       hwc2_display_t dummy_disp_id = map_hwc_display_.find(client_id)->second;
3139       auto &hwc_display_dummy = hwc_display_[dummy_disp_id];
3140       display_ready_.reset(UINT32(dummy_disp_id));
3141       if (hwc_display_dummy) {
3142         HWCDisplayDummy::Destroy(hwc_display_dummy);
3143         hwc_display_dummy = nullptr;
3144       }
3145     }
3146     pending_power_mode_[client_id] = false;
3147     hwc_display = nullptr;
3148     display_ready_.reset(UINT32(client_id));
3149     map_info->Reset();
3150 }
3151 
ValidateDisplayInternal(hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)3152 HWC2::Error HWCSession::ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
3153                                                 uint32_t *out_num_requests) {
3154   HWCDisplay *hwc_display = hwc_display_[display];
3155 
3156   DTRACE_SCOPED();
3157   if (hwc_display->IsInternalValidateState()) {
3158     // Internal Validation has already been done on display, get the Output params.
3159     return hwc_display->GetValidateDisplayOutput(out_num_types, out_num_requests);
3160   }
3161 
3162   if (display == HWC_DISPLAY_PRIMARY) {
3163     // TODO(user): This can be moved to HWCDisplayPrimary
3164     if (need_invalidate_) {
3165       callbacks_.Refresh(display);
3166       need_invalidate_ = false;
3167     }
3168   }
3169 
3170   auto status = HWC2::Error::None;
3171   status = hwc_display->Validate(out_num_types, out_num_requests);
3172   SetCpuPerfHintLargeCompCycle();
3173   return status;
3174 }
3175 
PresentDisplayInternal(hwc2_display_t display)3176 HWC2::Error HWCSession::PresentDisplayInternal(hwc2_display_t display) {
3177   HWCDisplay *hwc_display = hwc_display_[display];
3178 
3179   DTRACE_SCOPED();
3180   // If display is in Skip-Validate state and Validate cannot be skipped, do Internal
3181   // Validation to optimize for the frames which don't require the Client composition.
3182   if (hwc_display->IsSkipValidateState() && !hwc_display->CanSkipValidate()) {
3183     uint32_t out_num_types = 0, out_num_requests = 0;
3184     hwc_display->SetFastPathComposition(true);
3185     HWC2::Error error = ValidateDisplayInternal(display, &out_num_types, &out_num_requests);
3186     if ((error != HWC2::Error::None) || hwc_display->HWCClientNeedsValidate()) {
3187       hwc_display->SetValidationState(HWCDisplay::kInternalValidate);
3188       hwc_display->SetFastPathComposition(false);
3189       return HWC2::Error::NotValidated;
3190     }
3191   }
3192   return HWC2::Error::None;
3193 }
3194 
DisplayPowerReset()3195 void HWCSession::DisplayPowerReset() {
3196   // Acquire lock on all displays.
3197   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3198     display < HWCCallbacks::kNumDisplays; display++) {
3199     locker_[display].Lock();
3200   }
3201 
3202   HWC2::Error status = HWC2::Error::None;
3203   HWC2::PowerMode last_power_mode[HWCCallbacks::kNumDisplays] = {};
3204 
3205   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3206     display < HWCCallbacks::kNumDisplays; display++) {
3207     if (hwc_display_[display] != NULL) {
3208       last_power_mode[display] = hwc_display_[display]->GetCurrentPowerMode();
3209       DLOGI("Powering off display = %d", INT32(display));
3210       status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::Off,
3211                                                    true /* teardown */);
3212       if (status != HWC2::Error::None) {
3213         DLOGE("Power off for display = %d failed with error = %d", INT32(display), status);
3214       }
3215     }
3216   }
3217   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3218     display < HWCCallbacks::kNumDisplays; display++) {
3219     if (hwc_display_[display] != NULL) {
3220       HWC2::PowerMode mode = last_power_mode[display];
3221       DLOGI("Setting display %d to mode = %d", INT32(display), mode);
3222       status = hwc_display_[display]->SetPowerMode(mode, false /* teardown */);
3223       if (status != HWC2::Error::None) {
3224         DLOGE("%d mode for display = %d failed with error = %d", mode, INT32(display), status);
3225       }
3226       ColorMode color_mode = hwc_display_[display]->GetCurrentColorMode();
3227       status = hwc_display_[display]->SetColorMode(color_mode);
3228       if (status != HWC2::Error::None) {
3229         DLOGE("SetColorMode failed for display = %d error = %d", INT32(display), status);
3230       }
3231     }
3232   }
3233 
3234   hwc2_display_t vsync_source = callbacks_.GetVsyncSource();
3235   status = hwc_display_[vsync_source]->SetVsyncEnabled(HWC2::Vsync::Enable);
3236   if (status != HWC2::Error::None) {
3237     DLOGE("Enabling vsync failed for disp: %" PRIu64 " with error = %d", vsync_source, status);
3238   }
3239 
3240   // Release lock on all displays.
3241   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3242     display < HWCCallbacks::kNumDisplays; display++) {
3243     locker_[display].Unlock();
3244   }
3245 
3246   callbacks_.Refresh(vsync_source);
3247 }
3248 
HandleSecureSession()3249 void HWCSession::HandleSecureSession() {
3250   std::bitset<kSecureMax> secure_sessions = 0;
3251   {
3252     // TODO(user): Revisit if supporting secure display on non-primary.
3253     hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3254     if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
3255       return;
3256     }
3257     Locker::ScopeLock lock_pwr(power_state_[active_builtin_disp_id]);
3258     if (power_state_transition_[active_builtin_disp_id]) {
3259       // Route all interactions with client to dummy display.
3260       active_builtin_disp_id = map_hwc_display_.find(active_builtin_disp_id)->second;
3261     }
3262     Locker::ScopeLock lock_d(locker_[active_builtin_disp_id]);
3263     hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
3264   }
3265 
3266   if (secure_sessions.any()) {
3267     secure_session_active_ = true;
3268   } else if (!secure_session_active_) {
3269     // No secure session active. No secure session transition to handle. Skip remaining steps.
3270     return;
3271   }
3272 
3273   // If it is called during primary prepare/commit, we need to pause any ongoing commit on
3274   // external/virtual display.
3275   bool found_active_secure_display = false;
3276   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3277        display < HWCCallbacks::kNumRealDisplays; display++) {
3278     Locker::ScopeLock lock_d(locker_[display]);
3279     HWCDisplay *hwc_display = hwc_display_[display];
3280     if (!hwc_display) {
3281       continue;
3282     }
3283 
3284     bool is_active_secure_display = false;
3285     // The first On/Doze/DozeSuspend built-in display is taken as the secure display.
3286     if (!found_active_secure_display &&
3287         hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN &&
3288         hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
3289       is_active_secure_display = true;
3290       found_active_secure_display = true;
3291     }
3292     hwc_display->HandleSecureSession(secure_sessions, &pending_power_mode_[display],
3293                                      is_active_secure_display);
3294   }
3295 }
3296 
HandlePendingPowerMode(hwc2_display_t disp_id,const shared_ptr<Fence> & retire_fence)3297 void HWCSession::HandlePendingPowerMode(hwc2_display_t disp_id,
3298                                         const shared_ptr<Fence> &retire_fence) {
3299   if (!secure_session_active_) {
3300     // No secure session active. Skip remaining steps.
3301     return;
3302   }
3303 
3304   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3305   if (disp_id != active_builtin_disp_id) {
3306     return;
3307   }
3308 
3309   Locker::ScopeLock lock_d(locker_[active_builtin_disp_id]);
3310   bool pending_power_mode = false;
3311   std::bitset<kSecureMax> secure_sessions = 0;
3312   hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
3313   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1;
3314     display < HWCCallbacks::kNumDisplays; display++) {
3315     if (display != active_builtin_disp_id) {
3316       Locker::ScopeLock lock_d(locker_[display]);
3317       if (pending_power_mode_[display]) {
3318         pending_power_mode = true;
3319         break;
3320       }
3321     }
3322   }
3323 
3324   if (!pending_power_mode) {
3325     if (!secure_sessions.any()) {
3326       secure_session_active_ = false;
3327     }
3328     return;
3329   }
3330 
3331   // retire fence is set only after successful primary commit, So check for retire fence to know
3332   // non secure commit went through to notify driver to change the CRTC mode to non secure.
3333   // Otherwise any commit to non-primary display would fail.
3334   if (retire_fence == nullptr) {
3335     return;
3336   }
3337 
3338   Fence::Wait(retire_fence);
3339 
3340   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1;
3341     display < HWCCallbacks::kNumDisplays; display++) {
3342     if (display != active_builtin_disp_id) {
3343       Locker::ScopeLock lock_d(locker_[display]);
3344       if (pending_power_mode_[display] && hwc_display_[display]) {
3345         HWC2::Error error =
3346           hwc_display_[display]->SetPowerMode(hwc_display_[display]->GetPendingPowerMode(), false);
3347         if (HWC2::Error::None == error) {
3348           pending_power_mode_[display] = false;
3349           hwc_display_[display]->ClearPendingPowerMode();
3350           pending_refresh_.set(UINT32(HWC_DISPLAY_PRIMARY));
3351         } else {
3352           DLOGE("SetDisplayStatus error = %d (%s)", error, to_string(error).c_str());
3353         }
3354       }
3355     }
3356   }
3357   secure_session_active_ = false;
3358 }
3359 
HandlePendingHotplug(hwc2_display_t disp_id,const shared_ptr<Fence> & retire_fence)3360 void HWCSession::HandlePendingHotplug(hwc2_display_t disp_id,
3361                                       const shared_ptr<Fence> &retire_fence) {
3362   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3363   if (disp_id != active_builtin_disp_id ||
3364       (kHotPlugNone == pending_hotplug_event_ && !destroy_virtual_disp_pending_)) {
3365     return;
3366   }
3367 
3368   std :: bitset < kSecureMax > secure_sessions = 0;
3369   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
3370     Locker::ScopeLock lock_d(locker_[active_builtin_disp_id]);
3371     hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
3372   }
3373 
3374   if (secure_sessions.any() || active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
3375     return;
3376   }
3377 
3378   if (destroy_virtual_disp_pending_ || kHotPlugEvent == pending_hotplug_event_) {
3379     Fence::Wait(retire_fence);
3380 
3381     // Destroy the pending virtual display if secure session not present.
3382     if (destroy_virtual_disp_pending_) {
3383       for (auto &map_info : map_info_virtual_) {
3384         DestroyDisplay(&map_info);
3385         destroy_virtual_disp_pending_ = false;
3386         virtual_id_ = HWCCallbacks::kNumDisplays;
3387       }
3388     }
3389     // Handle connect/disconnect hotplugs if secure session is not present.
3390     hwc2_display_t virtual_display_idx = (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
3391     if (!hwc_display_[virtual_display_idx] && kHotPlugEvent == pending_hotplug_event_) {
3392       // Handle deferred hotplug event.
3393       int32_t err = pluggable_handler_lock_.TryLock();
3394       if (!err) {
3395         // Do hotplug handling in a different thread to avoid blocking PresentDisplay.
3396         std::thread(&HWCSession::HandlePluggableDisplays, this, true).detach();
3397         pluggable_handler_lock_.Unlock();
3398       } else {
3399         // EBUSY means another thread is already handling hotplug. Skip deferred hotplug handling.
3400         if (EBUSY != err) {
3401           DLOGW("Failed to acquire pluggable display handler lock. Error %d '%s'.", err,
3402                 strerror(abs(err)));
3403         }
3404       }
3405     }
3406   }
3407 }
3408 
GetReadbackBufferAttributes(hwc2_display_t display,int32_t * format,int32_t * dataspace)3409 int32_t HWCSession::GetReadbackBufferAttributes(hwc2_display_t display, int32_t *format,
3410                                                 int32_t *dataspace) {
3411   if (display >= HWCCallbacks::kNumDisplays) {
3412     return HWC2_ERROR_BAD_DISPLAY;
3413   }
3414 
3415   if (!format || !dataspace) {
3416     return HWC2_ERROR_BAD_PARAMETER;
3417   }
3418 
3419   if (display != HWC_DISPLAY_PRIMARY) {
3420     return HWC2_ERROR_UNSUPPORTED;
3421   }
3422 
3423   HWCDisplay *hwc_display = hwc_display_[display];
3424   if (hwc_display == nullptr) {
3425     return HWC2_ERROR_BAD_DISPLAY;
3426   } else if (!hwc_display->HasReadBackBufferSupport()) {
3427     return HWC2_ERROR_UNSUPPORTED;
3428   }
3429 
3430   *format = HAL_PIXEL_FORMAT_RGB_888;
3431   *dataspace = GetDataspaceFromColorMode(hwc_display->GetCurrentColorMode());
3432 
3433   return HWC2_ERROR_NONE;
3434 }
3435 
SetReadbackBuffer(hwc2_display_t display,const native_handle_t * buffer,const shared_ptr<Fence> & acquire_fence)3436 int32_t HWCSession::SetReadbackBuffer(hwc2_display_t display, const native_handle_t *buffer,
3437                                       const shared_ptr<Fence> &acquire_fence) {
3438 
3439   if (display >= HWCCallbacks::kNumDisplays) {
3440     return HWC2_ERROR_BAD_DISPLAY;
3441   }
3442 
3443   if (!buffer) {
3444     return HWC2_ERROR_BAD_PARAMETER;
3445   }
3446 
3447   if (display != HWC_DISPLAY_PRIMARY) {
3448     return HWC2_ERROR_UNSUPPORTED;
3449   }
3450 
3451   int external_dpy_index = GetDisplayIndex(qdutils::DISPLAY_EXTERNAL);
3452   int virtual_dpy_index = GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
3453   if (((external_dpy_index != -1) && hwc_display_[external_dpy_index]) ||
3454       ((virtual_dpy_index != -1) && hwc_display_[virtual_dpy_index])) {
3455     return HWC2_ERROR_UNSUPPORTED;
3456   }
3457 
3458   return CallDisplayFunction(display, &HWCDisplay::SetReadbackBuffer, buffer, acquire_fence,
3459                              false, kCWBClientComposer);
3460 }
3461 
GetReadbackBufferFence(hwc2_display_t display,shared_ptr<Fence> * release_fence)3462 int32_t HWCSession::GetReadbackBufferFence(hwc2_display_t display,
3463                                            shared_ptr<Fence> *release_fence) {
3464   if (display >= HWCCallbacks::kNumDisplays) {
3465     return HWC2_ERROR_BAD_DISPLAY;
3466   }
3467 
3468   if (!release_fence) {
3469     return HWC2_ERROR_BAD_PARAMETER;
3470   }
3471 
3472   if (display != HWC_DISPLAY_PRIMARY) {
3473     return HWC2_ERROR_UNSUPPORTED;
3474   }
3475 
3476   return CallDisplayFunction(display, &HWCDisplay::GetReadbackBufferFence, release_fence);
3477 }
3478 
GetDisplayIdentificationData(hwc2_display_t display,uint8_t * outPort,uint32_t * outDataSize,uint8_t * outData)3479 int32_t HWCSession::GetDisplayIdentificationData(hwc2_display_t display, uint8_t *outPort,
3480                                                  uint32_t *outDataSize, uint8_t *outData) {
3481   if (!outPort || !outDataSize) {
3482     return HWC2_ERROR_BAD_PARAMETER;
3483   }
3484 
3485   if (display >= HWCCallbacks::kNumDisplays) {
3486     return HWC2_ERROR_BAD_DISPLAY;
3487   }
3488 
3489   return CallDisplayFunction(display, &HWCDisplay::GetDisplayIdentificationData, outPort,
3490                              outDataSize, outData);
3491 }
3492 
GetDisplayCapabilities(hwc2_display_t display,uint32_t * outNumCapabilities,uint32_t * outCapabilities)3493 int32_t HWCSession::GetDisplayCapabilities(hwc2_display_t display, uint32_t *outNumCapabilities,
3494                                            uint32_t *outCapabilities) {
3495   if (!outNumCapabilities) {
3496     return HWC2_ERROR_BAD_PARAMETER;
3497   }
3498 
3499   if (display >= HWCCallbacks::kNumDisplays) {
3500     return HWC2_ERROR_BAD_DISPLAY;
3501   }
3502 
3503   if (!hwc_display_[display]) {
3504     DLOGE("Expected valid hwc_display");
3505     return HWC2_ERROR_BAD_PARAMETER;
3506   }
3507 
3508   bool isBuiltin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
3509   *outNumCapabilities = 0;
3510   if (isBuiltin) {
3511     *outNumCapabilities = 3;
3512     if (outCapabilities != nullptr) {
3513       // TODO(user): Handle SKIP_CLIENT_COLOR_TRANSFORM based on DSPP availability
3514       outCapabilities[0] = static_cast<uint32_t>(HwcDisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
3515       outCapabilities[1] = static_cast<uint32_t>(HwcDisplayCapability::DOZE);
3516       outCapabilities[2] = static_cast<uint32_t>(HwcDisplayCapability::BRIGHTNESS);
3517     }
3518   }
3519 
3520   return HWC2_ERROR_NONE;
3521 }
3522 
GetDisplayCapabilities_2_4(hwc2_display_t display,uint32_t * outNumCapabilities,uint32_t * outCapabilities)3523 int32_t HWCSession::GetDisplayCapabilities_2_4(hwc2_display_t display, uint32_t *outNumCapabilities,
3524                                                uint32_t *outCapabilities) {
3525   if (!outNumCapabilities) {
3526     return HWC2_ERROR_BAD_PARAMETER;
3527   }
3528 
3529   if (display >= HWCCallbacks::kNumDisplays) {
3530     return HWC2_ERROR_BAD_DISPLAY;
3531   }
3532 
3533   if (!hwc_display_[display]) {
3534     DLOGE("Expected valid hwc_display");
3535     return HWC2_ERROR_BAD_PARAMETER;
3536   }
3537 
3538   bool isBuiltin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
3539   *outNumCapabilities = 0;
3540   if (isBuiltin) {
3541     *outNumCapabilities = 1;
3542     if (outCapabilities != nullptr) {
3543       outCapabilities[0] = static_cast<uint32_t>(HwcDisplayCapability::PROTECTED_CONTENTS);
3544     }
3545   }
3546 
3547   return HWC2_ERROR_NONE;
3548 }
3549 
GetDisplayConnectionType(hwc2_display_t display,HwcDisplayConnectionType * type)3550 int32_t HWCSession::GetDisplayConnectionType(hwc2_display_t display,
3551                                              HwcDisplayConnectionType *type) {
3552   if (display >= HWCCallbacks::kNumDisplays) {
3553     return HWC2_ERROR_BAD_DISPLAY;
3554   }
3555 
3556   if (!type) {
3557     return HWC2_ERROR_BAD_PARAMETER;
3558   }
3559 
3560   if (!hwc_display_[display]) {
3561     DLOGE("Expected valid hwc_display");
3562     return HWC2_ERROR_BAD_DISPLAY;
3563   }
3564   *type = HwcDisplayConnectionType::EXTERNAL;
3565   if (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
3566     *type = HwcDisplayConnectionType::INTERNAL;
3567   }
3568 
3569   return HWC2_ERROR_NONE;
3570 }
3571 
GetClientTargetProperty(hwc2_display_t display,HwcClientTargetProperty * outClientTargetProperty)3572 int32_t HWCSession::GetClientTargetProperty(hwc2_display_t display,
3573                                             HwcClientTargetProperty *outClientTargetProperty) {
3574   if (!outClientTargetProperty) {
3575     return HWC2_ERROR_BAD_PARAMETER;
3576   }
3577 
3578   if (display >= HWCCallbacks::kNumDisplays) {
3579     return HWC2_ERROR_BAD_DISPLAY;
3580   }
3581 
3582   return CallDisplayFunction(display, &HWCDisplay::GetClientTargetProperty,
3583                              outClientTargetProperty);
3584 }
3585 
GetDisplayBrightnessSupport(hwc2_display_t display,bool * outSupport)3586 int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_display_t display, bool *outSupport) {
3587   if (!outSupport) {
3588     return HWC2_ERROR_BAD_PARAMETER;
3589   }
3590 
3591   if (display >= HWCCallbacks::kNumDisplays) {
3592     return HWC2_ERROR_BAD_DISPLAY;
3593   }
3594 
3595   if (!hwc_display_[display]) {
3596     DLOGE("Expected valid hwc_display");
3597     return HWC2_ERROR_BAD_PARAMETER;
3598   }
3599   *outSupport = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
3600   return HWC2_ERROR_NONE;
3601 }
3602 
SetDisplayBrightness(hwc2_display_t display,float brightness)3603 int32_t HWCSession::SetDisplayBrightness(hwc2_display_t display, float brightness) {
3604   if (display >= HWCCallbacks::kNumDisplays) {
3605     return HWC2_ERROR_BAD_DISPLAY;
3606   }
3607 
3608   if (!hwc_display_[display]) {
3609     return HWC2_ERROR_BAD_PARAMETER;
3610   }
3611 
3612   return INT32(hwc_display_[display]->SetPanelBrightness(brightness));
3613 }
3614 
SetQSyncMode(const android::Parcel * input_parcel)3615 android::status_t HWCSession::SetQSyncMode(const android::Parcel *input_parcel) {
3616   auto mode = input_parcel->readInt32();
3617 
3618   QSyncMode qsync_mode = kQSyncModeNone;
3619   switch (mode) {
3620     case qService::IQService::QSYNC_MODE_NONE:
3621       qsync_mode = kQSyncModeNone;
3622       break;
3623     case qService::IQService::QSYNC_MODE_CONTINUOUS:
3624       qsync_mode = kQSyncModeContinuous;
3625       break;
3626     case qService::IQService::QSYNC_MODE_ONESHOT:
3627       qsync_mode = kQsyncModeOneShot;
3628       break;
3629     default:
3630       DLOGE("Qsync mode not supported %d", mode);
3631       return -EINVAL;
3632   }
3633   return CallDisplayFunction(HWC_DISPLAY_PRIMARY, &HWCDisplay::SetQSyncMode, qsync_mode);
3634 }
3635 
UpdateThrottlingRate()3636 void HWCSession::UpdateThrottlingRate() {
3637   uint32_t new_min = 0;
3638 
3639   for (int i=0; i < HWCCallbacks::kNumDisplays; i++) {
3640     auto &display = hwc_display_[i];
3641     if (!display)
3642       continue;
3643     if (display->GetCurrentPowerMode() != HWC2::PowerMode::Off)
3644       new_min = (new_min == 0) ? display->GetMaxRefreshRate() :
3645         std::min(new_min, display->GetMaxRefreshRate());
3646   }
3647 
3648   SetNewThrottlingRate(new_min);
3649 }
3650 
SetNewThrottlingRate(const uint32_t new_rate)3651 void HWCSession::SetNewThrottlingRate(const uint32_t new_rate) {
3652   if (new_rate !=0 && throttling_refresh_rate_ != new_rate) {
3653     HWCDisplay::SetThrottlingRefreshRate(new_rate);
3654     throttling_refresh_rate_ = new_rate;
3655   }
3656 }
3657 
SetIdlePC(const android::Parcel * input_parcel)3658 android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) {
3659   auto enable = input_parcel->readInt32();
3660   auto synchronous = input_parcel->readInt32();
3661 
3662   return static_cast<android::status_t>(ControlIdlePowerCollapse(enable, synchronous));
3663 }
3664 
GetActiveBuiltinDisplay()3665 hwc2_display_t HWCSession::GetActiveBuiltinDisplay() {
3666   hwc2_display_t active_display = HWCCallbacks::kNumDisplays;
3667   // Get first active display among primary and built-in displays.
3668   std::vector<DisplayMapInfo> map_info = {map_info_primary_};
3669   std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
3670 
3671   for (auto &info : map_info) {
3672     hwc2_display_t target_display = info.client_id;
3673     SCOPE_LOCK(power_state_[target_display]);
3674     if (power_state_transition_[target_display]) {
3675       // Route all interactions with client to dummy display.
3676       target_display = map_hwc_display_.find(target_display)->second;
3677     }
3678     Locker::ScopeLock lock_d(locker_[target_display]);
3679     auto &hwc_display = hwc_display_[target_display];
3680     if (hwc_display && hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
3681       active_display = info.client_id;
3682       break;
3683     }
3684   }
3685 
3686   return active_display;
3687 }
3688 
SetDisplayBrightnessScale(const android::Parcel * input_parcel)3689 int32_t HWCSession::SetDisplayBrightnessScale(const android::Parcel *input_parcel) {
3690   auto display = input_parcel->readInt32();
3691   auto level = input_parcel->readInt32();
3692   if (level < 0 || level > kBrightnessScaleMax) {
3693     DLOGE("Invalid backlight scale level %d", level);
3694     return -EINVAL;
3695   }
3696   auto bl_scale = level * kSvBlScaleMax / kBrightnessScaleMax;
3697   auto error = CallDisplayFunction(display, &HWCDisplay::SetBLScale, (uint32_t)bl_scale);
3698   if (INT32(error) == HWC2_ERROR_NONE) {
3699     callbacks_.Refresh(display);
3700   }
3701 
3702   return INT32(error);
3703 }
3704 
NotifyClientStatus(bool connected)3705 void HWCSession::NotifyClientStatus(bool connected) {
3706   for (uint32_t i = 0; i < HWCCallbacks::kNumDisplays; i++) {
3707     if (!hwc_display_[i]) {
3708       continue;
3709     }
3710     SCOPE_LOCK(locker_[i]);
3711     hwc_display_[i]->NotifyClientStatus(connected);
3712     hwc_display_[i]->SetVsyncEnabled(HWC2::Vsync::Disable);
3713   }
3714   callbacks_.UpdateVsyncSource(HWCCallbacks::kNumDisplays);
3715 }
3716 
WaitForResources(bool wait_for_resources,hwc2_display_t active_builtin_id,hwc2_display_t display_id)3717 void HWCSession::WaitForResources(bool wait_for_resources, hwc2_display_t active_builtin_id,
3718                                   hwc2_display_t display_id) {
3719   std::vector<DisplayMapInfo> map_info = {map_info_primary_};
3720   std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
3721 
3722   for (auto &info : map_info) {
3723     hwc2_display_t target_display = info.client_id;
3724     {
3725       SCOPE_LOCK(power_state_[target_display]);
3726       if (power_state_transition_[target_display]) {
3727         // Route all interactions with client to dummy display.
3728         target_display = map_hwc_display_.find(target_display)->second;
3729       }
3730     }
3731     {
3732       SEQUENCE_WAIT_SCOPE_LOCK(locker_[target_display]);
3733       auto &hwc_display = hwc_display_[target_display];
3734       if (hwc_display && hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
3735         hwc_display->ResetValidation();
3736       }
3737     }
3738   }
3739 
3740   if (wait_for_resources) {
3741     bool res_wait = true;
3742     do {
3743       if (client_connected_) {
3744         Refresh(active_builtin_id);
3745       }
3746       {
3747         std::unique_lock<std::mutex> caller_lock(hotplug_mutex_);
3748         hotplug_cv_.wait(caller_lock);
3749       }
3750       res_wait = hwc_display_[display_id]->CheckResourceState();
3751     } while (res_wait);
3752   }
3753 }
3754 
GetDisplayVsyncPeriod(hwc2_display_t disp,VsyncPeriodNanos * vsync_period)3755 int32_t HWCSession::GetDisplayVsyncPeriod(hwc2_display_t disp, VsyncPeriodNanos *vsync_period) {
3756   if (vsync_period == nullptr) {
3757     return HWC2_ERROR_BAD_PARAMETER;
3758   }
3759 
3760   return CallDisplayFunction(disp, &HWCDisplay::GetDisplayVsyncPeriod, vsync_period);
3761 }
3762 
SetActiveConfigWithConstraints(hwc2_display_t display,hwc2_config_t config,const VsyncPeriodChangeConstraints * vsync_period_change_constraints,VsyncPeriodChangeTimeline * out_timeline)3763 int32_t HWCSession::SetActiveConfigWithConstraints(
3764     hwc2_display_t display, hwc2_config_t config,
3765     const VsyncPeriodChangeConstraints *vsync_period_change_constraints,
3766     VsyncPeriodChangeTimeline *out_timeline) {
3767   if ((vsync_period_change_constraints == nullptr) || (out_timeline == nullptr)) {
3768     return HWC2_ERROR_BAD_PARAMETER;
3769   }
3770 
3771   return CallDisplayFunction(display, &HWCDisplay::SetActiveConfigWithConstraints, config,
3772                              vsync_period_change_constraints, out_timeline);
3773 }
3774 
SetAutoLowLatencyMode(hwc2_display_t display,bool on)3775 int32_t HWCSession::SetAutoLowLatencyMode(hwc2_display_t display, bool on) {
3776   if (display >= HWCCallbacks::kNumDisplays) {
3777     return HWC2_ERROR_BAD_DISPLAY;
3778   }
3779 
3780   return CallDisplayFunction(display, &HWCDisplay::SetAutoLowLatencyMode, on);
3781 }
3782 
GetSupportedContentTypes(hwc2_display_t display,hidl_vec<HwcContentType> * types)3783 int32_t HWCSession::GetSupportedContentTypes(hwc2_display_t display,
3784                                              hidl_vec<HwcContentType> *types) {
3785   if (display >= HWCCallbacks::kNumDisplays) {
3786     return HWC2_ERROR_BAD_DISPLAY;
3787   }
3788 
3789   return CallDisplayFunction(display, &HWCDisplay::GetSupportedContentTypes, types);
3790 }
3791 
SetContentType(hwc2_display_t display,HwcContentType type)3792 int32_t HWCSession::SetContentType(hwc2_display_t display, HwcContentType type) {
3793   if (display >= HWCCallbacks::kNumDisplays) {
3794     return HWC2_ERROR_BAD_DISPLAY;
3795   }
3796 
3797   return CallDisplayFunction(display, &HWCDisplay::SetContentType, type);
3798 }
3799 
IsHbmSupported()3800 bool HWCSession::IsHbmSupported() {
3801   auto hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
3802 
3803   if (hwc_display)
3804     return hwc_display->IsHbmSupported();
3805 
3806   return 0;
3807 }
3808 
SetHbmState(HbmState state)3809 void HWCSession::SetHbmState(HbmState state) {
3810   CallDisplayFunction(HWC_DISPLAY_PRIMARY, &HWCDisplay::SetHbm, state, HWCDisplay::APP);
3811 }
3812 
GetHbmState()3813 HbmState HWCSession::GetHbmState() {
3814   auto hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
3815 
3816   if (hwc_display)
3817     return hwc_display->GetHbm();
3818 
3819   return HbmState::OFF;
3820 }
3821 
IsLbeSupported()3822 bool HWCSession::IsLbeSupported() {
3823   return (is_lbe_supported_ != 0);
3824 }
3825 
SetLbeState(LbeState state)3826 void HWCSession::SetLbeState(LbeState state) {
3827   std::string_view state_cmd;
3828   int ret = 0;
3829 
3830   if (!is_lbe_supported_) {
3831     DLOGE("lbe is not supported");
3832     return;
3833   }
3834 
3835   if (lbe_cur_state_ == state)
3836     return;
3837 
3838   switch (state) {
3839     case LbeState::OFF:
3840       state_cmd = ltm_off_cmd_;
3841       break;
3842     case LbeState::NORMAL:
3843       state_cmd = ltm_default_mode_cmd_;
3844       break;
3845     case LbeState::HIGH_BRIGHTNESS:
3846       state_cmd = ltm_hbm_mode_cmd_;
3847       break;
3848     case LbeState::POWER_SAVE:
3849       state_cmd = ltm_power_save_mode_cmd_;
3850       break;
3851     default:
3852       DLOGE("lbe mode not support");
3853       return;
3854   }
3855 
3856   if (lbe_cur_state_ == LbeState::OFF) {
3857     std::string_view on_cmd = ltm_on_cmd_;
3858     ret = SendLTMCommand(on_cmd.data());
3859     if (ret) {
3860       DLOGE("failed to enable lbe");
3861       return;
3862     }
3863   }
3864 
3865   ret = SendLTMCommand(state_cmd.data());
3866   if (!ret)
3867     lbe_cur_state_ = state;
3868 }
3869 
SetLbeAmbientLight(int value)3870 void HWCSession::SetLbeAmbientLight(int value) {
3871   if (!is_lbe_supported_ || value < 0 || (lbe_cur_state_ == LbeState::OFF))
3872     return;
3873 
3874   std::string cmd = ltm_lux_cmd_;
3875   std::string val = std::to_string(value);
3876 
3877   cmd += val;
3878 
3879   SendLTMCommand(cmd.c_str());
3880 }
3881 
GetLbeState()3882 LbeState HWCSession::GetLbeState() {
3883   return lbe_cur_state_;
3884 }
3885 
SendLTMCommand(const char * cmd)3886 int HWCSession::SendLTMCommand(const char *cmd) {
3887   if (!cmd || !pps_retry)
3888     return -EINVAL;
3889 
3890   while ((pps_retry > 0) && (pps_socket_ < 0)) {
3891     pps_socket_ = socket_local_client("pps", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
3892     if (pps_socket_ < 0) {
3893       pps_retry--;
3894       if (pps_retry == 0) {
3895         DLOGE("Connecting to pps socket failed, error = %s", strerror(errno));
3896         return -ETIMEDOUT;
3897       }
3898     }
3899   }
3900 
3901   int ret = write(pps_socket_, cmd, strlen(cmd));
3902   if (ret < 0) {
3903     DLOGE("Failed to send LTM cmd, error = %s", strerror(errno));
3904     return -EINVAL;
3905   }
3906   usleep(1000);
3907 
3908   return 0;
3909 }
3910 
SetCpuPerfHintLargeCompCycle()3911 void HWCSession::SetCpuPerfHintLargeCompCycle() {
3912   bool found_non_primary_active_display = false;
3913 
3914   // Check any non-primary display is active
3915   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1;
3916     display < HWCCallbacks::kNumDisplays; display++) {
3917     if (hwc_display_[display] == NULL) {
3918       continue;
3919     }
3920     if (hwc_display_[display]->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
3921       found_non_primary_active_display = true;
3922       break;
3923     }
3924   }
3925 
3926   // send cpu hint for primary display
3927   if (!found_non_primary_active_display) {
3928     hwc_display_[HWC_DISPLAY_PRIMARY]->SetCpuPerfHintLargeCompCycle();
3929   }
3930 }
3931 
3932 }  // namespace sdm
3933