IMediaMetadataRetriever.cpp revision cce8bd12da6d8419a8770e4552a51ec297c250c2
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 <utils/Parcel.h> 21#include <SkBitmap.h> 22#include <media/IMediaMetadataRetriever.h> 23 24namespace android { 25 26enum { 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 37class BpMediaMetadataRetriever: public BpInterface<IMediaMetadataRetriever> 38{ 39public: 40 BpMediaMetadataRetriever(const sp<IBinder>& impl) 41 : BpInterface<IMediaMetadataRetriever>(impl) 42 { 43 } 44 45 // disconnect from media metadata retriever service 46 void disconnect() 47 { 48 Parcel data, reply; 49 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 50 remote()->transact(DISCONNECT, data, &reply); 51 } 52 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 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 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 82 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 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 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 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 129IMPLEMENT_META_INTERFACE(MediaMetadataRetriever, "android.hardware.IMediaMetadataRetriever"); 130 131// ---------------------------------------------------------------------- 132 133#define CHECK_INTERFACE(interface, data, reply) \ 134 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 135 LOGW("Call incorrectly routed to " #interface); \ 136 return PERMISSION_DENIED; \ 137 } } while (0) 138 139status_t BnMediaMetadataRetriever::onTransact( 140 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 141{ 142 switch (code) { 143 case DISCONNECT: { 144 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 145 disconnect(); 146 return NO_ERROR; 147 } break; 148 case SET_DATA_SOURCE_URL: { 149 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 150 const char* srcUrl = data.readCString(); 151 reply->writeInt32(setDataSource(srcUrl)); 152 return NO_ERROR; 153 } break; 154 case SET_DATA_SOURCE_FD: { 155 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 156 int fd = dup(data.readFileDescriptor()); 157 int64_t offset = data.readInt64(); 158 int64_t length = data.readInt64(); 159 reply->writeInt32(setDataSource(fd, offset, length)); 160 return NO_ERROR; 161 } break; 162 case SET_MODE: { 163 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 164 int mode = data.readInt32(); 165 reply->writeInt32(setMode(mode)); 166 return NO_ERROR; 167 } break; 168 case GET_MODE: { 169 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 170 int mode; 171 status_t status = getMode(&mode); 172 reply->writeInt32(mode); 173 reply->writeInt32(status); 174 return NO_ERROR; 175 } break; 176 case CAPTURE_FRAME: { 177 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 178 sp<IMemory> bitmap = captureFrame(); 179 if (bitmap != 0) { // Don't send NULL across the binder interface 180 reply->writeInt32(NO_ERROR); 181 reply->writeStrongBinder(bitmap->asBinder()); 182 } else { 183 reply->writeInt32(UNKNOWN_ERROR); 184 } 185 return NO_ERROR; 186 } break; 187 case EXTARCT_ALBUM_ART: { 188 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 189 sp<IMemory> albumArt = extractAlbumArt(); 190 if (albumArt != 0) { // Don't send NULL across the binder interface 191 reply->writeInt32(NO_ERROR); 192 reply->writeStrongBinder(albumArt->asBinder()); 193 } else { 194 reply->writeInt32(UNKNOWN_ERROR); 195 } 196 return NO_ERROR; 197 } break; 198 case EXTRACT_METADATA: { 199 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 200 int keyCode = data.readInt32(); 201 const char* value = extractMetadata(keyCode); 202 if (value != NULL) { // Don't send NULL across the binder interface 203 reply->writeInt32(NO_ERROR); 204 reply->writeCString(value); 205 } else { 206 reply->writeInt32(UNKNOWN_ERROR); 207 } 208 return NO_ERROR; 209 } break; 210 default: 211 return BBinder::onTransact(code, data, reply, flags); 212 } 213} 214 215// ---------------------------------------------------------------------------- 216 217}; // namespace android 218 219