blob: d6fc69562b1c070bf941e0fab958d0dcd8f6a551 [file] [log] [blame]
Haoxiang Li95917b12019-11-15 11:29:05 -08001//
2// Copyright (C) 2019 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080016
17#include <utility>
18
Haoxiang Li95917b12019-11-15 11:29:05 -080019#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
20
Changyeon Jo4ff8fb02020-02-05 21:56:59 -080021#include "AutomotiveDisplayProxyService.h"
Haoxiang Li95917b12019-11-15 11:29:05 -080022
23namespace android {
24namespace frameworks {
25namespace automotive {
26namespace display {
27namespace V1_0 {
28namespace implementation {
29
Haoxiang Li95917b12019-11-15 11:29:05 -080030
Changyeon Jo75c8aa92019-12-30 11:12:53 -080031Return<sp<IGraphicBufferProducer>>
32AutomotiveDisplayProxyService::getIGraphicBufferProducer(uint64_t id) {
33 auto it = mDisplays.find(id);
34 sp<IBinder> displayToken = nullptr;
35 sp<SurfaceControl> surfaceControl = nullptr;
36 if (it == mDisplays.end()) {
Marin Shalamanova524a092020-07-27 21:39:55 +020037 displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
Changyeon Jo75c8aa92019-12-30 11:12:53 -080038 if (displayToken == nullptr) {
Changyeon Job0d738a2020-02-16 10:38:47 -080039 ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080040 return nullptr;
41 }
42
43 // Get the resolution from stored display state.
Marin Shalamanova7fe3042021-01-29 21:02:08 +010044 ui::DisplayMode displayMode = {};
45 auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080046 if (err != NO_ERROR) {
Marin Shalamanova7fe3042021-01-29 21:02:08 +010047 ALOGE("Failed to get display mode of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -080048 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080049 return nullptr;
50 }
51
52 ui::DisplayState displayState = {};
53 err = SurfaceComposerClient::getDisplayState(displayToken, &displayState);
54 if (err != NO_ERROR) {
55 ALOGE("Failed to get current display status of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -080056 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080057 return nullptr;
58 }
59
Marin Shalamanova7fe3042021-01-29 21:02:08 +010060 auto displayWidth = displayMode.resolution.getWidth();
61 auto displayHeight = displayMode.resolution.getHeight();
Changyeon Jo75c8aa92019-12-30 11:12:53 -080062 if ((displayState.orientation != ui::ROTATION_0) &&
63 (displayState.orientation != ui::ROTATION_180)) {
64 std::swap(displayWidth, displayHeight);
65 }
66
67 sp<android::SurfaceComposerClient> surfaceClient = new SurfaceComposerClient();
68 err = surfaceClient->initCheck();
Haoxiang Li95917b12019-11-15 11:29:05 -080069 if (err != NO_ERROR) {
70 ALOGE("SurfaceComposerClient::initCheck error: %#x", err);
Haoxiang Li95917b12019-11-15 11:29:05 -080071 return nullptr;
72 }
73
Changyeon Jo75c8aa92019-12-30 11:12:53 -080074 // Create a SurfaceControl instance
75 surfaceControl = surfaceClient->createSurface(
Changyeon Job0d738a2020-02-16 10:38:47 -080076 String8::format("AutomotiveDisplay::%lX", (unsigned long)id),
Changyeon Jo75c8aa92019-12-30 11:12:53 -080077 displayWidth, displayHeight,
Haoxiang Li95917b12019-11-15 11:29:05 -080078 PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080079 if (surfaceControl == nullptr || !surfaceControl->isValid()) {
80 ALOGE("Failed to create SurfaceControl.");
Haoxiang Li95917b12019-11-15 11:29:05 -080081 return nullptr;
82 }
83
Changyeon Jo75c8aa92019-12-30 11:12:53 -080084 // Store
85 DisplayDesc descriptor = {displayToken, surfaceControl};
86 mDisplays.insert_or_assign(id, std::move(descriptor));
87 } else {
88 displayToken = it->second.token;
89 surfaceControl = it->second.surfaceControl;
Haoxiang Li95917b12019-11-15 11:29:05 -080090 }
91
Changyeon Jo75c8aa92019-12-30 11:12:53 -080092 // SurfaceControl::getSurface is guaranteed to be not null.
93 auto targetSurface = surfaceControl->getSurface();
Haoxiang Li95917b12019-11-15 11:29:05 -080094 return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
Changyeon Jo75c8aa92019-12-30 11:12:53 -080095 B2HGraphicBufferProducer(targetSurface->getIGraphicBufferProducer());
Haoxiang Li95917b12019-11-15 11:29:05 -080096}
97
Haoxiang Li95917b12019-11-15 11:29:05 -080098
Changyeon Jo75c8aa92019-12-30 11:12:53 -080099Return<bool> AutomotiveDisplayProxyService::showWindow(uint64_t id) {
100 auto it = mDisplays.find(id);
101 if (it == mDisplays.end()) {
102 ALOGE("Given display token is invalid or unknown.");
Haoxiang Li95917b12019-11-15 11:29:05 -0800103 return false;
104 }
105
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800106 ui::DisplayState displayState;
107 auto err = SurfaceComposerClient::getDisplayState(it->second.token, &displayState);
108 if (err != NO_ERROR) {
Changyeon Job0d738a2020-02-16 10:38:47 -0800109 ALOGE("Failed to get current state of the display 0x%lX", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800110 return false;
111 }
112
113 SurfaceComposerClient::Transaction t;
114 t.setDisplayLayerStack(it->second.token, displayState.layerStack);
115 t.setLayerStack(it->second.surfaceControl, displayState.layerStack);
116
117 status_t status = t.setLayer(it->second.surfaceControl, 0x7FFFFFFF)
118 .show(it->second.surfaceControl)
119 .apply();
120
Haoxiang Li95917b12019-11-15 11:29:05 -0800121 return status == NO_ERROR;
122}
123
Haoxiang Li95917b12019-11-15 11:29:05 -0800124
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800125Return<bool> AutomotiveDisplayProxyService::hideWindow(uint64_t id) {
126 auto it = mDisplays.find(id);
127 if (it == mDisplays.end()) {
128 ALOGE("Given display token is invalid or unknown.");
Haoxiang Li95917b12019-11-15 11:29:05 -0800129 return false;
130 }
131
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800132 status_t status = SurfaceComposerClient::Transaction{}
133 .hide(it->second.surfaceControl)
134 .apply();
135
Haoxiang Li95917b12019-11-15 11:29:05 -0800136 return status == NO_ERROR;
137}
138
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800139
140Return<void> AutomotiveDisplayProxyService::getDisplayIdList(getDisplayIdList_cb _cb) {
141 hardware::hidl_vec<uint64_t> ids;
142
143 // Get stable IDs of all available displays and get their tokens and
144 // descriptors.
145 auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
146 ids.resize(displayIds.size());
147 for (auto i = 0; i < displayIds.size(); ++i) {
Marin Shalamanova524a092020-07-27 21:39:55 +0200148 ids[i] = displayIds[i].value;
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800149 }
150
151 _cb(ids);
152 return hardware::Void();
153}
154
155
156Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDisplayInfo_cb _cb) {
157 HwDisplayConfig activeConfig;
158 HwDisplayState activeState;
159
Marin Shalamanova524a092020-07-27 21:39:55 +0200160 auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800161 if (displayToken == nullptr) {
Changyeon Job0d738a2020-02-16 10:38:47 -0800162 ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800163 } else {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100164 ui::DisplayMode displayMode = {};
165 auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800166 if (err != NO_ERROR) {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100167 ALOGW("Failed to get display mode of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -0800168 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800169 }
170
171 ui::DisplayState displayState = {};
172 err = SurfaceComposerClient::getDisplayState(displayToken, &displayState);
173 if (err != NO_ERROR) {
174 ALOGW("Failed to get current display status of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -0800175 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800176 }
177
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100178 activeConfig.setToExternal((uint8_t*)&displayMode, sizeof(ui::DisplayMode));
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800179 activeState.setToExternal((uint8_t*)&displayState, sizeof(DisplayState));
180 }
181
182 _cb(activeConfig, activeState);
183 return hardware::Void();
184}
185
186
Haoxiang Li95917b12019-11-15 11:29:05 -0800187} // namespace implementation
188} // namespace V1_0
189} // namespace display
190} // namespace automotive
191} // namespace frameworks
192} // namespace android
193