• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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