• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright (C) 2008 The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include <stdint.h>
19 #include <sys/types.h>
20 #include <binder/Parcel.h>
21 #include <SkBitmap.h>
22 #include <media/IMediaMetadataRetriever.h>
23 
24 namespace android {
25 
26 enum {
27     DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
28     SET_DATA_SOURCE_URL,
29     SET_DATA_SOURCE_FD,
30     SET_MODE,
31     GET_MODE,
32     CAPTURE_FRAME,
33     EXTARCT_ALBUM_ART,
34     EXTRACT_METADATA,
35 };
36 
37 class BpMediaMetadataRetriever: public BpInterface<IMediaMetadataRetriever>
38 {
39 public:
BpMediaMetadataRetriever(const sp<IBinder> & impl)40     BpMediaMetadataRetriever(const sp<IBinder>& impl)
41         : BpInterface<IMediaMetadataRetriever>(impl)
42     {
43     }
44 
45     // disconnect from media metadata retriever service
disconnect()46     void disconnect()
47     {
48         Parcel data, reply;
49         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
50         remote()->transact(DISCONNECT, data, &reply);
51     }
52 
setDataSource(const char * srcUrl)53     status_t setDataSource(const char* srcUrl)
54     {
55         Parcel data, reply;
56         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
57         data.writeCString(srcUrl);
58         remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
59         return reply.readInt32();
60     }
61 
setDataSource(int fd,int64_t offset,int64_t length)62     status_t setDataSource(int fd, int64_t offset, int64_t length)
63     {
64         Parcel data, reply;
65         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
66         data.writeFileDescriptor(fd);
67         data.writeInt64(offset);
68         data.writeInt64(length);
69         remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
70         return reply.readInt32();
71     }
72 
setMode(int mode)73     status_t setMode(int mode)
74     {
75         Parcel data, reply;
76         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
77         data.writeInt32(mode);
78         remote()->transact(SET_MODE, data, &reply);
79         return reply.readInt32();
80     }
81 
getMode(int * mode) const82     status_t getMode(int* mode) const
83     {
84         Parcel data, reply;
85         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
86         remote()->transact(GET_MODE, data, &reply);
87         *mode = reply.readInt32();
88         return reply.readInt32();
89     }
90 
captureFrame()91     sp<IMemory> captureFrame()
92     {
93         Parcel data, reply;
94         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
95         remote()->transact(CAPTURE_FRAME, data, &reply);
96         status_t ret = reply.readInt32();
97         if (ret != NO_ERROR) {
98             return NULL;
99         }
100         return interface_cast<IMemory>(reply.readStrongBinder());
101     }
102 
extractAlbumArt()103     sp<IMemory> extractAlbumArt()
104     {
105         Parcel data, reply;
106         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
107         remote()->transact(EXTARCT_ALBUM_ART, data, &reply);
108         status_t ret = reply.readInt32();
109         if (ret != NO_ERROR) {
110             return NULL;
111         }
112         return interface_cast<IMemory>(reply.readStrongBinder());
113     }
114 
extractMetadata(int keyCode)115     const char* extractMetadata(int keyCode)
116     {
117         Parcel data, reply;
118         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
119         data.writeInt32(keyCode);
120         remote()->transact(EXTRACT_METADATA, data, &reply);
121         status_t ret = reply.readInt32();
122         if (ret != NO_ERROR) {
123             return NULL;
124         }
125         return reply.readCString();
126     }
127 };
128 
129 IMPLEMENT_META_INTERFACE(MediaMetadataRetriever, "android.media.IMediaMetadataRetriever");
130 
131 // ----------------------------------------------------------------------
132 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)133 status_t BnMediaMetadataRetriever::onTransact(
134     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
135 {
136     switch (code) {
137         case DISCONNECT: {
138             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
139             disconnect();
140             return NO_ERROR;
141         } break;
142         case SET_DATA_SOURCE_URL: {
143             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
144             const char* srcUrl = data.readCString();
145             reply->writeInt32(setDataSource(srcUrl));
146             return NO_ERROR;
147         } break;
148         case SET_DATA_SOURCE_FD: {
149             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
150             int fd = dup(data.readFileDescriptor());
151             int64_t offset = data.readInt64();
152             int64_t length = data.readInt64();
153             reply->writeInt32(setDataSource(fd, offset, length));
154             return NO_ERROR;
155         } break;
156         case SET_MODE: {
157             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
158             int mode = data.readInt32();
159             reply->writeInt32(setMode(mode));
160             return NO_ERROR;
161         } break;
162         case GET_MODE: {
163             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
164             int mode;
165             status_t status = getMode(&mode);
166             reply->writeInt32(mode);
167             reply->writeInt32(status);
168             return NO_ERROR;
169         } break;
170         case CAPTURE_FRAME: {
171             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
172             sp<IMemory> bitmap = captureFrame();
173             if (bitmap != 0) {  // Don't send NULL across the binder interface
174                 reply->writeInt32(NO_ERROR);
175                 reply->writeStrongBinder(bitmap->asBinder());
176             } else {
177                 reply->writeInt32(UNKNOWN_ERROR);
178             }
179             return NO_ERROR;
180         } break;
181         case EXTARCT_ALBUM_ART: {
182             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
183             sp<IMemory> albumArt = extractAlbumArt();
184             if (albumArt != 0) {  // Don't send NULL across the binder interface
185                 reply->writeInt32(NO_ERROR);
186                 reply->writeStrongBinder(albumArt->asBinder());
187             } else {
188                 reply->writeInt32(UNKNOWN_ERROR);
189             }
190             return NO_ERROR;
191         } break;
192         case EXTRACT_METADATA: {
193             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
194             int keyCode = data.readInt32();
195             const char* value = extractMetadata(keyCode);
196             if (value != NULL) {  // Don't send NULL across the binder interface
197                 reply->writeInt32(NO_ERROR);
198                 reply->writeCString(value);
199             } else {
200                 reply->writeInt32(UNKNOWN_ERROR);
201             }
202             return NO_ERROR;
203         } break;
204         default:
205             return BBinder::onTransact(code, data, reply, flags);
206     }
207 }
208 
209 // ----------------------------------------------------------------------------
210 
211 }; // namespace android
212