blob: fbefef0d16baf5b42a41537310dc8dd3cf02408e [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>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080020#include <ui/DisplayConfig.h>
21#include <ui/DisplayState.h>
Haoxiang Li95917b12019-11-15 11:29:05 -080022
23#include "CarWindowService.h"
24
25namespace android {
26namespace frameworks {
27namespace automotive {
28namespace display {
29namespace V1_0 {
30namespace implementation {
31
32Return<sp<IGraphicBufferProducer>>
33 CarWindowService::getIGraphicBufferProducer() {
34 if (mSurface == nullptr) {
35 status_t err;
36 mSurfaceComposerClient = new SurfaceComposerClient();
37
38 err = mSurfaceComposerClient->initCheck();
39 if (err != NO_ERROR) {
40 ALOGE("SurfaceComposerClient::initCheck error: %#x", err);
41 mSurfaceComposerClient = nullptr;
42 return nullptr;
43 }
44
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080045 const auto displayToken = SurfaceComposerClient::getInternalDisplayToken();
46 if (displayToken == nullptr) {
Haoxiang Li95917b12019-11-15 11:29:05 -080047 ALOGE("Failed to get internal display ");
48 return nullptr;
49 }
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080050
51 DisplayConfig displayConfig;
52 err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig);
Haoxiang Li95917b12019-11-15 11:29:05 -080053 if (err != NO_ERROR) {
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080054 ALOGE("Failed to get active display config");
Haoxiang Li95917b12019-11-15 11:29:05 -080055 return nullptr;
56 }
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080057
58 ui::DisplayState displayState;
59 err = SurfaceComposerClient::getDisplayState(displayToken, &displayState);
60 if (err != NO_ERROR) {
61 ALOGE("Failed to get display state");
62 return nullptr;
63 }
64
65 const ui::Size& resolution = displayConfig.resolution;
66 auto width = resolution.getWidth();
67 auto height = resolution.getHeight();
68
69 if (displayState.orientation == ui::ROTATION_90 ||
70 displayState.orientation == ui::ROTATION_270) {
71 std::swap(width, height);
Haoxiang Li95917b12019-11-15 11:29:05 -080072 }
73
74 mSurfaceControl = mSurfaceComposerClient->createSurface(
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080075 String8("Automotive Display"), width, height,
Haoxiang Li95917b12019-11-15 11:29:05 -080076 PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
77 if (mSurfaceControl == nullptr || !mSurfaceControl->isValid()) {
78 ALOGE("Failed to create SurfaceControl");
79 mSurfaceComposerClient = nullptr;
80 mSurfaceControl = nullptr;
81 return nullptr;
82 }
83
84 // SurfaceControl::getSurface is guaranteed to be not null.
85 mSurface = mSurfaceControl->getSurface();
86 }
87
88 return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
89 B2HGraphicBufferProducer(
90 mSurface->getIGraphicBufferProducer());
91}
92
93Return<bool> CarWindowService::showWindow() {
94 status_t status = NO_ERROR;
95
96 if (mSurfaceControl != nullptr) {
97 status = SurfaceComposerClient::Transaction{}
98 .setLayer(
99 mSurfaceControl, 0x7FFFFFFF) // always on top
100 .show(mSurfaceControl)
101 .apply();
102 } else {
103 ALOGE("showWindow: Failed to get a valid SurfaceControl!");
104 return false;
105 }
106
107 return status == NO_ERROR;
108}
109
110Return<bool> CarWindowService::hideWindow() {
111 status_t status = NO_ERROR;
112
113 if (mSurfaceControl != nullptr) {
114 status = SurfaceComposerClient::Transaction{}
115 .hide(mSurfaceControl)
116 .apply();
117 } else {
118 ALOGE("hideWindow: Failed to get a valid SurfaceControl!");
119 return false;
120 }
121
122 return status == NO_ERROR;
123}
124
125} // namespace implementation
126} // namespace V1_0
127} // namespace display
128} // namespace automotive
129} // namespace frameworks
130} // namespace android
131