IConsumerListener.cpp revision 97514a25d6fb0b108882e5e6ddcc6ca9fb2e334d
1/*
2 * Copyright (C) 2013 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 <stdint.h>
18#include <sys/types.h>
19
20#include <binder/IInterface.h>
21#include <binder/Parcel.h>
22
23#include <gui/IConsumerListener.h>
24#include <gui/BufferItem.h>
25
26// ---------------------------------------------------------------------------
27namespace android {
28// ---------------------------------------------------------------------------
29
30enum {
31    ON_FRAME_AVAILABLE = IBinder::FIRST_CALL_TRANSACTION,
32    ON_BUFFER_RELEASED,
33    ON_SIDEBAND_STREAM_CHANGED,
34    GET_FRAME_TIMESTAMPS
35};
36
37class BpConsumerListener : public BpInterface<IConsumerListener>
38{
39public:
40    explicit BpConsumerListener(const sp<IBinder>& impl)
41        : BpInterface<IConsumerListener>(impl) {
42    }
43
44    virtual ~BpConsumerListener();
45
46    virtual void onFrameAvailable(const BufferItem& item) {
47        Parcel data, reply;
48        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
49        data.write(item);
50        remote()->transact(ON_FRAME_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
51    }
52
53    virtual void onBuffersReleased() {
54        Parcel data, reply;
55        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
56        remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
57    }
58
59    virtual void onSidebandStreamChanged() {
60        Parcel data, reply;
61        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
62        remote()->transact(ON_SIDEBAND_STREAM_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
63    }
64
65    virtual bool getFrameTimestamps(uint64_t frameNumber,
66            FrameTimestamps* outTimestamps) const {
67        Parcel data, reply;
68        status_t result = data.writeInterfaceToken(
69                IConsumerListener::getInterfaceDescriptor());
70        if (result != NO_ERROR) {
71            ALOGE("getFrameTimestamps failed to write token: %d", result);
72            return false;
73        }
74        result = data.writeUint64(frameNumber);
75        if (result != NO_ERROR) {
76            ALOGE("getFrameTimestamps failed to write: %d", result);
77            return false;
78        }
79        result = remote()->transact(GET_FRAME_TIMESTAMPS, data, &reply);
80        if (result != NO_ERROR) {
81            ALOGE("getFrameTimestamps failed to transact: %d", result);
82            return false;
83        }
84        bool found = false;
85        result = reply.readBool(&found);
86        if (result != NO_ERROR) {
87            ALOGE("getFrameTimestamps failed to read: %d", result);
88            return false;
89        }
90        if (found) {
91            result = reply.read(*outTimestamps);
92            if (result != NO_ERROR) {
93                ALOGE("getFrameTimestamps failed to read timestamps: %d",
94                        result);
95                return false;
96            }
97        }
98        return found;
99    }
100};
101
102// Out-of-line virtual method definition to trigger vtable emission in this
103// translation unit (see clang warning -Wweak-vtables)
104BpConsumerListener::~BpConsumerListener() {}
105
106IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener");
107
108// ----------------------------------------------------------------------
109
110status_t BnConsumerListener::onTransact(
111    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
112{
113    switch(code) {
114        case ON_FRAME_AVAILABLE: {
115            CHECK_INTERFACE(IConsumerListener, data, reply);
116            BufferItem item;
117            data.read(item);
118            onFrameAvailable(item);
119            return NO_ERROR; }
120        case ON_BUFFER_RELEASED: {
121            CHECK_INTERFACE(IConsumerListener, data, reply);
122            onBuffersReleased();
123            return NO_ERROR; }
124        case ON_SIDEBAND_STREAM_CHANGED: {
125            CHECK_INTERFACE(IConsumerListener, data, reply);
126            onSidebandStreamChanged();
127            return NO_ERROR; }
128        case GET_FRAME_TIMESTAMPS: {
129            CHECK_INTERFACE(IConsumerListener, data, reply);
130            uint64_t frameNumber = 0;
131            status_t result = data.readUint64(&frameNumber);
132            if (result != NO_ERROR) {
133                ALOGE("onTransact failed to read: %d", result);
134                return result;
135            }
136            FrameTimestamps timestamps;
137            bool found = getFrameTimestamps(frameNumber, &timestamps);
138            result = reply->writeBool(found);
139            if (result != NO_ERROR) {
140                ALOGE("onTransact failed to write: %d", result);
141                return result;
142            }
143            if (found) {
144                result = reply->write(timestamps);
145                if (result != NO_ERROR) {
146                    ALOGE("onTransact failed to write timestamps: %d", result);
147                    return result;
148                }
149            }
150            return NO_ERROR;
151        }
152    }
153    return BBinder::onTransact(code, data, reply, flags);
154}
155
156ConsumerListener::~ConsumerListener() = default;
157
158// ---------------------------------------------------------------------------
159}; // namespace android
160// ---------------------------------------------------------------------------
161