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