1 /*
2 * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *     * Redistributions of source code must retain the above copyright
8 *       notice, this list of conditions and the following disclaimer.
9 *     * Redistributions in binary form must reproduce the above
10 *       copyright notice, this list of conditions and the following
11 *       disclaimer in the documentation and/or other materials provided
12 *       with the distribution.
13 *     * Neither the name of The Linux Foundation nor the names of its
14 *       contributors may be used to endorse or promote products derived
15 *       from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <core/dump_interface.h>
31 #include <core/buffer_allocator.h>
32 #include <private/color_params.h>
33 #include <utils/constants.h>
34 #include <utils/String16.h>
35 #include <cutils/properties.h>
36 #include <hardware_legacy/uevent.h>
37 #include <sys/resource.h>
38 #include <sys/prctl.h>
39 #include <binder/Parcel.h>
40 #include <QService.h>
41 #include <gr.h>
42 #include <gralloc_priv.h>
43 #include <display_config.h>
44 #include <utils/debug.h>
45 #include <sync/sync.h>
46 #include <profiler.h>
47 #include <bitset>
48 
49 #include "hwc_buffer_allocator.h"
50 #include "hwc_buffer_sync_handler.h"
51 #include "hwc_session.h"
52 #include "hwc_debugger.h"
53 #include "hwc_display_null.h"
54 #include "hwc_display_primary.h"
55 #include "hwc_display_virtual.h"
56 
57 #define __CLASS__ "HWCSession"
58 
59 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
60 #define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
61 
62 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
63 
64 hwc_module_t HAL_MODULE_INFO_SYM = {
65   .common = {
66     .tag = HARDWARE_MODULE_TAG,
67     .version_major = 2,
68     .version_minor = 0,
69     .id = HWC_HARDWARE_MODULE_ID,
70     .name = "QTI Hardware Composer Module",
71     .author = "CodeAurora Forum",
72     .methods = &g_hwc_module_methods,
73     .dso = 0,
74     .reserved = {0},
75   }
76 };
77 
78 namespace sdm {
79 
80 Locker HWCSession::locker_;
81 
Invalidate(const struct hwc_procs * procs)82 static void Invalidate(const struct hwc_procs *procs) {
83 }
84 
VSync(const struct hwc_procs * procs,int disp,int64_t timestamp)85 static void VSync(const struct hwc_procs* procs, int disp, int64_t timestamp) {
86 }
87 
Hotplug(const struct hwc_procs * procs,int disp,int connected)88 static void Hotplug(const struct hwc_procs* procs, int disp, int connected) {
89 }
90 
HWCSession(const hw_module_t * module)91 HWCSession::HWCSession(const hw_module_t *module) {
92   // By default, drop any events. Calls will be routed to SurfaceFlinger after registerProcs.
93   hwc_procs_default_.invalidate = Invalidate;
94   hwc_procs_default_.vsync = VSync;
95   hwc_procs_default_.hotplug = Hotplug;
96 
97   hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
98   hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_5;
99   hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module);
100   hwc_composer_device_1_t::common.close = Close;
101   hwc_composer_device_1_t::prepare = Prepare;
102   hwc_composer_device_1_t::set = Set;
103   hwc_composer_device_1_t::eventControl = EventControl;
104   hwc_composer_device_1_t::setPowerMode = SetPowerMode;
105   hwc_composer_device_1_t::query = Query;
106   hwc_composer_device_1_t::registerProcs = RegisterProcs;
107   hwc_composer_device_1_t::dump = Dump;
108   hwc_composer_device_1_t::getDisplayConfigs = GetDisplayConfigs;
109   hwc_composer_device_1_t::getDisplayAttributes = GetDisplayAttributes;
110   hwc_composer_device_1_t::getActiveConfig = GetActiveConfig;
111   hwc_composer_device_1_t::setActiveConfig = SetActiveConfig;
112   hwc_composer_device_1_t::setCursorPositionAsync = SetCursorPositionAsync;
113 }
114 
Init()115 int HWCSession::Init() {
116   int status = -EINVAL;
117   const char *qservice_name = "display.qservice";
118 
119   // Start QService and connect to it.
120   qService::QService::init();
121   android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
122                 android::defaultServiceManager()->getService(android::String16(qservice_name)));
123 
124   if (iqservice.get()) {
125     iqservice->connect(android::sp<qClient::IQClient>(this));
126     qservice_ = reinterpret_cast<qService::QService* >(iqservice.get());
127   } else {
128     DLOGE("Failed to acquire %s", qservice_name);
129     return -EINVAL;
130   }
131 
132   DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
133                                                  &buffer_sync_handler_, &core_intf_);
134   if (error != kErrorNone) {
135     DLOGE("Display core initialization failed. Error = %d", error);
136     return -EINVAL;
137   }
138 
139   // Read which display is first, and create it and store it in primary slot
140   HWDisplayInterfaceInfo hw_disp_info;
141   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
142   if (error == kErrorNone) {
143     if (hw_disp_info.type == kHDMI) {
144       // HDMI is primary display. If already connected, then create it and store in
145       // primary display slot. If not connected, create a NULL display for now.
146       HWCDebugHandler::Get()->SetProperty("persist.sys.is_hdmi_primary", "1");
147       is_hdmi_primary_ = true;
148       if (hw_disp_info.is_connected) {
149         status = HWCDisplayExternal::Create(core_intf_, &hwc_procs_, qservice_,
150                                             &hwc_display_[HWC_DISPLAY_PRIMARY]);
151         is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
152       } else {
153         // NullDisplay simply closes all its fences, and advertizes a standard
154         // resolution to SurfaceFlinger
155         status = HWCDisplayNull::Create(core_intf_, &hwc_procs_,
156                                         &hwc_display_[HWC_DISPLAY_PRIMARY]);
157       }
158     } else {
159       // Create and power on primary display
160       status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &hwc_procs_, qservice_,
161                                          &hwc_display_[HWC_DISPLAY_PRIMARY]);
162     }
163   } else {
164     // Create and power on primary display
165     status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &hwc_procs_, qservice_,
166                                        &hwc_display_[HWC_DISPLAY_PRIMARY]);
167   }
168 
169   if (status) {
170     CoreInterface::DestroyCore();
171     return status;
172   }
173 
174   color_mgr_ = HWCColorManager::CreateColorManager();
175   if (!color_mgr_) {
176     DLOGW("Failed to load HWCColorManager.");
177   }
178 
179   if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
180     DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
181     HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
182     hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
183     CoreInterface::DestroyCore();
184     return -errno;
185   }
186 
187   return 0;
188 }
189 
Deinit()190 int HWCSession::Deinit() {
191   HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
192   hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
193   if (color_mgr_) {
194     color_mgr_->DestroyColorManager();
195   }
196   uevent_thread_exit_ = true;
197   pthread_join(uevent_thread_, NULL);
198 
199   DisplayError error = CoreInterface::DestroyCore();
200   if (error != kErrorNone) {
201     DLOGE("Display core de-initialization failed. Error = %d", error);
202   }
203 
204   return 0;
205 }
206 
Open(const hw_module_t * module,const char * name,hw_device_t ** device)207 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
208   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
209 
210   if (!module || !name || !device) {
211     DLOGE("Invalid parameters.");
212     return -EINVAL;
213   }
214 
215   if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
216     HWCSession *hwc_session = new HWCSession(module);
217     if (!hwc_session) {
218       return -ENOMEM;
219     }
220 
221     int status = hwc_session->Init();
222     if (status != 0) {
223       delete hwc_session;
224       return status;
225     }
226 
227     hwc_composer_device_1_t *composer_device = hwc_session;
228     *device = reinterpret_cast<hw_device_t *>(composer_device);
229   }
230 
231   return 0;
232 }
233 
Close(hw_device_t * device)234 int HWCSession::Close(hw_device_t *device) {
235   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
236 
237   if (!device) {
238     return -EINVAL;
239   }
240 
241   hwc_composer_device_1_t *composer_device = reinterpret_cast<hwc_composer_device_1_t *>(device);
242   HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
243 
244   hwc_session->Deinit();
245   delete hwc_session;
246 
247   return 0;
248 }
249 
Prepare(hwc_composer_device_1 * device,size_t num_displays,hwc_display_contents_1_t ** displays)250 int HWCSession::Prepare(hwc_composer_device_1 *device, size_t num_displays,
251                         hwc_display_contents_1_t **displays) {
252   DTRACE_SCOPED();
253 
254   if (!device || !displays || num_displays > HWC_NUM_DISPLAY_TYPES) {
255     return -EINVAL;
256   }
257 
258   HWCSession *hwc_session = static_cast<HWCSession *>(device);
259   hwc_procs_t const *hwc_procs = NULL;
260   bool hotplug_connect = false;
261 
262   // Hold mutex only in this scope.
263   {
264     SEQUENCE_ENTRY_SCOPE_LOCK(locker_);
265 
266     hwc_procs = hwc_session->hwc_procs_;
267 
268     if (hwc_session->reset_panel_) {
269       DLOGW("panel is in bad state, resetting the panel");
270       hwc_session->ResetPanel();
271     }
272 
273     if (hwc_session->need_invalidate_) {
274       hwc_procs->invalidate(hwc_procs);
275     }
276 
277     hwc_session->HandleSecureDisplaySession(displays);
278 
279     if (hwc_session->color_mgr_) {
280       HWCDisplay *primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY];
281       if (primary_display) {
282         int ret = hwc_session->color_mgr_->SolidFillLayersPrepare(displays, primary_display);
283         if (ret)
284           return 0;
285       }
286     }
287 
288     for (ssize_t dpy = static_cast<ssize_t>(num_displays - 1); dpy >= 0; dpy--) {
289       hwc_display_contents_1_t *content_list = displays[dpy];
290       // If external display is connected, ignore virtual display content list.
291       // If virtual display content list is valid, connect virtual display if not connected.
292       // If virtual display content list is invalid, disconnect virtual display if connected.
293       // If external display connection is pending, connect external display when virtual
294       // display is destroyed.
295       // If HDMI is primary and the output format is YUV then ignore the virtual display
296       // content list.
297       if (dpy == HWC_DISPLAY_VIRTUAL) {
298         if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
299                 (hwc_session->is_hdmi_primary_ && hwc_session->is_hdmi_yuv_)) {
300           continue;
301         }
302 
303         bool valid_content = HWCDisplayVirtual::IsValidContentList(content_list);
304         bool connected = (hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL] != NULL);
305 
306         if (valid_content && !connected) {
307           hwc_session->ConnectDisplay(HWC_DISPLAY_VIRTUAL, content_list);
308         } else if (!valid_content && connected) {
309           hwc_session->DisconnectDisplay(HWC_DISPLAY_VIRTUAL);
310 
311           if (hwc_session->external_pending_connect_) {
312             DLOGI("Process pending external display connection");
313             hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL);
314             hwc_session->external_pending_connect_ = false;
315             hotplug_connect = true;
316           }
317         }
318       }
319 
320       if (hwc_session->hwc_display_[dpy]) {
321         if (!content_list) {
322           DLOGI("Display[%d] connected. content_list is null", dpy);
323         } else if (!content_list->numHwLayers) {
324           DLOGE("Display[%d] connected. numHwLayers is zero", dpy);
325         } else {
326           hwc_session->hwc_display_[dpy]->Prepare(content_list);
327         }
328       }
329     }
330   }
331 
332   if (hotplug_connect) {
333     // notify client
334     hwc_procs->hotplug(hwc_procs, HWC_DISPLAY_EXTERNAL, true);
335   }
336   // Return 0, else client will go into bad state
337   return 0;
338 }
339 
GetVsyncPeriod(int disp)340 int HWCSession::GetVsyncPeriod(int disp) {
341   SCOPE_LOCK(locker_);
342   // default value
343   int32_t vsync_period = 1000000000l / 60;
344   const uint32_t attribute = HWC_DISPLAY_VSYNC_PERIOD;
345 
346   if (hwc_display_[disp]) {
347     hwc_display_[disp]->GetDisplayAttributes(0, &attribute, &vsync_period);
348   }
349 
350   return vsync_period;
351 }
352 
Set(hwc_composer_device_1 * device,size_t num_displays,hwc_display_contents_1_t ** displays)353 int HWCSession::Set(hwc_composer_device_1 *device, size_t num_displays,
354                     hwc_display_contents_1_t **displays) {
355   DTRACE_SCOPED();
356 
357   SEQUENCE_EXIT_SCOPE_LOCK(locker_);
358 
359   if (!device || !displays || num_displays > HWC_NUM_DISPLAY_TYPES) {
360     return -EINVAL;
361   }
362 
363   HWCSession *hwc_session = static_cast<HWCSession *>(device);
364 
365   if (hwc_session->color_mgr_) {
366     HWCDisplay *primary_display = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY];
367     if (primary_display) {
368       int ret = hwc_session->color_mgr_->SolidFillLayersSet(displays, primary_display);
369       if (ret)
370         return 0;
371     }
372   }
373 
374   for (size_t dpy = 0; dpy < num_displays; dpy++) {
375     hwc_display_contents_1_t *content_list = displays[dpy];
376 
377     // Drop virtual display composition if virtual display object could not be created
378     // due to HDMI concurrency.
379     if (dpy == HWC_DISPLAY_VIRTUAL && !hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
380       CloseAcquireFds(content_list);
381       if (content_list) {
382         content_list->retireFenceFd = -1;
383       }
384 
385       continue;
386     }
387 
388     if (hwc_session->hwc_display_[dpy]) {
389       hwc_session->hwc_display_[dpy]->Commit(content_list);
390     }
391     CloseAcquireFds(content_list);
392   }
393 
394   if (hwc_session->new_bw_mode_) {
395     hwc_display_contents_1_t *content_list = displays[HWC_DISPLAY_PRIMARY];
396     hwc_session->new_bw_mode_ = false;
397     if (hwc_session->bw_mode_release_fd_ >= 0) {
398       close(hwc_session->bw_mode_release_fd_);
399     }
400     hwc_session->bw_mode_release_fd_ = dup(content_list->retireFenceFd);
401   }
402 
403   // This is only indicative of how many times SurfaceFlinger posts
404   // frames to the display.
405   CALC_FPS();
406 
407   // Return 0, else client will go into bad state
408   return 0;
409 }
410 
CloseAcquireFds(hwc_display_contents_1_t * content_list)411 void HWCSession::CloseAcquireFds(hwc_display_contents_1_t *content_list) {
412   if (content_list) {
413     for (size_t i = 0; i < content_list->numHwLayers; i++) {
414       int &acquireFenceFd = content_list->hwLayers[i].acquireFenceFd;
415       if (acquireFenceFd >= 0) {
416         close(acquireFenceFd);
417         acquireFenceFd = -1;
418       }
419     }
420 
421     int &outbufAcquireFenceFd = content_list->outbufAcquireFenceFd;
422     if (outbufAcquireFenceFd >= 0) {
423       close(outbufAcquireFenceFd);
424       outbufAcquireFenceFd = -1;
425     }
426   }
427 }
428 
IsDisplayYUV(int disp)429 bool HWCSession::IsDisplayYUV(int disp) {
430   int error = -EINVAL;
431   bool is_yuv = false;
432   DisplayConfigVariableInfo attributes = {};
433 
434   if (disp < 0 || disp >= HWC_NUM_DISPLAY_TYPES || !hwc_display_[disp]) {
435     DLOGE("Invalid input parameters. Display = %d", disp);
436     return is_yuv;
437   }
438 
439   uint32_t active_config = 0;
440   error = hwc_display_[disp]->GetActiveDisplayConfig(&active_config);
441   if (!error) {
442     error = hwc_display_[disp]->GetDisplayAttributesForConfig(INT(active_config), &attributes);
443     if (error == 0) {
444       is_yuv = attributes.is_yuv;
445     } else {
446       DLOGW("Error querying display attributes. Display = %d, Config = %d", disp, active_config);
447     }
448   }
449 
450   return is_yuv;
451 }
452 
EventControl(hwc_composer_device_1 * device,int disp,int event,int enable)453 int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
454   if (!device) {
455     return -EINVAL;
456   }
457 
458   HWCSession *hwc_session = static_cast<HWCSession *>(device);
459   int status = -EINVAL;
460   if (hwc_session->hwc_display_[disp]) {
461     status = hwc_session->hwc_display_[disp]->EventControl(event, enable);
462   }
463 
464   return status;
465 }
466 
SetPowerMode(hwc_composer_device_1 * device,int disp,int mode)467 int HWCSession::SetPowerMode(hwc_composer_device_1 *device, int disp, int mode) {
468   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
469 
470   if (!device) {
471     return -EINVAL;
472   }
473 
474   HWCSession *hwc_session = static_cast<HWCSession *>(device);
475   int status = -EINVAL;
476   if (hwc_session->hwc_display_[disp]) {
477     status = hwc_session->hwc_display_[disp]->SetPowerMode(mode);
478   }
479   if (disp == HWC_DISPLAY_PRIMARY && hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
480     // Set the power mode for virtual display while setting power mode for primary, as SF
481     // does not invoke SetPowerMode() for virtual display.
482     status = hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(mode);
483   }
484 
485   return status;
486 }
487 
Query(hwc_composer_device_1 * device,int param,int * value)488 int HWCSession::Query(hwc_composer_device_1 *device, int param, int *value) {
489   SCOPE_LOCK(locker_);
490 
491   if (!device || !value) {
492     return -EINVAL;
493   }
494 
495   int status = 0;
496 
497   switch (param) {
498   case HWC_BACKGROUND_LAYER_SUPPORTED:
499     value[0] = 1;
500     break;
501 
502   default:
503     status = -EINVAL;
504   }
505 
506   return status;
507 }
508 
RegisterProcs(hwc_composer_device_1 * device,hwc_procs_t const * procs)509 void HWCSession::RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs) {
510   SCOPE_LOCK(locker_);
511 
512   if (!device || !procs) {
513     return;
514   }
515 
516   HWCSession *hwc_session = static_cast<HWCSession *>(device);
517   hwc_session->hwc_procs_ = procs;
518 }
519 
Dump(hwc_composer_device_1 * device,char * buffer,int length)520 void HWCSession::Dump(hwc_composer_device_1 *device, char *buffer, int length) {
521   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
522 
523   if (!device || !buffer || !length) {
524     return;
525   }
526 
527   DumpInterface::GetDump(buffer, UINT32(length));
528 }
529 
GetDisplayConfigs(hwc_composer_device_1 * device,int disp,uint32_t * configs,size_t * num_configs)530 int HWCSession::GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs,
531                                   size_t *num_configs) {
532   SCOPE_LOCK(locker_);
533 
534   if (!device || !configs || !num_configs) {
535     return -EINVAL;
536   }
537 
538   if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
539     return -EINVAL;
540   }
541 
542   HWCSession *hwc_session = static_cast<HWCSession *>(device);
543   int status = -EINVAL;
544   if (hwc_session->hwc_display_[disp]) {
545     status = hwc_session->hwc_display_[disp]->GetDisplayConfigs(configs, num_configs);
546   }
547 
548   return status;
549 }
550 
GetDisplayAttributes(hwc_composer_device_1 * device,int disp,uint32_t config,const uint32_t * display_attributes,int32_t * values)551 int HWCSession::GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
552                                      const uint32_t *display_attributes, int32_t *values) {
553   SCOPE_LOCK(locker_);
554 
555   if (!device || !display_attributes || !values) {
556     return -EINVAL;
557   }
558 
559   if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
560     return -EINVAL;
561   }
562 
563   HWCSession *hwc_session = static_cast<HWCSession *>(device);
564   int status = -EINVAL;
565   if (hwc_session->hwc_display_[disp]) {
566     status = hwc_session->hwc_display_[disp]->GetDisplayAttributes(config, display_attributes,
567                                                                    values);
568   }
569 
570   return status;
571 }
572 
GetActiveConfig(hwc_composer_device_1 * device,int disp)573 int HWCSession::GetActiveConfig(hwc_composer_device_1 *device, int disp) {
574   SCOPE_LOCK(locker_);
575 
576   if (!device) {
577     return -EINVAL;
578   }
579 
580   if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
581     return -EINVAL;
582   }
583 
584   HWCSession *hwc_session = static_cast<HWCSession *>(device);
585   int active_config = -1;
586   if (hwc_session->hwc_display_[disp]) {
587     active_config = hwc_session->hwc_display_[disp]->GetActiveConfig();
588   }
589 
590   return active_config;
591 }
592 
SetActiveConfig(hwc_composer_device_1 * device,int disp,int index)593 int HWCSession::SetActiveConfig(hwc_composer_device_1 *device, int disp, int index) {
594   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
595 
596   if (!device) {
597     return -EINVAL;
598   }
599 
600   if (disp < HWC_DISPLAY_PRIMARY || disp >  HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
601     return -EINVAL;
602   }
603 
604   HWCSession *hwc_session = static_cast<HWCSession *>(device);
605   int status = -EINVAL;
606 
607   if (hwc_session->hwc_display_[disp]) {
608     status = hwc_session->hwc_display_[disp]->SetActiveConfig(index);
609   }
610 
611   return status;
612 }
613 
SetCursorPositionAsync(hwc_composer_device_1 * device,int disp,int x,int y)614 int HWCSession::SetCursorPositionAsync(hwc_composer_device_1 *device, int disp, int x, int y) {
615   DTRACE_SCOPED();
616 
617   SCOPE_LOCK(locker_);
618 
619   if (!device || (disp < HWC_DISPLAY_PRIMARY) || (disp > HWC_DISPLAY_VIRTUAL)) {
620     return -EINVAL;
621   }
622 
623   int status = -EINVAL;
624   HWCSession *hwc_session = static_cast<HWCSession *>(device);
625   if (hwc_session->hwc_display_[disp]) {
626     status = hwc_session->hwc_display_[disp]->SetCursorPosition(x, y);
627   }
628 
629   return status;
630 }
631 
ConnectDisplay(int disp,hwc_display_contents_1_t * content_list)632 int HWCSession::ConnectDisplay(int disp, hwc_display_contents_1_t *content_list) {
633   DLOGI("Display = %d", disp);
634 
635   int status = 0;
636   uint32_t primary_width = 0;
637   uint32_t primary_height = 0;
638 
639   hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
640 
641   if (disp == HWC_DISPLAY_EXTERNAL) {
642     status = HWCDisplayExternal::Create(core_intf_, &hwc_procs_, primary_width, primary_height,
643                                         qservice_, false, &hwc_display_[disp]);
644   } else if (disp == HWC_DISPLAY_VIRTUAL) {
645     status = HWCDisplayVirtual::Create(core_intf_, &hwc_procs_, primary_width, primary_height,
646                                        content_list, &hwc_display_[disp]);
647   } else {
648     DLOGE("Invalid display type");
649     return -1;
650   }
651 
652   if (!status) {
653     hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
654   }
655 
656   return status;
657 }
658 
DisconnectDisplay(int disp)659 int HWCSession::DisconnectDisplay(int disp) {
660   DLOGI("Display = %d", disp);
661 
662   if (disp == HWC_DISPLAY_EXTERNAL) {
663     HWCDisplayExternal::Destroy(hwc_display_[disp]);
664   } else if (disp == HWC_DISPLAY_VIRTUAL) {
665     HWCDisplayVirtual::Destroy(hwc_display_[disp]);
666   } else {
667     DLOGE("Invalid display type");
668     return -1;
669   }
670 
671   hwc_display_[disp] = NULL;
672 
673   return 0;
674 }
675 
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)676 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
677                                              android::Parcel *output_parcel) {
678   SEQUENCE_WAIT_SCOPE_LOCK(locker_);
679 
680   android::status_t status = 0;
681 
682   switch (command) {
683   case qService::IQService::DYNAMIC_DEBUG:
684     DynamicDebug(input_parcel);
685     break;
686 
687   case qService::IQService::SCREEN_REFRESH:
688     hwc_procs_->invalidate(hwc_procs_);
689     break;
690 
691   case qService::IQService::SET_IDLE_TIMEOUT:
692     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
693       uint32_t timeout = UINT32(input_parcel->readInt32());
694       hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout);
695     }
696     break;
697 
698   case qService::IQService::SET_FRAME_DUMP_CONFIG:
699     SetFrameDumpConfig(input_parcel);
700     break;
701 
702   case qService::IQService::SET_MAX_PIPES_PER_MIXER:
703     status = SetMaxMixerStages(input_parcel);
704     break;
705 
706   case qService::IQService::SET_DISPLAY_MODE:
707     status = SetDisplayMode(input_parcel);
708     break;
709 
710   case qService::IQService::SET_SECONDARY_DISPLAY_STATUS:
711     status = SetSecondaryDisplayStatus(input_parcel, output_parcel);
712     break;
713 
714   case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
715     status = ConfigureRefreshRate(input_parcel);
716     break;
717 
718   case qService::IQService::SET_VIEW_FRAME:
719     break;
720 
721   case qService::IQService::TOGGLE_SCREEN_UPDATES:
722     status = ToggleScreenUpdates(input_parcel, output_parcel);
723     break;
724 
725   case qService::IQService::QDCM_SVC_CMDS:
726     status = QdcmCMDHandler(input_parcel, output_parcel);
727     break;
728 
729   case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED:
730     status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel);
731     break;
732 
733   case qService::IQService::CONTROL_PARTIAL_UPDATE:
734     status = ControlPartialUpdate(input_parcel, output_parcel);
735     break;
736 
737   case qService::IQService::SET_ACTIVE_CONFIG:
738     status = HandleSetActiveDisplayConfig(input_parcel, output_parcel);
739     break;
740 
741   case qService::IQService::GET_ACTIVE_CONFIG:
742     status = HandleGetActiveDisplayConfig(input_parcel, output_parcel);
743     break;
744 
745   case qService::IQService::GET_CONFIG_COUNT:
746     status = HandleGetDisplayConfigCount(input_parcel, output_parcel);
747     break;
748 
749   case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
750     status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
751     break;
752 
753   case qService::IQService::GET_PANEL_BRIGHTNESS:
754     status = GetPanelBrightness(input_parcel, output_parcel);
755     break;
756 
757   case qService::IQService::SET_PANEL_BRIGHTNESS:
758     status = SetPanelBrightness(input_parcel, output_parcel);
759     break;
760 
761   case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
762     status = GetVisibleDisplayRect(input_parcel, output_parcel);
763     break;
764 
765   case qService::IQService::SET_CAMERA_STATUS:
766     status = SetDynamicBWForCamera(input_parcel, output_parcel);
767     break;
768 
769   case qService::IQService::GET_BW_TRANSACTION_STATUS:
770     status = GetBWTransactionStatus(input_parcel, output_parcel);
771     break;
772 
773   case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
774     status = SetMixerResolution(input_parcel);
775     break;
776 
777   default:
778     DLOGW("QService command = %d is not supported", command);
779     return -EINVAL;
780   }
781 
782   return status;
783 }
784 
ToggleScreenUpdates(const android::Parcel * input_parcel,android::Parcel * output_parcel)785 android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel,
786                                                   android::Parcel *output_parcel) {
787   int input = input_parcel->readInt32();
788   int error = android::BAD_VALUE;
789 
790   if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) {
791     error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1);
792     if (error != 0) {
793       DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error);
794     }
795   }
796   output_parcel->writeInt32(error);
797 
798   return error;
799 }
800 
SetPanelBrightness(const android::Parcel * input_parcel,android::Parcel * output_parcel)801 android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel,
802                                                  android::Parcel *output_parcel) {
803   int level = input_parcel->readInt32();
804   int error = android::BAD_VALUE;
805 
806   if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
807     error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level);
808     if (error != 0) {
809       DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
810     }
811   }
812   output_parcel->writeInt32(error);
813 
814   return error;
815 }
816 
GetPanelBrightness(const android::Parcel * input_parcel,android::Parcel * output_parcel)817 android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel,
818                                                  android::Parcel *output_parcel) {
819   int error = android::BAD_VALUE;
820   int ret = error;
821 
822   if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
823     error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret);
824     if (error != 0) {
825       ret = error;
826       DLOGE("Failed to get the panel brightness. Error = %d", error);
827     }
828   }
829   output_parcel->writeInt32(ret);
830 
831   return error;
832 }
833 
ControlPartialUpdate(const android::Parcel * input_parcel,android::Parcel * out)834 android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
835                                                    android::Parcel *out) {
836   DisplayError error = kErrorNone;
837   int ret = 0;
838   uint32_t disp_id = UINT32(input_parcel->readInt32());
839   uint32_t enable = UINT32(input_parcel->readInt32());
840 
841   if (disp_id != HWC_DISPLAY_PRIMARY) {
842     DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
843     ret = -EINVAL;
844     out->writeInt32(ret);
845     return ret;
846   }
847 
848   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
849     DLOGE("primary display object is not instantiated");
850     ret = -EINVAL;
851     out->writeInt32(ret);
852     return ret;
853   }
854 
855   uint32_t pending = 0;
856   error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending);
857 
858   if (error == kErrorNone) {
859     if (!pending) {
860       out->writeInt32(ret);
861       return ret;
862     }
863   } else if (error == kErrorNotSupported) {
864     out->writeInt32(ret);
865     return ret;
866   } else {
867     ret = -EINVAL;
868     out->writeInt32(ret);
869     return ret;
870   }
871 
872   // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
873   hwc_procs_->invalidate(hwc_procs_);
874 
875   // Wait until partial update control is complete
876   ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
877 
878   out->writeInt32(ret);
879 
880   return ret;
881 }
882 
HandleSetActiveDisplayConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)883 android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
884                                                      android::Parcel *output_parcel) {
885   int config = input_parcel->readInt32();
886   int dpy = input_parcel->readInt32();
887   int error = android::BAD_VALUE;
888 
889   if (dpy > HWC_DISPLAY_VIRTUAL) {
890     return android::BAD_VALUE;
891   }
892 
893   if (hwc_display_[dpy]) {
894     error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
895     if (error == 0) {
896       hwc_procs_->invalidate(hwc_procs_);
897     }
898   }
899 
900   return error;
901 }
902 
HandleGetActiveDisplayConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)903 android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
904                                                            android::Parcel *output_parcel) {
905   int dpy = input_parcel->readInt32();
906   int error = android::BAD_VALUE;
907 
908   if (dpy > HWC_DISPLAY_VIRTUAL) {
909     return android::BAD_VALUE;
910   }
911 
912   if (hwc_display_[dpy]) {
913     uint32_t config = 0;
914     error = hwc_display_[dpy]->GetActiveDisplayConfig(&config);
915     if (error == 0) {
916       output_parcel->writeInt32(INT(config));
917     }
918   }
919 
920   return error;
921 }
922 
HandleGetDisplayConfigCount(const android::Parcel * input_parcel,android::Parcel * output_parcel)923 android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
924                                                           android::Parcel *output_parcel) {
925   int dpy = input_parcel->readInt32();
926   int error = android::BAD_VALUE;
927 
928   if (dpy > HWC_DISPLAY_VIRTUAL) {
929     return android::BAD_VALUE;
930   }
931 
932   uint32_t count = 0;
933   if (hwc_display_[dpy]) {
934     error = hwc_display_[dpy]->GetDisplayConfigCount(&count);
935     if (error == 0) {
936       output_parcel->writeInt32(INT(count));
937     }
938   }
939 
940   return error;
941 }
942 
HandleGetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)943 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
944                                                                   *input_parcel,
945                                                                   android::Parcel *output_parcel) {
946   int config = input_parcel->readInt32();
947   int dpy = input_parcel->readInt32();
948   int error = android::BAD_VALUE;
949   DisplayConfigVariableInfo display_attributes;
950 
951   if (dpy > HWC_DISPLAY_VIRTUAL) {
952     return android::BAD_VALUE;
953   }
954 
955   if (hwc_display_[dpy]) {
956     error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
957     if (error == 0) {
958       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
959       output_parcel->writeInt32(INT(display_attributes.x_pixels));
960       output_parcel->writeInt32(INT(display_attributes.y_pixels));
961       output_parcel->writeFloat(display_attributes.x_dpi);
962       output_parcel->writeFloat(display_attributes.y_dpi);
963       output_parcel->writeInt32(0);  // Panel type, unsupported.
964       output_parcel->writeInt32(display_attributes.is_yuv);
965     }
966   }
967 
968   return error;
969 }
970 
SetSecondaryDisplayStatus(const android::Parcel * input_parcel,android::Parcel * output_parcel)971 android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
972                                                         android::Parcel *output_parcel) {
973   int ret = -EINVAL;
974 
975   uint32_t display_id = UINT32(input_parcel->readInt32());
976   uint32_t display_status = UINT32(input_parcel->readInt32());
977 
978   DLOGI("Display = %d, Status = %d", display_id, display_status);
979 
980   if (display_id >= HWC_NUM_DISPLAY_TYPES) {
981     DLOGE("Invalid display_id");
982   } else if (display_id == HWC_DISPLAY_PRIMARY) {
983     DLOGE("Not supported for this display");
984   } else if (!hwc_display_[display_id]) {
985     DLOGW("Display is not connected");
986   } else {
987     ret = hwc_display_[display_id]->SetDisplayStatus(display_status);
988   }
989 
990   output_parcel->writeInt32(ret);
991 
992   return ret;
993 }
994 
ConfigureRefreshRate(const android::Parcel * input_parcel)995 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
996   uint32_t operation = UINT32(input_parcel->readInt32());
997   switch (operation) {
998     case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
999       return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
1000           HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
1001     case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
1002       return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
1003           HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
1004     case qdutils::SET_BINDER_DYN_REFRESH_RATE:
1005       {
1006         uint32_t refresh_rate = UINT32(input_parcel->readInt32());
1007         return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
1008             HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE,
1009             refresh_rate);
1010       }
1011     default:
1012       DLOGW("Invalid operation %d", operation);
1013       return -EINVAL;
1014   }
1015 
1016   return 0;
1017 }
1018 
SetDisplayMode(const android::Parcel * input_parcel)1019 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
1020   uint32_t mode = UINT32(input_parcel->readInt32());
1021   return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
1022 }
1023 
SetMaxMixerStages(const android::Parcel * input_parcel)1024 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
1025   DisplayError error = kErrorNone;
1026   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1027   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
1028 
1029   if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
1030     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1031       error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
1032       if (error != kErrorNone) {
1033         return -EINVAL;
1034       }
1035     }
1036   }
1037 
1038   if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
1039     if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1040       error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
1041       if (error != kErrorNone) {
1042         return -EINVAL;
1043       }
1044     }
1045   }
1046 
1047   if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
1048     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1049       error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
1050       if (error != kErrorNone) {
1051         return -EINVAL;
1052       }
1053     }
1054   }
1055 
1056   return 0;
1057 }
1058 
SetDynamicBWForCamera(const android::Parcel * input_parcel,android::Parcel * output_parcel)1059 android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel,
1060                                                     android::Parcel *output_parcel) {
1061   DisplayError error = kErrorNone;
1062   uint32_t camera_status = UINT32(input_parcel->readInt32());
1063   HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
1064 
1065   // trigger invalidate to apply new bw caps.
1066   hwc_procs_->invalidate(hwc_procs_);
1067 
1068     error = core_intf_->SetMaxBandwidthMode(mode);
1069   if (error != kErrorNone) {
1070       return -EINVAL;
1071   }
1072 
1073   new_bw_mode_ = true;
1074   need_invalidate_ = true;
1075 
1076   return 0;
1077 }
1078 
GetBWTransactionStatus(const android::Parcel * input_parcel,android::Parcel * output_parcel)1079 android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel,
1080                                                      android::Parcel *output_parcel)  {
1081   bool state = true;
1082 
1083   if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1084     if (sync_wait(bw_mode_release_fd_, 0) < 0) {
1085       DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno));
1086       state = false;
1087     }
1088     output_parcel->writeInt32(state);
1089   }
1090 
1091   return 0;
1092 }
1093 
SetFrameDumpConfig(const android::Parcel * input_parcel)1094 void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
1095   uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
1096   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1097   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
1098 
1099   if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
1100     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1101       hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
1102     }
1103   }
1104 
1105   if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
1106     if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1107       hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
1108     }
1109   }
1110 
1111   if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
1112     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1113       hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
1114     }
1115   }
1116 }
1117 
SetMixerResolution(const android::Parcel * input_parcel)1118 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
1119   DisplayError error = kErrorNone;
1120   uint32_t dpy = UINT32(input_parcel->readInt32());
1121 
1122   if (dpy != HWC_DISPLAY_PRIMARY) {
1123     DLOGI("Resoulution change not supported for this display %d", dpy);
1124     return -EINVAL;
1125   }
1126 
1127   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1128     DLOGI("Primary display is not initialized");
1129     return -EINVAL;
1130   }
1131 
1132   uint32_t width = UINT32(input_parcel->readInt32());
1133   uint32_t height = UINT32(input_parcel->readInt32());
1134 
1135   error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
1136   if (error != kErrorNone) {
1137     return -EINVAL;
1138   }
1139 
1140   return 0;
1141 }
1142 
DynamicDebug(const android::Parcel * input_parcel)1143 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
1144   int type = input_parcel->readInt32();
1145   bool enable = (input_parcel->readInt32() > 0);
1146   DLOGI("type = %d enable = %d", type, enable);
1147   int verbose_level = input_parcel->readInt32();
1148 
1149   switch (type) {
1150   case qService::IQService::DEBUG_ALL:
1151     HWCDebugHandler::DebugAll(enable, verbose_level);
1152     break;
1153 
1154   case qService::IQService::DEBUG_MDPCOMP:
1155     HWCDebugHandler::DebugStrategy(enable, verbose_level);
1156     HWCDebugHandler::DebugCompManager(enable, verbose_level);
1157     break;
1158 
1159   case qService::IQService::DEBUG_PIPE_LIFECYCLE:
1160     HWCDebugHandler::DebugResources(enable, verbose_level);
1161     break;
1162 
1163   case qService::IQService::DEBUG_DRIVER_CONFIG:
1164     HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1165     break;
1166 
1167   case qService::IQService::DEBUG_ROTATOR:
1168     HWCDebugHandler::DebugResources(enable, verbose_level);
1169     HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1170     HWCDebugHandler::DebugRotator(enable, verbose_level);
1171     break;
1172 
1173   case qService::IQService::DEBUG_QDCM:
1174     HWCDebugHandler::DebugQdcm(enable, verbose_level);
1175     break;
1176 
1177   default:
1178     DLOGW("type = %d is not supported", type);
1179   }
1180 }
1181 
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)1182 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
1183                                              android::Parcel *output_parcel) {
1184   int ret = 0;
1185   int32_t *brightness_value = NULL;
1186   uint32_t display_id(0);
1187   PPPendingParams pending_action;
1188   PPDisplayAPIPayload resp_payload, req_payload;
1189 
1190   if (!color_mgr_) {
1191     return -1;
1192   }
1193 
1194   pending_action.action = kNoAction;
1195   pending_action.params = NULL;
1196 
1197   // Read display_id, payload_size and payload from in_parcel.
1198   ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
1199   if (!ret) {
1200     if (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY])
1201       ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload,
1202                                                                   &resp_payload, &pending_action);
1203 
1204     if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL])
1205       ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload,
1206                                                                   &pending_action);
1207   }
1208 
1209   if (ret) {
1210     output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
1211     req_payload.DestroyPayload();
1212     resp_payload.DestroyPayload();
1213     return ret;
1214   }
1215 
1216   switch (pending_action.action) {
1217     case kInvalidating:
1218       hwc_procs_->invalidate(hwc_procs_);
1219       break;
1220     case kEnterQDCMMode:
1221       ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1222       break;
1223     case kExitQDCMMode:
1224       ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1225       break;
1226     case kApplySolidFill:
1227       ret = color_mgr_->SetSolidFill(pending_action.params,
1228                                      true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1229       hwc_procs_->invalidate(hwc_procs_);
1230       break;
1231     case kDisableSolidFill:
1232       ret = color_mgr_->SetSolidFill(pending_action.params,
1233                                      false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1234       hwc_procs_->invalidate(hwc_procs_);
1235       break;
1236     case kSetPanelBrightness:
1237       brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
1238       if (brightness_value == NULL) {
1239         DLOGE("Brightness value is Null");
1240         return -EINVAL;
1241       }
1242       if (HWC_DISPLAY_PRIMARY == display_id)
1243         ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
1244       break;
1245     case kEnableFrameCapture:
1246       ret = color_mgr_->SetFrameCapture(pending_action.params,
1247                                         true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1248       hwc_procs_->invalidate(hwc_procs_);
1249       break;
1250     case kDisableFrameCapture:
1251       ret = color_mgr_->SetFrameCapture(pending_action.params,
1252                                         false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1253       break;
1254     case kNoAction:
1255       break;
1256     default:
1257       DLOGW("Invalid pending action = %d!", pending_action.action);
1258       break;
1259   }
1260 
1261   // for display API getter case, marshall returned params into out_parcel.
1262   output_parcel->writeInt32(ret);
1263   HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
1264   req_payload.DestroyPayload();
1265   resp_payload.DestroyPayload();
1266 
1267   return (ret? -EINVAL : 0);
1268 }
1269 
OnMinHdcpEncryptionLevelChange(const android::Parcel * input_parcel,android::Parcel * output_parcel)1270 android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
1271                                                              android::Parcel *output_parcel) {
1272   int ret = -EINVAL;
1273   uint32_t display_id = UINT32(input_parcel->readInt32());
1274   uint32_t min_enc_level = UINT32(input_parcel->readInt32());
1275 
1276   DLOGI("Display %d", display_id);
1277 
1278   if (display_id >= HWC_NUM_DISPLAY_TYPES) {
1279     DLOGE("Invalid display_id");
1280   } else if (display_id != HWC_DISPLAY_EXTERNAL) {
1281     DLOGE("Not supported for display");
1282   } else if (!hwc_display_[display_id]) {
1283     DLOGW("Display is not connected");
1284   } else {
1285     ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
1286   }
1287 
1288   output_parcel->writeInt32(ret);
1289 
1290   return ret;
1291 }
1292 
HWCUeventThread(void * context)1293 void* HWCSession::HWCUeventThread(void *context) {
1294   if (context) {
1295     return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
1296   }
1297 
1298   return NULL;
1299 }
1300 
HWCUeventThreadHandler()1301 void* HWCSession::HWCUeventThreadHandler() {
1302   static char uevent_data[PAGE_SIZE];
1303   int length = 0;
1304   prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
1305   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
1306   if (!uevent_init()) {
1307     DLOGE("Failed to init uevent");
1308     pthread_exit(0);
1309     return NULL;
1310   }
1311 
1312   while (!uevent_thread_exit_) {
1313     // keep last 2 zeroes to ensure double 0 termination
1314     length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
1315 
1316     if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
1317       DLOGI("Uevent HDMI = %s", uevent_data);
1318       int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
1319       if (connected >= 0) {
1320         DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
1321         if (HotPlugHandler(connected) == -1) {
1322           DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
1323         }
1324       }
1325     } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
1326       DLOGI("Uevent FB0 = %s", uevent_data);
1327       int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
1328       if (panel_reset == 0) {
1329         if (hwc_procs_) {
1330           reset_panel_ = true;
1331           hwc_procs_->invalidate(hwc_procs_);
1332         } else {
1333           DLOGW("Ignore resetpanel - hwc_proc not registered");
1334         }
1335       }
1336     }
1337   }
1338   pthread_exit(0);
1339 
1340   return NULL;
1341 }
1342 
GetEventValue(const char * uevent_data,int length,const char * event_info)1343 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
1344   const char *iterator_str = uevent_data;
1345   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
1346     const char *pstr = strstr(iterator_str, event_info);
1347     if (pstr != NULL) {
1348       return (atoi(iterator_str + strlen(event_info)));
1349     }
1350     iterator_str += strlen(iterator_str) + 1;
1351   }
1352 
1353   return -1;
1354 }
1355 
ResetPanel()1356 void HWCSession::ResetPanel() {
1357   int status = -EINVAL;
1358 
1359   DLOGI("Powering off primary");
1360   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC_POWER_MODE_OFF);
1361   if (status) {
1362     DLOGE("power-off on primary failed with error = %d", status);
1363   }
1364 
1365   DLOGI("Restoring power mode on primary");
1366   int32_t mode = INT(hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode());
1367   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
1368   if (status) {
1369     DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
1370   }
1371 
1372   status = hwc_display_[HWC_DISPLAY_PRIMARY]->EventControl(HWC_EVENT_VSYNC, 1);
1373   if (status) {
1374     DLOGE("enabling vsync failed for primary with error = %d", status);
1375   }
1376 
1377   reset_panel_ = false;
1378 }
1379 
HotPlugHandler(bool connected)1380 int HWCSession::HotPlugHandler(bool connected) {
1381   int status = 0;
1382   bool notify_hotplug = false;
1383 
1384   // To prevent sending events to client while a lock is held, acquire scope locks only within
1385   // below scope so that those get automatically unlocked after the scope ends.
1386   {
1387     SEQUENCE_WAIT_SCOPE_LOCK(locker_);
1388 
1389     if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1390       DLOGE("Primay display is not connected.");
1391       return -1;
1392     }
1393 
1394 
1395     HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
1396     HWCDisplay *external_display = NULL;
1397     HWCDisplay *null_display = NULL;
1398 
1399     if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) {
1400       external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
1401     } else if (primary_display->GetDisplayClass() == DISPLAY_CLASS_NULL) {
1402       null_display = static_cast<HWCDisplayNull *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
1403     }
1404 
1405     // If primary display connected is a NULL display, then replace it with the external display
1406     if (connected) {
1407       // If we are in HDMI as primary and the primary display just got plugged in
1408       if (is_hdmi_primary_ && null_display) {
1409         uint32_t primary_width, primary_height;
1410         null_display->GetFrameBufferResolution(&primary_width, &primary_height);
1411         delete null_display;
1412         hwc_display_[HWC_DISPLAY_PRIMARY] = NULL;
1413 
1414         // Create external display with a forced framebuffer resolution to that of what the NULL
1415         // display had. This is necessary because SurfaceFlinger does not dynamically update
1416         // framebuffer resolution once it reads it at bootup. So we always have to have the NULL
1417         // display/external display both at the bootup resolution.
1418         int status = HWCDisplayExternal::Create(core_intf_, &hwc_procs_, primary_width,
1419                                                 primary_height, qservice_, true,
1420                                                 &hwc_display_[HWC_DISPLAY_PRIMARY]);
1421         if (status) {
1422           DLOGE("Could not create external display");
1423           return -1;
1424         }
1425 
1426         is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
1427 
1428         // Next, go ahead and enable vsync on external display. This is expliclity required
1429         // because in HDMI as primary case, SurfaceFlinger may not be aware of underlying
1430         // changing display. and thus may not explicitly enable vsync
1431 
1432         status = hwc_display_[HWC_DISPLAY_PRIMARY]->EventControl(HWC_EVENT_VSYNC, true);
1433         if (status) {
1434           DLOGE("Error enabling vsync for HDMI as primary case");
1435         }
1436         // Don't do hotplug notification for HDMI as primary case for now
1437         notify_hotplug = false;
1438       } else {
1439         if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1440           DLOGE("HDMI is already connected");
1441           return -1;
1442         }
1443 
1444         // Connect external display if virtual display is not connected.
1445         // Else, defer external display connection and process it when virtual display
1446         // tears down; Do not notify SurfaceFlinger since connection is deferred now.
1447         if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1448           status = ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL);
1449           if (status) {
1450             return status;
1451           }
1452           notify_hotplug = true;
1453         } else {
1454           DLOGI("Virtual display is connected, pending connection");
1455           external_pending_connect_ = true;
1456         }
1457       }
1458     } else {
1459       // Do not return error if external display is not in connected status.
1460       // Due to virtual display concurrency, external display connection might be still pending
1461       // but hdmi got disconnected before pending connection could be processed.
1462 
1463       if (is_hdmi_primary_ && external_display) {
1464         uint32_t x_res, y_res;
1465         external_display->GetFrameBufferResolution(&x_res, &y_res);
1466         // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases
1467         // for HDMI as primary
1468         external_display->EventControl(HWC_EVENT_VSYNC, false);
1469         HWCDisplayExternal::Destroy(external_display);
1470 
1471         HWCDisplayNull *null_display;
1472 
1473         int status = HWCDisplayNull::Create(core_intf_, &hwc_procs_,
1474                                             reinterpret_cast<HWCDisplay **>(&null_display));
1475 
1476         if (status) {
1477           DLOGE("Could not create Null display when primary got disconnected");
1478           return -1;
1479         }
1480 
1481         null_display->SetResolution(x_res, y_res);
1482         hwc_display_[HWC_DISPLAY_PRIMARY] = null_display;
1483 
1484         // Don't do hotplug notification for HDMI as primary case for now
1485         notify_hotplug = false;
1486       } else {
1487         if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1488           status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
1489           notify_hotplug = true;
1490         }
1491         external_pending_connect_ = false;
1492       }
1493     }
1494   }
1495 
1496   if (connected && notify_hotplug) {
1497     // trigger screen refresh to ensure sufficient resources are available to process new
1498     // new display connection.
1499     hwc_procs_->invalidate(hwc_procs_);
1500     uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
1501     usleep(vsync_period * 2 / 1000);
1502   }
1503   // notify client
1504   if (notify_hotplug) {
1505     hwc_procs_->hotplug(hwc_procs_, HWC_DISPLAY_EXTERNAL, connected);
1506   }
1507 
1508   qservice_->onHdmiHotplug(INT(connected));
1509 
1510   return 0;
1511 }
1512 
HandleSecureDisplaySession(hwc_display_contents_1_t ** displays)1513 void HWCSession::HandleSecureDisplaySession(hwc_display_contents_1_t **displays) {
1514   secure_display_active_ = false;
1515   if (!*displays) {
1516     DLOGW("Invalid display contents");
1517     return;
1518   }
1519 
1520   hwc_display_contents_1_t *content_list = displays[HWC_DISPLAY_PRIMARY];
1521   if (!content_list) {
1522     DLOGW("Invalid primary content list");
1523     return;
1524   }
1525   size_t num_hw_layers = content_list->numHwLayers;
1526 
1527   for (size_t i = 0; i < num_hw_layers - 1; i++) {
1528     hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
1529     const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
1530     if (pvt_handle && pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
1531       secure_display_active_ = true;
1532     }
1533   }
1534 
1535   for (ssize_t dpy = static_cast<ssize_t>(HWC_NUM_DISPLAY_TYPES - 1); dpy >= 0; dpy--) {
1536     if (hwc_display_[dpy]) {
1537       hwc_display_[dpy]->SetSecureDisplay(secure_display_active_);
1538     }
1539   }
1540 }
1541 
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)1542 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
1543                                                     android::Parcel *output_parcel) {
1544   int dpy = input_parcel->readInt32();
1545 
1546   if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
1547     return android::BAD_VALUE;;
1548   }
1549 
1550   if (!hwc_display_[dpy]) {
1551     return android::NO_INIT;
1552   }
1553 
1554   hwc_rect_t visible_rect = {0, 0, 0, 0};
1555   int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
1556   if (error < 0) {
1557     return error;
1558   }
1559 
1560   output_parcel->writeInt32(visible_rect.left);
1561   output_parcel->writeInt32(visible_rect.top);
1562   output_parcel->writeInt32(visible_rect.right);
1563   output_parcel->writeInt32(visible_rect.bottom);
1564 
1565   return android::NO_ERROR;
1566 }
1567 
1568 }  // namespace sdm
1569 
1570