1 //
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 //
16
17 #include <utility>
18
19 #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
20
21 #include "AutomotiveDisplayProxyService.h"
22
23 namespace android {
24 namespace frameworks {
25 namespace automotive {
26 namespace display {
27 namespace V1_0 {
28 namespace implementation {
29
30
31 Return<sp<IGraphicBufferProducer>>
getIGraphicBufferProducer(uint64_t id)32 AutomotiveDisplayProxyService::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(PhysicalDisplayId(id));
38 if (displayToken == nullptr) {
39 ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
40 return nullptr;
41 }
42
43 // Get the resolution from stored display state.
44 ui::DisplayMode displayMode = {};
45 auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
46 if (err != NO_ERROR) {
47 ALOGE("Failed to get display mode of %lX. "
48 "This display will be ignored.", (unsigned long)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.", (unsigned long)id);
57 return nullptr;
58 }
59
60 auto displayWidth = displayMode.resolution.getWidth();
61 auto displayHeight = displayMode.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();
69 if (err != NO_ERROR) {
70 ALOGE("SurfaceComposerClient::initCheck error: %#x", err);
71 return nullptr;
72 }
73
74 // Create a SurfaceControl instance
75 surfaceControl = surfaceClient->createSurface(
76 String8::format("AutomotiveDisplay::%lX", (unsigned long)id),
77 displayWidth, displayHeight,
78 PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
79 if (surfaceControl == nullptr || !surfaceControl->isValid()) {
80 ALOGE("Failed to create SurfaceControl.");
81 return nullptr;
82 }
83
84 // 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;
90 }
91
92 // SurfaceControl::getSurface is guaranteed to be not null.
93 auto targetSurface = surfaceControl->getSurface();
94 return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
95 B2HGraphicBufferProducer(targetSurface->getIGraphicBufferProducer());
96 }
97
98
showWindow(uint64_t id)99 Return<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.");
103 return false;
104 }
105
106 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", (unsigned long)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
121 return status == NO_ERROR;
122 }
123
124
hideWindow(uint64_t id)125 Return<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.");
129 return false;
130 }
131
132 status_t status = SurfaceComposerClient::Transaction{}
133 .hide(it->second.surfaceControl)
134 .apply();
135
136 return status == NO_ERROR;
137 }
138
139
getDisplayIdList(getDisplayIdList_cb _cb)140 Return<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].value;
149 }
150
151 _cb(ids);
152 return hardware::Void();
153 }
154
155
getDisplayInfo(uint64_t id,getDisplayInfo_cb _cb)156 Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDisplayInfo_cb _cb) {
157 HwDisplayConfig activeConfig;
158 HwDisplayState activeState;
159
160 auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
161 if (displayToken == nullptr) {
162 ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
163 } else {
164 ui::DisplayMode displayMode = {};
165 auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
166 if (err != NO_ERROR) {
167 ALOGW("Failed to get display mode of %lX. "
168 "This display will be ignored.", (unsigned long)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.", (unsigned long)id);
176 }
177
178 activeConfig.setToExternal((uint8_t*)&displayMode, sizeof(ui::DisplayMode));
179 activeState.setToExternal((uint8_t*)&displayState, sizeof(DisplayState));
180 }
181
182 _cb(activeConfig, activeState);
183 return hardware::Void();
184 }
185
186
187 } // namespace implementation
188 } // namespace V1_0
189 } // namespace display
190 } // namespace automotive
191 } // namespace frameworks
192 } // namespace android
193
194