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