blob: d2052310332c1c960fc2b11cc4764592aafd28fb [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()) {
Dominik Laskowskif1833852021-03-23 15:06:50 -070037 if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
38 displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
39 }
40
Changyeon Jo75c8aa92019-12-30 11:12:53 -080041 if (displayToken == nullptr) {
Changyeon Job0d738a2020-02-16 10:38:47 -080042 ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080043 return nullptr;
44 }
45
46 // Get the resolution from stored display state.
Marin Shalamanova7fe3042021-01-29 21:02:08 +010047 ui::DisplayMode displayMode = {};
48 auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080049 if (err != NO_ERROR) {
Marin Shalamanova7fe3042021-01-29 21:02:08 +010050 ALOGE("Failed to get display mode of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -080051 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080052 return nullptr;
53 }
54
55 ui::DisplayState displayState = {};
56 err = SurfaceComposerClient::getDisplayState(displayToken, &displayState);
57 if (err != NO_ERROR) {
58 ALOGE("Failed to get current display status of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -080059 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080060 return nullptr;
61 }
62
Marin Shalamanova7fe3042021-01-29 21:02:08 +010063 auto displayWidth = displayMode.resolution.getWidth();
64 auto displayHeight = displayMode.resolution.getHeight();
Changyeon Jo75c8aa92019-12-30 11:12:53 -080065 if ((displayState.orientation != ui::ROTATION_0) &&
66 (displayState.orientation != ui::ROTATION_180)) {
67 std::swap(displayWidth, displayHeight);
68 }
69
70 sp<android::SurfaceComposerClient> surfaceClient = new SurfaceComposerClient();
71 err = surfaceClient->initCheck();
Haoxiang Li95917b12019-11-15 11:29:05 -080072 if (err != NO_ERROR) {
73 ALOGE("SurfaceComposerClient::initCheck error: %#x", err);
Haoxiang Li95917b12019-11-15 11:29:05 -080074 return nullptr;
75 }
76
Changyeon Jo75c8aa92019-12-30 11:12:53 -080077 // Create a SurfaceControl instance
78 surfaceControl = surfaceClient->createSurface(
Changyeon Job0d738a2020-02-16 10:38:47 -080079 String8::format("AutomotiveDisplay::%lX", (unsigned long)id),
Changyeon Jo75c8aa92019-12-30 11:12:53 -080080 displayWidth, displayHeight,
Haoxiang Li95917b12019-11-15 11:29:05 -080081 PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
Changyeon Jo75c8aa92019-12-30 11:12:53 -080082 if (surfaceControl == nullptr || !surfaceControl->isValid()) {
83 ALOGE("Failed to create SurfaceControl.");
Haoxiang Li95917b12019-11-15 11:29:05 -080084 return nullptr;
85 }
86
Changyeon Jo75c8aa92019-12-30 11:12:53 -080087 // Store
88 DisplayDesc descriptor = {displayToken, surfaceControl};
89 mDisplays.insert_or_assign(id, std::move(descriptor));
90 } else {
91 displayToken = it->second.token;
92 surfaceControl = it->second.surfaceControl;
Haoxiang Li95917b12019-11-15 11:29:05 -080093 }
94
Changyeon Jo75c8aa92019-12-30 11:12:53 -080095 // SurfaceControl::getSurface is guaranteed to be not null.
96 auto targetSurface = surfaceControl->getSurface();
Haoxiang Li95917b12019-11-15 11:29:05 -080097 return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
Changyeon Jo75c8aa92019-12-30 11:12:53 -080098 B2HGraphicBufferProducer(targetSurface->getIGraphicBufferProducer());
Haoxiang Li95917b12019-11-15 11:29:05 -080099}
100
Haoxiang Li95917b12019-11-15 11:29:05 -0800101
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800102Return<bool> AutomotiveDisplayProxyService::showWindow(uint64_t id) {
103 auto it = mDisplays.find(id);
104 if (it == mDisplays.end()) {
105 ALOGE("Given display token is invalid or unknown.");
Haoxiang Li95917b12019-11-15 11:29:05 -0800106 return false;
107 }
108
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800109 ui::DisplayState displayState;
110 auto err = SurfaceComposerClient::getDisplayState(it->second.token, &displayState);
111 if (err != NO_ERROR) {
Changyeon Job0d738a2020-02-16 10:38:47 -0800112 ALOGE("Failed to get current state of the display 0x%lX", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800113 return false;
114 }
115
116 SurfaceComposerClient::Transaction t;
117 t.setDisplayLayerStack(it->second.token, displayState.layerStack);
118 t.setLayerStack(it->second.surfaceControl, displayState.layerStack);
119
120 status_t status = t.setLayer(it->second.surfaceControl, 0x7FFFFFFF)
121 .show(it->second.surfaceControl)
122 .apply();
123
Haoxiang Li95917b12019-11-15 11:29:05 -0800124 return status == NO_ERROR;
125}
126
Haoxiang Li95917b12019-11-15 11:29:05 -0800127
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800128Return<bool> AutomotiveDisplayProxyService::hideWindow(uint64_t id) {
129 auto it = mDisplays.find(id);
130 if (it == mDisplays.end()) {
131 ALOGE("Given display token is invalid or unknown.");
Haoxiang Li95917b12019-11-15 11:29:05 -0800132 return false;
133 }
134
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800135 status_t status = SurfaceComposerClient::Transaction{}
136 .hide(it->second.surfaceControl)
137 .apply();
138
Haoxiang Li95917b12019-11-15 11:29:05 -0800139 return status == NO_ERROR;
140}
141
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800142
143Return<void> AutomotiveDisplayProxyService::getDisplayIdList(getDisplayIdList_cb _cb) {
144 hardware::hidl_vec<uint64_t> ids;
145
146 // Get stable IDs of all available displays and get their tokens and
147 // descriptors.
148 auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
149 ids.resize(displayIds.size());
150 for (auto i = 0; i < displayIds.size(); ++i) {
Marin Shalamanova524a092020-07-27 21:39:55 +0200151 ids[i] = displayIds[i].value;
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800152 }
153
154 _cb(ids);
155 return hardware::Void();
156}
157
158
159Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDisplayInfo_cb _cb) {
160 HwDisplayConfig activeConfig;
161 HwDisplayState activeState;
162
Dominik Laskowskif1833852021-03-23 15:06:50 -0700163 sp<IBinder> displayToken;
164 if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
165 displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
166 }
167
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800168 if (displayToken == nullptr) {
Changyeon Job0d738a2020-02-16 10:38:47 -0800169 ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800170 } else {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100171 ui::DisplayMode displayMode = {};
172 auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800173 if (err != NO_ERROR) {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100174 ALOGW("Failed to get display mode 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
178 ui::DisplayState displayState = {};
179 err = SurfaceComposerClient::getDisplayState(displayToken, &displayState);
180 if (err != NO_ERROR) {
181 ALOGW("Failed to get current display status of %lX. "
Changyeon Job0d738a2020-02-16 10:38:47 -0800182 "This display will be ignored.", (unsigned long)id);
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800183 }
184
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100185 activeConfig.setToExternal((uint8_t*)&displayMode, sizeof(ui::DisplayMode));
Changyeon Jo75c8aa92019-12-30 11:12:53 -0800186 activeState.setToExternal((uint8_t*)&displayState, sizeof(DisplayState));
187 }
188
189 _cb(activeConfig, activeState);
190 return hardware::Void();
191}
192
193
Haoxiang Li95917b12019-11-15 11:29:05 -0800194} // namespace implementation
195} // namespace V1_0
196} // namespace display
197} // namespace automotive
198} // namespace frameworks
199} // namespace android
200