blob: 8f57dcdb186c7e28bd62020adb1a4fce3d00c34b [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()) {
37 displayToken = SurfaceComposerClient::getPhysicalDisplayToken(id);
38 if (displayToken == nullptr) {
39 ALOGE("Given display id, 0x%lX, is invalid.", id);
40 return nullptr;
41 }
42
43 // Get the resolution from stored display state.
44 DisplayConfig displayConfig = {};
45 auto err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig);
46 if (err != NO_ERROR) {
47 ALOGE("Failed to get display configuration of %lX. "
48 "This display will be ignored.", id);
49 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. "
56 "This display will be ignored.", id);
57 return nullptr;
58 }
59
60 auto displayWidth = displayConfig.resolution.getWidth();
61 auto displayHeight = displayConfig.resolution.getHeight();
62 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(
76 String8::format("AutomotiveDisplay::%lX", id),
77 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) {
109 ALOGE("Failed to get current state of the display 0x%lX", id);
110 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) {
148 ids[i] = displayIds[i];
149 }
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
160 auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(id);
161 if (displayToken == nullptr) {
162 ALOGE("Given display id, 0x%lX, is invalid.", id);
163 } else {
164 DisplayConfig displayConfig = {};
165 auto err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig);
166 if (err != NO_ERROR) {
167 ALOGW("Failed to get display configuration of %lX. "
168 "This display will be ignored.", id);
169 }
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. "
175 "This display will be ignored.", id);
176 }
177
178 activeConfig.setToExternal((uint8_t*)&displayConfig, sizeof(DisplayConfig));
179 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