• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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_NDEBUG 0
18 #define LOG_TAG "IStreamSource"
19 #include <utils/Log.h>
20 
21 #include <media/IStreamSource.h>
22 #include <media/stagefright/foundation/AMessage.h>
23 #include <media/stagefright/foundation/MediaKeys.h>
24 
25 #include <binder/IMemory.h>
26 #include <binder/Parcel.h>
27 
28 namespace android {
29 
30 enum {
31     // IStreamSource
32     SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
33     SET_BUFFERS,
34     ON_BUFFER_AVAILABLE,
35     FLAGS,
36 
37     // IStreamListener
38     QUEUE_BUFFER,
39     ISSUE_COMMAND,
40 };
41 
42 struct BpStreamSource : public BpInterface<IStreamSource> {
BpStreamSourceandroid::BpStreamSource43     explicit BpStreamSource(const sp<IBinder> &impl)
44         : BpInterface<IStreamSource>(impl) {
45     }
46 
setListenerandroid::BpStreamSource47     virtual void setListener(const sp<IStreamListener> &listener) {
48         Parcel data, reply;
49         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
50         data.writeStrongBinder(IInterface::asBinder(listener));
51         remote()->transact(SET_LISTENER, data, &reply);
52     }
53 
setBuffersandroid::BpStreamSource54     virtual void setBuffers(const Vector<sp<IMemory> > &buffers) {
55         Parcel data, reply;
56         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
57         data.writeInt64(static_cast<int64_t>(buffers.size()));
58         for (size_t i = 0; i < buffers.size(); ++i) {
59             data.writeStrongBinder(IInterface::asBinder(buffers.itemAt(i)));
60         }
61         remote()->transact(SET_BUFFERS, data, &reply);
62     }
63 
onBufferAvailableandroid::BpStreamSource64     virtual void onBufferAvailable(size_t index) {
65         Parcel data, reply;
66         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
67         data.writeInt64(static_cast<int64_t>(index));
68         remote()->transact(
69                 ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
70     }
71 
flagsandroid::BpStreamSource72     virtual uint32_t flags() const {
73         Parcel data, reply;
74         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
75         remote()->transact(FLAGS, data, &reply);
76 
77         return reply.readInt32();
78     }
79 };
80 
81 IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource");
82 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)83 status_t BnStreamSource::onTransact(
84         uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
85     switch (code) {
86         case SET_LISTENER:
87         {
88             CHECK_INTERFACE(IStreamSource, data, reply);
89             setListener(
90                     interface_cast<IStreamListener>(data.readStrongBinder()));
91             break;
92         }
93 
94         case SET_BUFFERS:
95         {
96             CHECK_INTERFACE(IStreamSource, data, reply);
97             size_t n = static_cast<size_t>(data.readInt64());
98             Vector<sp<IMemory> > buffers;
99             for (size_t i = 0; i < n; ++i) {
100                 sp<IMemory> mem =
101                     interface_cast<IMemory>(data.readStrongBinder());
102 
103                 if (mem != NULL) {
104                     buffers.push(mem);
105                 } else if (data.dataAvail() == 0) {
106                     break;
107                 }
108             }
109             setBuffers(buffers);
110             break;
111         }
112 
113         case ON_BUFFER_AVAILABLE:
114         {
115             CHECK_INTERFACE(IStreamSource, data, reply);
116             onBufferAvailable(static_cast<size_t>(data.readInt64()));
117             break;
118         }
119 
120         case FLAGS:
121         {
122             CHECK_INTERFACE(IStreamSource, data, reply);
123             reply->writeInt32(this->flags());
124             break;
125         }
126 
127         default:
128             return BBinder::onTransact(code, data, reply, flags);
129     }
130 
131     return OK;
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 
136 struct BpStreamListener : public BpInterface<IStreamListener> {
BpStreamListenerandroid::BpStreamListener137     explicit BpStreamListener(const sp<IBinder> &impl)
138         : BpInterface<IStreamListener>(impl) {
139     }
140 
queueBufferandroid::BpStreamListener141     virtual void queueBuffer(size_t index, size_t size) {
142         Parcel data, reply;
143         data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
144         data.writeInt64(static_cast<int64_t>(index));
145         data.writeInt64(static_cast<int64_t>(size));
146 
147         remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
148     }
149 
issueCommandandroid::BpStreamListener150     virtual void issueCommand(
151             Command cmd, bool synchronous, const sp<AMessage> &msg) {
152         Parcel data, reply;
153         data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
154         data.writeInt32(static_cast<int32_t>(cmd));
155         data.writeInt32(static_cast<int32_t>(synchronous));
156 
157         if (msg != NULL) {
158             data.writeInt32(1);
159             msg->writeToParcel(&data);
160         } else {
161             data.writeInt32(0);
162         }
163 
164         remote()->transact(ISSUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY);
165     }
166 };
167 
168 IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener");
169 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)170 status_t BnStreamListener::onTransact(
171         uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
172     switch (code) {
173         case QUEUE_BUFFER:
174         {
175             CHECK_INTERFACE(IStreamListener, data, reply);
176             size_t index = static_cast<size_t>(data.readInt64());
177             size_t size = static_cast<size_t>(data.readInt64());
178 
179             queueBuffer(index, size);
180             break;
181         }
182 
183         case ISSUE_COMMAND:
184         {
185             CHECK_INTERFACE(IStreamListener, data, reply);
186             Command cmd = static_cast<Command>(data.readInt32());
187 
188             bool synchronous = static_cast<bool>(data.readInt32());
189 
190             sp<AMessage> msg;
191 
192             if (data.readInt32()) {
193                 msg = AMessage::FromParcel(data);
194             }
195 
196             issueCommand(cmd, synchronous, msg);
197             break;
198         }
199 
200         default:
201             return BBinder::onTransact(code, data, reply, flags);
202     }
203 
204     return OK;
205 }
206 
207 }  // namespace android
208