blob: 590ba1a55a9258f8763ca5dee5a672b6858bdf4e [file] [log] [blame]
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001/*
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
Mark Salyzyn34fb2962014-06-18 16:30:56 -070018#include <inttypes.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080019#include <stdint.h>
20#include <sys/types.h>
Mark Salyzyn34fb2962014-06-18 16:30:56 -070021
Mathias Agopian75624082009-05-19 19:08:10 -070022#include <binder/Parcel.h>
Chris Watkins99f31602015-03-20 13:06:33 -070023#include <media/IDataSource.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080024#include <media/IMediaHTTPService.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080025#include <media/IMediaMetadataRetriever.h>
Andreas Huberaf8791e2011-03-21 10:25:44 -070026#include <utils/String8.h>
Sangkyu Leed01c1482013-02-08 16:26:39 +090027#include <utils/KeyedVector.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080028
Dave Sparksec4dde72009-11-23 16:51:15 -080029// The binder is supposed to propagate the scheduler group across
30// the binder interface so that remote calls are executed with
31// the same priority as local calls. This is currently not working
32// so this change puts in a temporary hack to fix the issue with
33// metadata retrieval which can be a huge CPU hit if done on a
34// foreground thread.
35#ifndef DISABLE_GROUP_SCHEDULE_HACK
36
Dave Sparksf311c552009-11-23 19:51:33 -080037#undef LOG_TAG
Dave Sparksec4dde72009-11-23 16:51:15 -080038#define LOG_TAG "IMediaMetadataRetriever"
39#include <utils/Log.h>
40#include <cutils/sched_policy.h>
41
42namespace android {
43
44static void sendSchedPolicy(Parcel& data)
45{
46 SchedPolicy policy;
Glenn Kasten0512ab52011-05-04 17:58:57 -070047 get_sched_policy(gettid(), &policy);
Dave Sparksec4dde72009-11-23 16:51:15 -080048 data.writeInt32(policy);
49}
50
51static void setSchedPolicy(const Parcel& data)
52{
53 SchedPolicy policy = (SchedPolicy) data.readInt32();
Glenn Kasten0512ab52011-05-04 17:58:57 -070054 set_sched_policy(gettid(), policy);
Dave Sparksec4dde72009-11-23 16:51:15 -080055}
56static void restoreSchedPolicy()
57{
Glenn Kasten0512ab52011-05-04 17:58:57 -070058 set_sched_policy(gettid(), SP_FOREGROUND);
Dave Sparksec4dde72009-11-23 16:51:15 -080059}
60}; // end namespace android
61#endif
62
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080063namespace android {
64
65enum {
66 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
67 SET_DATA_SOURCE_URL,
68 SET_DATA_SOURCE_FD,
Chris Watkins99f31602015-03-20 13:06:33 -070069 SET_DATA_SOURCE_CALLBACK,
James Dong16afe2f2010-12-02 17:42:08 -080070 GET_FRAME_AT_TIME,
Chong Zhangd3e0d862017-10-03 13:17:13 -070071 GET_IMAGE_AT_INDEX,
Chong Zhang0c1407f2018-05-02 17:09:05 -070072 GET_IMAGE_RECT_AT_INDEX,
Chong Zhangd3e0d862017-10-03 13:17:13 -070073 GET_FRAME_AT_INDEX,
Dave Sparksec4dde72009-11-23 16:51:15 -080074 EXTRACT_ALBUM_ART,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080075 EXTRACT_METADATA,
76};
77
78class BpMediaMetadataRetriever: public BpInterface<IMediaMetadataRetriever>
79{
80public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070081 explicit BpMediaMetadataRetriever(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080082 : BpInterface<IMediaMetadataRetriever>(impl)
83 {
84 }
85
86 // disconnect from media metadata retriever service
87 void disconnect()
88 {
89 Parcel data, reply;
90 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
91 remote()->transact(DISCONNECT, data, &reply);
92 }
93
Andreas Huberaf8791e2011-03-21 10:25:44 -070094 status_t setDataSource(
Andreas Huber1b86fe02014-01-29 11:13:26 -080095 const sp<IMediaHTTPService> &httpService,
96 const char *srcUrl,
97 const KeyedVector<String8, String8> *headers)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080098 {
99 Parcel data, reply;
100 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800101 data.writeInt32(httpService != NULL);
102 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800103 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800104 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800105 data.writeCString(srcUrl);
Andreas Huberaf8791e2011-03-21 10:25:44 -0700106
107 if (headers == NULL) {
108 data.writeInt32(0);
109 } else {
110 // serialize the headers
Glenn Kastene03dd222014-01-28 11:04:39 -0800111 data.writeInt64(headers->size());
Andreas Huberaf8791e2011-03-21 10:25:44 -0700112 for (size_t i = 0; i < headers->size(); ++i) {
113 data.writeString8(headers->keyAt(i));
114 data.writeString8(headers->valueAt(i));
115 }
116 }
117
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800118 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
119 return reply.readInt32();
120 }
121
122 status_t setDataSource(int fd, int64_t offset, int64_t length)
123 {
124 Parcel data, reply;
125 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
126 data.writeFileDescriptor(fd);
127 data.writeInt64(offset);
128 data.writeInt64(length);
129 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
130 return reply.readInt32();
131 }
132
Chong Zhang24c15772017-07-26 16:25:28 -0700133 status_t setDataSource(const sp<IDataSource>& source, const char *mime)
Chris Watkins99f31602015-03-20 13:06:33 -0700134 {
135 Parcel data, reply;
136 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
137 data.writeStrongBinder(IInterface::asBinder(source));
Chong Zhang24c15772017-07-26 16:25:28 -0700138
139 if (mime != NULL) {
140 data.writeInt32(1);
141 data.writeCString(mime);
142 } else {
143 data.writeInt32(0);
144 }
Chris Watkins99f31602015-03-20 13:06:33 -0700145 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
146 return reply.readInt32();
147 }
148
Chong Zhang24c15772017-07-26 16:25:28 -0700149 sp<IMemory> getFrameAtTime(int64_t timeUs, int option, int colorFormat, bool metaOnly)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800150 {
Chong Zhang24c15772017-07-26 16:25:28 -0700151 ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d) metaOnly(%d)",
152 timeUs, option, colorFormat, metaOnly);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800153 Parcel data, reply;
154 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
James Dong16afe2f2010-12-02 17:42:08 -0800155 data.writeInt64(timeUs);
156 data.writeInt32(option);
Chong Zhang24c15772017-07-26 16:25:28 -0700157 data.writeInt32(colorFormat);
158 data.writeInt32(metaOnly);
Dave Sparksec4dde72009-11-23 16:51:15 -0800159#ifndef DISABLE_GROUP_SCHEDULE_HACK
160 sendSchedPolicy(data);
161#endif
James Dong16afe2f2010-12-02 17:42:08 -0800162 remote()->transact(GET_FRAME_AT_TIME, data, &reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800163 status_t ret = reply.readInt32();
164 if (ret != NO_ERROR) {
165 return NULL;
166 }
167 return interface_cast<IMemory>(reply.readStrongBinder());
168 }
169
Chong Zhangd5fa3572018-04-09 19:03:10 -0700170 sp<IMemory> getImageAtIndex(int index, int colorFormat, bool metaOnly, bool thumbnail)
Chong Zhangd3e0d862017-10-03 13:17:13 -0700171 {
Chong Zhangd5fa3572018-04-09 19:03:10 -0700172 ALOGV("getImageAtIndex: index %d, colorFormat(%d) metaOnly(%d) thumbnail(%d)",
173 index, colorFormat, metaOnly, thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700174 Parcel data, reply;
175 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
176 data.writeInt32(index);
177 data.writeInt32(colorFormat);
178 data.writeInt32(metaOnly);
Chong Zhangd5fa3572018-04-09 19:03:10 -0700179 data.writeInt32(thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700180#ifndef DISABLE_GROUP_SCHEDULE_HACK
181 sendSchedPolicy(data);
182#endif
183 remote()->transact(GET_IMAGE_AT_INDEX, data, &reply);
184 status_t ret = reply.readInt32();
185 if (ret != NO_ERROR) {
186 return NULL;
187 }
188 return interface_cast<IMemory>(reply.readStrongBinder());
189 }
190
Chong Zhang0c1407f2018-05-02 17:09:05 -0700191 sp<IMemory> getImageRectAtIndex(
192 int index, int colorFormat, int left, int top, int right, int bottom)
193 {
194 ALOGV("getImageRectAtIndex: index %d, colorFormat(%d) rect {%d, %d, %d, %d}",
195 index, colorFormat, left, top, right, bottom);
196 Parcel data, reply;
197 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
198 data.writeInt32(index);
199 data.writeInt32(colorFormat);
200 data.writeInt32(left);
201 data.writeInt32(top);
202 data.writeInt32(right);
203 data.writeInt32(bottom);
204#ifndef DISABLE_GROUP_SCHEDULE_HACK
205 sendSchedPolicy(data);
206#endif
207 remote()->transact(GET_IMAGE_RECT_AT_INDEX, data, &reply);
208 status_t ret = reply.readInt32();
209 if (ret != NO_ERROR) {
210 return NULL;
211 }
212 return interface_cast<IMemory>(reply.readStrongBinder());
213 }
214
Chong Zhangd3e0d862017-10-03 13:17:13 -0700215 status_t getFrameAtIndex(std::vector<sp<IMemory> > *frames,
216 int frameIndex, int numFrames, int colorFormat, bool metaOnly)
217 {
218 ALOGV("getFrameAtIndex: frameIndex(%d), numFrames(%d), colorFormat(%d) metaOnly(%d)",
219 frameIndex, numFrames, colorFormat, metaOnly);
220 Parcel data, reply;
221 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
222 data.writeInt32(frameIndex);
223 data.writeInt32(numFrames);
224 data.writeInt32(colorFormat);
225 data.writeInt32(metaOnly);
226#ifndef DISABLE_GROUP_SCHEDULE_HACK
227 sendSchedPolicy(data);
228#endif
229 remote()->transact(GET_FRAME_AT_INDEX, data, &reply);
230 status_t ret = reply.readInt32();
231 if (ret != NO_ERROR) {
232 return ret;
233 }
234 int retNumFrames = reply.readInt32();
235 if (retNumFrames < numFrames) {
236 numFrames = retNumFrames;
237 }
238 for (int i = 0; i < numFrames; i++) {
239 frames->push_back(interface_cast<IMemory>(reply.readStrongBinder()));
240 }
241 return OK;
242 }
243
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800244 sp<IMemory> extractAlbumArt()
245 {
246 Parcel data, reply;
247 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
Dave Sparksec4dde72009-11-23 16:51:15 -0800248#ifndef DISABLE_GROUP_SCHEDULE_HACK
249 sendSchedPolicy(data);
250#endif
251 remote()->transact(EXTRACT_ALBUM_ART, data, &reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800252 status_t ret = reply.readInt32();
253 if (ret != NO_ERROR) {
254 return NULL;
255 }
256 return interface_cast<IMemory>(reply.readStrongBinder());
257 }
258
259 const char* extractMetadata(int keyCode)
260 {
261 Parcel data, reply;
262 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
Dave Sparksec4dde72009-11-23 16:51:15 -0800263#ifndef DISABLE_GROUP_SCHEDULE_HACK
264 sendSchedPolicy(data);
265#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800266 data.writeInt32(keyCode);
267 remote()->transact(EXTRACT_METADATA, data, &reply);
268 status_t ret = reply.readInt32();
269 if (ret != NO_ERROR) {
270 return NULL;
271 }
Sangkyu Leed01c1482013-02-08 16:26:39 +0900272 const char* str = reply.readCString();
273 if (str != NULL) {
274 String8 value(str);
275 if (mMetadata.indexOfKey(keyCode) < 0) {
276 mMetadata.add(keyCode, value);
277 } else {
278 mMetadata.replaceValueFor(keyCode, value);
279 }
280 return mMetadata.valueFor(keyCode).string();
281 } else {
282 return NULL;
283 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800284 }
Sangkyu Leed01c1482013-02-08 16:26:39 +0900285
286private:
287 KeyedVector<int, String8> mMetadata;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800288};
289
niko56f0cc52009-06-22 08:49:52 -0700290IMPLEMENT_META_INTERFACE(MediaMetadataRetriever, "android.media.IMediaMetadataRetriever");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800291
292// ----------------------------------------------------------------------
293
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800294status_t BnMediaMetadataRetriever::onTransact(
295 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
296{
297 switch (code) {
298 case DISCONNECT: {
299 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
300 disconnect();
301 return NO_ERROR;
302 } break;
303 case SET_DATA_SOURCE_URL: {
304 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800305
306 sp<IMediaHTTPService> httpService;
307 if (data.readInt32()) {
308 httpService =
309 interface_cast<IMediaHTTPService>(data.readStrongBinder());
310 }
311
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800312 const char* srcUrl = data.readCString();
Andreas Huberaf8791e2011-03-21 10:25:44 -0700313
Wei Jia2afac0c2016-01-07 12:13:07 -0800314 if (httpService == NULL || srcUrl == NULL) {
315 reply->writeInt32(BAD_VALUE);
316 return NO_ERROR;
317 }
318
Andreas Huberaf8791e2011-03-21 10:25:44 -0700319 KeyedVector<String8, String8> headers;
Glenn Kastene03dd222014-01-28 11:04:39 -0800320 size_t numHeaders = (size_t) data.readInt64();
321 for (size_t i = 0; i < numHeaders; ++i) {
Andreas Huberaf8791e2011-03-21 10:25:44 -0700322 String8 key = data.readString8();
323 String8 value = data.readString8();
324 headers.add(key, value);
325 }
326
327 reply->writeInt32(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800328 setDataSource(
329 httpService, srcUrl, numHeaders > 0 ? &headers : NULL));
Andreas Huberaf8791e2011-03-21 10:25:44 -0700330
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800331 return NO_ERROR;
332 } break;
333 case SET_DATA_SOURCE_FD: {
334 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Taiju Tsuiki55203e22015-04-21 17:36:22 +0900335 int fd = data.readFileDescriptor();
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800336 int64_t offset = data.readInt64();
337 int64_t length = data.readInt64();
338 reply->writeInt32(setDataSource(fd, offset, length));
339 return NO_ERROR;
340 } break;
Chris Watkins99f31602015-03-20 13:06:33 -0700341 case SET_DATA_SOURCE_CALLBACK: {
342 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
343 sp<IDataSource> source =
344 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800345 if (source == NULL) {
346 reply->writeInt32(BAD_VALUE);
347 } else {
Chong Zhang24c15772017-07-26 16:25:28 -0700348 int32_t hasMime = data.readInt32();
349 const char *mime = NULL;
350 if (hasMime) {
351 mime = data.readCString();
352 }
353 reply->writeInt32(setDataSource(source, mime));
Wei Jia2afac0c2016-01-07 12:13:07 -0800354 }
Chris Watkins99f31602015-03-20 13:06:33 -0700355 return NO_ERROR;
356 } break;
James Dong16afe2f2010-12-02 17:42:08 -0800357 case GET_FRAME_AT_TIME: {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800358 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
James Dong16afe2f2010-12-02 17:42:08 -0800359 int64_t timeUs = data.readInt64();
360 int option = data.readInt32();
Chong Zhang24c15772017-07-26 16:25:28 -0700361 int colorFormat = data.readInt32();
362 bool metaOnly = (data.readInt32() != 0);
363 ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d), metaOnly(%d)",
364 timeUs, option, colorFormat, metaOnly);
Dave Sparksec4dde72009-11-23 16:51:15 -0800365#ifndef DISABLE_GROUP_SCHEDULE_HACK
366 setSchedPolicy(data);
367#endif
Chong Zhang24c15772017-07-26 16:25:28 -0700368 sp<IMemory> bitmap = getFrameAtTime(timeUs, option, colorFormat, metaOnly);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800369 if (bitmap != 0) { // Don't send NULL across the binder interface
370 reply->writeInt32(NO_ERROR);
Marco Nelissen06b46062014-11-14 07:58:25 -0800371 reply->writeStrongBinder(IInterface::asBinder(bitmap));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800372 } else {
373 reply->writeInt32(UNKNOWN_ERROR);
374 }
Dave Sparksec4dde72009-11-23 16:51:15 -0800375#ifndef DISABLE_GROUP_SCHEDULE_HACK
376 restoreSchedPolicy();
377#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800378 return NO_ERROR;
379 } break;
Chong Zhangd3e0d862017-10-03 13:17:13 -0700380 case GET_IMAGE_AT_INDEX: {
381 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
382 int index = data.readInt32();
383 int colorFormat = data.readInt32();
384 bool metaOnly = (data.readInt32() != 0);
Chong Zhangd5fa3572018-04-09 19:03:10 -0700385 bool thumbnail = (data.readInt32() != 0);
386 ALOGV("getImageAtIndex: index(%d), colorFormat(%d), metaOnly(%d), thumbnail(%d)",
387 index, colorFormat, metaOnly, thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700388#ifndef DISABLE_GROUP_SCHEDULE_HACK
389 setSchedPolicy(data);
390#endif
Chong Zhangd5fa3572018-04-09 19:03:10 -0700391 sp<IMemory> bitmap = getImageAtIndex(index, colorFormat, metaOnly, thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700392 if (bitmap != 0) { // Don't send NULL across the binder interface
393 reply->writeInt32(NO_ERROR);
394 reply->writeStrongBinder(IInterface::asBinder(bitmap));
395 } else {
396 reply->writeInt32(UNKNOWN_ERROR);
397 }
398#ifndef DISABLE_GROUP_SCHEDULE_HACK
399 restoreSchedPolicy();
400#endif
401 return NO_ERROR;
402 } break;
Chong Zhang0c1407f2018-05-02 17:09:05 -0700403
404 case GET_IMAGE_RECT_AT_INDEX: {
405 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
406 int index = data.readInt32();
407 int colorFormat = data.readInt32();
408 int left = data.readInt32();
409 int top = data.readInt32();
410 int right = data.readInt32();
411 int bottom = data.readInt32();
412 ALOGV("getImageRectAtIndex: index(%d), colorFormat(%d), rect {%d, %d, %d, %d}",
413 index, colorFormat, left, top, right, bottom);
414#ifndef DISABLE_GROUP_SCHEDULE_HACK
415 setSchedPolicy(data);
416#endif
417 sp<IMemory> bitmap = getImageRectAtIndex(
418 index, colorFormat, left, top, right, bottom);
419 if (bitmap != 0) { // Don't send NULL across the binder interface
420 reply->writeInt32(NO_ERROR);
421 reply->writeStrongBinder(IInterface::asBinder(bitmap));
422 } else {
423 reply->writeInt32(UNKNOWN_ERROR);
424 }
425#ifndef DISABLE_GROUP_SCHEDULE_HACK
426 restoreSchedPolicy();
427#endif
428 return NO_ERROR;
429 } break;
430
Chong Zhangd3e0d862017-10-03 13:17:13 -0700431 case GET_FRAME_AT_INDEX: {
432 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
433 int frameIndex = data.readInt32();
434 int numFrames = data.readInt32();
435 int colorFormat = data.readInt32();
436 bool metaOnly = (data.readInt32() != 0);
437 ALOGV("getFrameAtIndex: frameIndex(%d), numFrames(%d), colorFormat(%d), metaOnly(%d)",
438 frameIndex, numFrames, colorFormat, metaOnly);
439#ifndef DISABLE_GROUP_SCHEDULE_HACK
440 setSchedPolicy(data);
441#endif
442 std::vector<sp<IMemory> > frames;
443 status_t err = getFrameAtIndex(
444 &frames, frameIndex, numFrames, colorFormat, metaOnly);
445 reply->writeInt32(err);
446 if (OK == err) {
447 reply->writeInt32(frames.size());
448 for (size_t i = 0; i < frames.size(); i++) {
449 reply->writeStrongBinder(IInterface::asBinder(frames[i]));
450 }
451 }
452#ifndef DISABLE_GROUP_SCHEDULE_HACK
453 restoreSchedPolicy();
454#endif
455 return NO_ERROR;
456 } break;
Dave Sparksec4dde72009-11-23 16:51:15 -0800457 case EXTRACT_ALBUM_ART: {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800458 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Dave Sparksec4dde72009-11-23 16:51:15 -0800459#ifndef DISABLE_GROUP_SCHEDULE_HACK
460 setSchedPolicy(data);
461#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800462 sp<IMemory> albumArt = extractAlbumArt();
463 if (albumArt != 0) { // Don't send NULL across the binder interface
464 reply->writeInt32(NO_ERROR);
Marco Nelissen06b46062014-11-14 07:58:25 -0800465 reply->writeStrongBinder(IInterface::asBinder(albumArt));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800466 } else {
467 reply->writeInt32(UNKNOWN_ERROR);
468 }
Dave Sparksec4dde72009-11-23 16:51:15 -0800469#ifndef DISABLE_GROUP_SCHEDULE_HACK
470 restoreSchedPolicy();
471#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800472 return NO_ERROR;
473 } break;
474 case EXTRACT_METADATA: {
475 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Dave Sparksec4dde72009-11-23 16:51:15 -0800476#ifndef DISABLE_GROUP_SCHEDULE_HACK
477 setSchedPolicy(data);
478#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800479 int keyCode = data.readInt32();
480 const char* value = extractMetadata(keyCode);
481 if (value != NULL) { // Don't send NULL across the binder interface
482 reply->writeInt32(NO_ERROR);
483 reply->writeCString(value);
484 } else {
485 reply->writeInt32(UNKNOWN_ERROR);
486 }
Dave Sparksec4dde72009-11-23 16:51:15 -0800487#ifndef DISABLE_GROUP_SCHEDULE_HACK
488 restoreSchedPolicy();
489#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800490 return NO_ERROR;
491 } break;
492 default:
493 return BBinder::onTransact(code, data, reply, flags);
494 }
495}
496
497// ----------------------------------------------------------------------------
498
Glenn Kasten40bc9062015-03-20 09:09:33 -0700499} // namespace android