1 /*
2 * Copyright (C) 2011 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 #define LOG_TAG "DisplayEventReceiver"
18
19 #include <string.h>
20
21 #include <utils/Errors.h>
22
23 #include <gui/DisplayEventReceiver.h>
24 #include <gui/VsyncEventData.h>
25
26 #include <private/gui/ComposerServiceAIDL.h>
27
28 #include <private/gui/BitTube.h>
29
30 // ---------------------------------------------------------------------------
31
32 namespace android {
33
34 // ---------------------------------------------------------------------------
35
DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource,EventRegistrationFlags eventRegistration,const sp<IBinder> & layerHandle)36 DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource,
37 EventRegistrationFlags eventRegistration,
38 const sp<IBinder>& layerHandle) {
39 sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
40 if (sf != nullptr) {
41 mEventConnection = nullptr;
42 binder::Status status =
43 sf->createDisplayEventConnection(vsyncSource,
44 static_cast<
45 gui::ISurfaceComposer::EventRegistration>(
46 eventRegistration.get()),
47 layerHandle, &mEventConnection);
48 if (status.isOk() && mEventConnection != nullptr) {
49 mDataChannel = std::make_unique<gui::BitTube>();
50 status = mEventConnection->stealReceiveChannel(mDataChannel.get());
51 if (!status.isOk()) {
52 ALOGE("stealReceiveChannel failed: %s", status.toString8().c_str());
53 mInitError = std::make_optional<status_t>(status.transactionError());
54 mDataChannel.reset();
55 mEventConnection.clear();
56 }
57 } else {
58 ALOGE("DisplayEventConnection creation failed: status=%s", status.toString8().c_str());
59 }
60 }
61 }
62
~DisplayEventReceiver()63 DisplayEventReceiver::~DisplayEventReceiver() {
64 }
65
initCheck() const66 status_t DisplayEventReceiver::initCheck() const {
67 if (mDataChannel != nullptr)
68 return NO_ERROR;
69 return mInitError.has_value() ? mInitError.value() : NO_INIT;
70 }
71
getFd() const72 int DisplayEventReceiver::getFd() const {
73 if (mDataChannel == nullptr) return mInitError.has_value() ? mInitError.value() : NO_INIT;
74
75 return mDataChannel->getFd();
76 }
77
setVsyncRate(uint32_t count)78 status_t DisplayEventReceiver::setVsyncRate(uint32_t count) {
79 if (int32_t(count) < 0)
80 return BAD_VALUE;
81
82 if (mEventConnection != nullptr) {
83 mEventConnection->setVsyncRate(count);
84 return NO_ERROR;
85 }
86 return mInitError.has_value() ? mInitError.value() : NO_INIT;
87 }
88
requestNextVsync()89 status_t DisplayEventReceiver::requestNextVsync() {
90 if (mEventConnection != nullptr) {
91 mEventConnection->requestNextVsync();
92 return NO_ERROR;
93 }
94 return mInitError.has_value() ? mInitError.value() : NO_INIT;
95 }
96
getLatestVsyncEventData(ParcelableVsyncEventData * outVsyncEventData) const97 status_t DisplayEventReceiver::getLatestVsyncEventData(
98 ParcelableVsyncEventData* outVsyncEventData) const {
99 if (mEventConnection != nullptr) {
100 auto status = mEventConnection->getLatestVsyncEventData(outVsyncEventData);
101 if (!status.isOk()) {
102 ALOGE("Failed to get latest vsync event data: %s", status.toString8().c_str());
103 return status.transactionError();
104 }
105 return NO_ERROR;
106 }
107 return NO_INIT;
108 }
109
getEvents(DisplayEventReceiver::Event * events,size_t count)110 ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
111 size_t count) {
112 return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count);
113 }
114
getEvents(gui::BitTube * dataChannel,Event * events,size_t count)115 ssize_t DisplayEventReceiver::getEvents(gui::BitTube* dataChannel,
116 Event* events, size_t count)
117 {
118 return gui::BitTube::recvObjects(dataChannel, events, count);
119 }
120
sendEvents(Event const * events,size_t count)121 ssize_t DisplayEventReceiver::sendEvents(Event const* events, size_t count) {
122 return DisplayEventReceiver::sendEvents(mDataChannel.get(), events, count);
123 }
124
sendEvents(gui::BitTube * dataChannel,Event const * events,size_t count)125 ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
126 Event const* events, size_t count)
127 {
128 return gui::BitTube::sendObjects(dataChannel, events, count);
129 }
130
131 // ---------------------------------------------------------------------------
132
133 }; // namespace android
134