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