• 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         if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
38             displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
39         }
40 
41         if (displayToken == nullptr) {
42             ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
43             return nullptr;
44         }
45 
46         // Get the resolution from stored display state.
47         ui::DisplayMode displayMode = {};
48         auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
49         if (err != NO_ERROR) {
50             ALOGE("Failed to get display mode of %lX.  "
51                   "This display will be ignored.", (unsigned long)id);
52             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.  "
59                   "This display will be ignored.", (unsigned long)id);
60             return nullptr;
61         }
62 
63         auto displayWidth  = displayMode.resolution.getWidth();
64         auto displayHeight = displayMode.resolution.getHeight();
65         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();
72         if (err != NO_ERROR) {
73             ALOGE("SurfaceComposerClient::initCheck error: %#x", err);
74             return nullptr;
75         }
76 
77         // Create a SurfaceControl instance
78         surfaceControl = surfaceClient->createSurface(
79                 String8::format("AutomotiveDisplay::%lX", (unsigned long)id),
80                 displayWidth, displayHeight,
81                 PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
82         if (surfaceControl == nullptr || !surfaceControl->isValid()) {
83             ALOGE("Failed to create SurfaceControl.");
84             return nullptr;
85         }
86 
87         // 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;
93     }
94 
95     // SurfaceControl::getSurface is guaranteed to be not null.
96     auto targetSurface = surfaceControl->getSurface();
97     return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
98                B2HGraphicBufferProducer(targetSurface->getIGraphicBufferProducer());
99 }
100 
101 
showWindow(uint64_t id)102 Return<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.");
106         return false;
107     }
108 
109     ui::DisplayState displayState;
110     auto err = SurfaceComposerClient::getDisplayState(it->second.token, &displayState);
111     if (err != NO_ERROR) {
112         ALOGE("Failed to get current state of the display 0x%lX", (unsigned long)id);
113         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 
124     return status == NO_ERROR;
125 }
126 
127 
hideWindow(uint64_t id)128 Return<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.");
132         return false;
133     }
134 
135     status_t status = SurfaceComposerClient::Transaction{}
136                       .hide(it->second.surfaceControl)
137                       .apply();
138 
139     return status == NO_ERROR;
140 }
141 
142 
getDisplayIdList(getDisplayIdList_cb _cb)143 Return<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) {
151         ids[i] = displayIds[i].value;
152     }
153 
154     _cb(ids);
155     return hardware::Void();
156 }
157 
158 
getDisplayInfo(uint64_t id,getDisplayInfo_cb _cb)159 Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDisplayInfo_cb _cb) {
160     HwDisplayConfig activeConfig;
161     HwDisplayState  activeState;
162 
163     sp<IBinder> displayToken;
164     if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
165         displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
166     }
167 
168     if (displayToken == nullptr) {
169         ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
170     } else {
171         ui::DisplayMode displayMode = {};
172         auto err = SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
173         if (err != NO_ERROR) {
174             ALOGW("Failed to get display mode of %lX.  "
175                   "This display will be ignored.", (unsigned long)id);
176         }
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.  "
182                   "This display will be ignored.", (unsigned long)id);
183         }
184 
185         activeConfig.setToExternal((uint8_t*)&displayMode, sizeof(ui::DisplayMode));
186         activeState.setToExternal((uint8_t*)&displayState, sizeof(DisplayState));
187     }
188 
189     _cb(activeConfig, activeState);
190     return hardware::Void();
191 }
192 
193 
194 }  // namespace implementation
195 }  // namespace V1_0
196 }  // namespace display
197 }  // namespace automotive
198 }  // namespace frameworks
199 }  // namespace android
200 
201