blob: 028bea16f82900003ef6610425ccf6f660811213 [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>
Suren Baghdasaryan7435e7d2018-12-19 17:09:28 -080026#include <processgroup/sched_policy.h>
Andreas Huberaf8791e2011-03-21 10:25:44 -070027#include <utils/String8.h>
Sangkyu Leed01c1482013-02-08 16:26:39 +090028#include <utils/KeyedVector.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080029
Dave Sparksec4dde72009-11-23 16:51:15 -080030// The binder is supposed to propagate the scheduler group across
31// the binder interface so that remote calls are executed with
32// the same priority as local calls. This is currently not working
33// so this change puts in a temporary hack to fix the issue with
34// metadata retrieval which can be a huge CPU hit if done on a
35// foreground thread.
36#ifndef DISABLE_GROUP_SCHEDULE_HACK
37
Dave Sparksf311c552009-11-23 19:51:33 -080038#undef LOG_TAG
Dave Sparksec4dde72009-11-23 16:51:15 -080039#define LOG_TAG "IMediaMetadataRetriever"
40#include <utils/Log.h>
41#include <cutils/sched_policy.h>
42
43namespace android {
44
45static void sendSchedPolicy(Parcel& data)
46{
47 SchedPolicy policy;
Glenn Kasten0512ab52011-05-04 17:58:57 -070048 get_sched_policy(gettid(), &policy);
Dave Sparksec4dde72009-11-23 16:51:15 -080049 data.writeInt32(policy);
50}
51
52static void setSchedPolicy(const Parcel& data)
53{
54 SchedPolicy policy = (SchedPolicy) data.readInt32();
Glenn Kasten0512ab52011-05-04 17:58:57 -070055 set_sched_policy(gettid(), policy);
Dave Sparksec4dde72009-11-23 16:51:15 -080056}
57static void restoreSchedPolicy()
58{
Glenn Kasten0512ab52011-05-04 17:58:57 -070059 set_sched_policy(gettid(), SP_FOREGROUND);
Dave Sparksec4dde72009-11-23 16:51:15 -080060}
61}; // end namespace android
62#endif
63
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080064namespace android {
65
66enum {
67 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
68 SET_DATA_SOURCE_URL,
69 SET_DATA_SOURCE_FD,
Chris Watkins99f31602015-03-20 13:06:33 -070070 SET_DATA_SOURCE_CALLBACK,
James Dong16afe2f2010-12-02 17:42:08 -080071 GET_FRAME_AT_TIME,
Chong Zhangd3e0d862017-10-03 13:17:13 -070072 GET_IMAGE_AT_INDEX,
Chong Zhang0c1407f2018-05-02 17:09:05 -070073 GET_IMAGE_RECT_AT_INDEX,
Chong Zhangd3e0d862017-10-03 13:17:13 -070074 GET_FRAME_AT_INDEX,
Dave Sparksec4dde72009-11-23 16:51:15 -080075 EXTRACT_ALBUM_ART,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080076 EXTRACT_METADATA,
77};
78
79class BpMediaMetadataRetriever: public BpInterface<IMediaMetadataRetriever>
80{
81public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070082 explicit BpMediaMetadataRetriever(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080083 : BpInterface<IMediaMetadataRetriever>(impl)
84 {
85 }
86
87 // disconnect from media metadata retriever service
88 void disconnect()
89 {
90 Parcel data, reply;
91 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
92 remote()->transact(DISCONNECT, data, &reply);
93 }
94
Andreas Huberaf8791e2011-03-21 10:25:44 -070095 status_t setDataSource(
Andreas Huber1b86fe02014-01-29 11:13:26 -080096 const sp<IMediaHTTPService> &httpService,
97 const char *srcUrl,
98 const KeyedVector<String8, String8> *headers)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080099 {
100 Parcel data, reply;
101 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800102 data.writeInt32(httpService != NULL);
103 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800104 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800105 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800106 data.writeCString(srcUrl);
Andreas Huberaf8791e2011-03-21 10:25:44 -0700107
108 if (headers == NULL) {
109 data.writeInt32(0);
110 } else {
111 // serialize the headers
Ray Essick9c9fdf62019-05-14 12:04:42 -0700112 data.writeInt32(headers->size());
Andreas Huberaf8791e2011-03-21 10:25:44 -0700113 for (size_t i = 0; i < headers->size(); ++i) {
114 data.writeString8(headers->keyAt(i));
115 data.writeString8(headers->valueAt(i));
116 }
117 }
118
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800119 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
120 return reply.readInt32();
121 }
122
123 status_t setDataSource(int fd, int64_t offset, int64_t length)
124 {
125 Parcel data, reply;
126 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
127 data.writeFileDescriptor(fd);
128 data.writeInt64(offset);
129 data.writeInt64(length);
130 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
131 return reply.readInt32();
132 }
133
Chong Zhang24c15772017-07-26 16:25:28 -0700134 status_t setDataSource(const sp<IDataSource>& source, const char *mime)
Chris Watkins99f31602015-03-20 13:06:33 -0700135 {
136 Parcel data, reply;
137 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
138 data.writeStrongBinder(IInterface::asBinder(source));
Chong Zhang24c15772017-07-26 16:25:28 -0700139
140 if (mime != NULL) {
141 data.writeInt32(1);
142 data.writeCString(mime);
143 } else {
144 data.writeInt32(0);
145 }
Chris Watkins99f31602015-03-20 13:06:33 -0700146 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
147 return reply.readInt32();
148 }
149
Chong Zhang24c15772017-07-26 16:25:28 -0700150 sp<IMemory> getFrameAtTime(int64_t timeUs, int option, int colorFormat, bool metaOnly)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800151 {
Chong Zhang24c15772017-07-26 16:25:28 -0700152 ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d) metaOnly(%d)",
153 timeUs, option, colorFormat, metaOnly);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800154 Parcel data, reply;
155 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
James Dong16afe2f2010-12-02 17:42:08 -0800156 data.writeInt64(timeUs);
157 data.writeInt32(option);
Chong Zhang24c15772017-07-26 16:25:28 -0700158 data.writeInt32(colorFormat);
159 data.writeInt32(metaOnly);
Dave Sparksec4dde72009-11-23 16:51:15 -0800160#ifndef DISABLE_GROUP_SCHEDULE_HACK
161 sendSchedPolicy(data);
162#endif
James Dong16afe2f2010-12-02 17:42:08 -0800163 remote()->transact(GET_FRAME_AT_TIME, data, &reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800164 status_t ret = reply.readInt32();
165 if (ret != NO_ERROR) {
166 return NULL;
167 }
168 return interface_cast<IMemory>(reply.readStrongBinder());
169 }
170
Chong Zhangd5fa3572018-04-09 19:03:10 -0700171 sp<IMemory> getImageAtIndex(int index, int colorFormat, bool metaOnly, bool thumbnail)
Chong Zhangd3e0d862017-10-03 13:17:13 -0700172 {
Chong Zhangd5fa3572018-04-09 19:03:10 -0700173 ALOGV("getImageAtIndex: index %d, colorFormat(%d) metaOnly(%d) thumbnail(%d)",
174 index, colorFormat, metaOnly, thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700175 Parcel data, reply;
176 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
177 data.writeInt32(index);
178 data.writeInt32(colorFormat);
179 data.writeInt32(metaOnly);
Chong Zhangd5fa3572018-04-09 19:03:10 -0700180 data.writeInt32(thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700181#ifndef DISABLE_GROUP_SCHEDULE_HACK
182 sendSchedPolicy(data);
183#endif
184 remote()->transact(GET_IMAGE_AT_INDEX, data, &reply);
185 status_t ret = reply.readInt32();
186 if (ret != NO_ERROR) {
187 return NULL;
188 }
189 return interface_cast<IMemory>(reply.readStrongBinder());
190 }
191
Chong Zhang0c1407f2018-05-02 17:09:05 -0700192 sp<IMemory> getImageRectAtIndex(
193 int index, int colorFormat, int left, int top, int right, int bottom)
194 {
195 ALOGV("getImageRectAtIndex: index %d, colorFormat(%d) rect {%d, %d, %d, %d}",
196 index, colorFormat, left, top, right, bottom);
197 Parcel data, reply;
198 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
199 data.writeInt32(index);
200 data.writeInt32(colorFormat);
201 data.writeInt32(left);
202 data.writeInt32(top);
203 data.writeInt32(right);
204 data.writeInt32(bottom);
205#ifndef DISABLE_GROUP_SCHEDULE_HACK
206 sendSchedPolicy(data);
207#endif
208 remote()->transact(GET_IMAGE_RECT_AT_INDEX, data, &reply);
209 status_t ret = reply.readInt32();
210 if (ret != NO_ERROR) {
211 return NULL;
212 }
213 return interface_cast<IMemory>(reply.readStrongBinder());
214 }
215
Chong Zhangd3e0d862017-10-03 13:17:13 -0700216 status_t getFrameAtIndex(std::vector<sp<IMemory> > *frames,
217 int frameIndex, int numFrames, int colorFormat, bool metaOnly)
218 {
219 ALOGV("getFrameAtIndex: frameIndex(%d), numFrames(%d), colorFormat(%d) metaOnly(%d)",
220 frameIndex, numFrames, colorFormat, metaOnly);
221 Parcel data, reply;
222 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
223 data.writeInt32(frameIndex);
224 data.writeInt32(numFrames);
225 data.writeInt32(colorFormat);
226 data.writeInt32(metaOnly);
227#ifndef DISABLE_GROUP_SCHEDULE_HACK
228 sendSchedPolicy(data);
229#endif
230 remote()->transact(GET_FRAME_AT_INDEX, data, &reply);
231 status_t ret = reply.readInt32();
232 if (ret != NO_ERROR) {
233 return ret;
234 }
235 int retNumFrames = reply.readInt32();
236 if (retNumFrames < numFrames) {
237 numFrames = retNumFrames;
238 }
239 for (int i = 0; i < numFrames; i++) {
240 frames->push_back(interface_cast<IMemory>(reply.readStrongBinder()));
241 }
242 return OK;
243 }
244
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800245 sp<IMemory> extractAlbumArt()
246 {
247 Parcel data, reply;
248 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
Dave Sparksec4dde72009-11-23 16:51:15 -0800249#ifndef DISABLE_GROUP_SCHEDULE_HACK
250 sendSchedPolicy(data);
251#endif
252 remote()->transact(EXTRACT_ALBUM_ART, data, &reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800253 status_t ret = reply.readInt32();
254 if (ret != NO_ERROR) {
255 return NULL;
256 }
257 return interface_cast<IMemory>(reply.readStrongBinder());
258 }
259
260 const char* extractMetadata(int keyCode)
261 {
262 Parcel data, reply;
263 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
Dave Sparksec4dde72009-11-23 16:51:15 -0800264#ifndef DISABLE_GROUP_SCHEDULE_HACK
265 sendSchedPolicy(data);
266#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800267 data.writeInt32(keyCode);
268 remote()->transact(EXTRACT_METADATA, data, &reply);
269 status_t ret = reply.readInt32();
270 if (ret != NO_ERROR) {
271 return NULL;
272 }
Sangkyu Leed01c1482013-02-08 16:26:39 +0900273 const char* str = reply.readCString();
274 if (str != NULL) {
275 String8 value(str);
276 if (mMetadata.indexOfKey(keyCode) < 0) {
277 mMetadata.add(keyCode, value);
278 } else {
279 mMetadata.replaceValueFor(keyCode, value);
280 }
281 return mMetadata.valueFor(keyCode).string();
282 } else {
283 return NULL;
284 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800285 }
Sangkyu Leed01c1482013-02-08 16:26:39 +0900286
287private:
288 KeyedVector<int, String8> mMetadata;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800289};
290
niko56f0cc52009-06-22 08:49:52 -0700291IMPLEMENT_META_INTERFACE(MediaMetadataRetriever, "android.media.IMediaMetadataRetriever");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800292
293// ----------------------------------------------------------------------
294
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800295status_t BnMediaMetadataRetriever::onTransact(
296 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
297{
298 switch (code) {
299 case DISCONNECT: {
300 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
301 disconnect();
302 return NO_ERROR;
303 } break;
304 case SET_DATA_SOURCE_URL: {
305 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800306
307 sp<IMediaHTTPService> httpService;
308 if (data.readInt32()) {
309 httpService =
310 interface_cast<IMediaHTTPService>(data.readStrongBinder());
311 }
312
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800313 const char* srcUrl = data.readCString();
Andreas Huberaf8791e2011-03-21 10:25:44 -0700314
Wei Jia2afac0c2016-01-07 12:13:07 -0800315 if (httpService == NULL || srcUrl == NULL) {
316 reply->writeInt32(BAD_VALUE);
317 return NO_ERROR;
318 }
319
Andreas Huberaf8791e2011-03-21 10:25:44 -0700320 KeyedVector<String8, String8> headers;
Ray Essick9c9fdf62019-05-14 12:04:42 -0700321 size_t numHeaders = (size_t) data.readInt32();
Glenn Kastene03dd222014-01-28 11:04:39 -0800322 for (size_t i = 0; i < numHeaders; ++i) {
Ray Essick9c9fdf62019-05-14 12:04:42 -0700323 String8 key;
324 String8 value;
325 status_t status;
326 status = data.readString8(&key);
327 if (status != OK) {
328 return status;
329 }
330 status = data.readString8(&value);
331 if (status != OK) {
332 return status;
333 }
334 if (headers.add(key, value) < 0) {
335 return UNKNOWN_ERROR;
336 }
Andreas Huberaf8791e2011-03-21 10:25:44 -0700337 }
338
339 reply->writeInt32(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800340 setDataSource(
341 httpService, srcUrl, numHeaders > 0 ? &headers : NULL));
Andreas Huberaf8791e2011-03-21 10:25:44 -0700342
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800343 return NO_ERROR;
344 } break;
345 case SET_DATA_SOURCE_FD: {
346 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Taiju Tsuiki55203e22015-04-21 17:36:22 +0900347 int fd = data.readFileDescriptor();
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800348 int64_t offset = data.readInt64();
349 int64_t length = data.readInt64();
350 reply->writeInt32(setDataSource(fd, offset, length));
351 return NO_ERROR;
352 } break;
Chris Watkins99f31602015-03-20 13:06:33 -0700353 case SET_DATA_SOURCE_CALLBACK: {
354 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
355 sp<IDataSource> source =
356 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800357 if (source == NULL) {
358 reply->writeInt32(BAD_VALUE);
359 } else {
Chong Zhang24c15772017-07-26 16:25:28 -0700360 int32_t hasMime = data.readInt32();
361 const char *mime = NULL;
362 if (hasMime) {
363 mime = data.readCString();
364 }
365 reply->writeInt32(setDataSource(source, mime));
Wei Jia2afac0c2016-01-07 12:13:07 -0800366 }
Chris Watkins99f31602015-03-20 13:06:33 -0700367 return NO_ERROR;
368 } break;
James Dong16afe2f2010-12-02 17:42:08 -0800369 case GET_FRAME_AT_TIME: {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800370 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
James Dong16afe2f2010-12-02 17:42:08 -0800371 int64_t timeUs = data.readInt64();
372 int option = data.readInt32();
Chong Zhang24c15772017-07-26 16:25:28 -0700373 int colorFormat = data.readInt32();
374 bool metaOnly = (data.readInt32() != 0);
375 ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d), metaOnly(%d)",
376 timeUs, option, colorFormat, metaOnly);
Dave Sparksec4dde72009-11-23 16:51:15 -0800377#ifndef DISABLE_GROUP_SCHEDULE_HACK
378 setSchedPolicy(data);
379#endif
Chong Zhang24c15772017-07-26 16:25:28 -0700380 sp<IMemory> bitmap = getFrameAtTime(timeUs, option, colorFormat, metaOnly);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800381 if (bitmap != 0) { // Don't send NULL across the binder interface
382 reply->writeInt32(NO_ERROR);
Marco Nelissen06b46062014-11-14 07:58:25 -0800383 reply->writeStrongBinder(IInterface::asBinder(bitmap));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800384 } else {
385 reply->writeInt32(UNKNOWN_ERROR);
386 }
Dave Sparksec4dde72009-11-23 16:51:15 -0800387#ifndef DISABLE_GROUP_SCHEDULE_HACK
388 restoreSchedPolicy();
389#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800390 return NO_ERROR;
391 } break;
Chong Zhangd3e0d862017-10-03 13:17:13 -0700392 case GET_IMAGE_AT_INDEX: {
393 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
394 int index = data.readInt32();
395 int colorFormat = data.readInt32();
396 bool metaOnly = (data.readInt32() != 0);
Chong Zhangd5fa3572018-04-09 19:03:10 -0700397 bool thumbnail = (data.readInt32() != 0);
398 ALOGV("getImageAtIndex: index(%d), colorFormat(%d), metaOnly(%d), thumbnail(%d)",
399 index, colorFormat, metaOnly, thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700400#ifndef DISABLE_GROUP_SCHEDULE_HACK
401 setSchedPolicy(data);
402#endif
Chong Zhangd5fa3572018-04-09 19:03:10 -0700403 sp<IMemory> bitmap = getImageAtIndex(index, colorFormat, metaOnly, thumbnail);
Chong Zhangd3e0d862017-10-03 13:17:13 -0700404 if (bitmap != 0) { // Don't send NULL across the binder interface
405 reply->writeInt32(NO_ERROR);
406 reply->writeStrongBinder(IInterface::asBinder(bitmap));
407 } else {
408 reply->writeInt32(UNKNOWN_ERROR);
409 }
410#ifndef DISABLE_GROUP_SCHEDULE_HACK
411 restoreSchedPolicy();
412#endif
413 return NO_ERROR;
414 } break;
Chong Zhang0c1407f2018-05-02 17:09:05 -0700415
416 case GET_IMAGE_RECT_AT_INDEX: {
417 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
418 int index = data.readInt32();
419 int colorFormat = data.readInt32();
420 int left = data.readInt32();
421 int top = data.readInt32();
422 int right = data.readInt32();
423 int bottom = data.readInt32();
424 ALOGV("getImageRectAtIndex: index(%d), colorFormat(%d), rect {%d, %d, %d, %d}",
425 index, colorFormat, left, top, right, bottom);
426#ifndef DISABLE_GROUP_SCHEDULE_HACK
427 setSchedPolicy(data);
428#endif
429 sp<IMemory> bitmap = getImageRectAtIndex(
430 index, colorFormat, left, top, right, bottom);
431 if (bitmap != 0) { // Don't send NULL across the binder interface
432 reply->writeInt32(NO_ERROR);
433 reply->writeStrongBinder(IInterface::asBinder(bitmap));
434 } else {
435 reply->writeInt32(UNKNOWN_ERROR);
436 }
437#ifndef DISABLE_GROUP_SCHEDULE_HACK
438 restoreSchedPolicy();
439#endif
440 return NO_ERROR;
441 } break;
442
Chong Zhangd3e0d862017-10-03 13:17:13 -0700443 case GET_FRAME_AT_INDEX: {
444 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
445 int frameIndex = data.readInt32();
446 int numFrames = data.readInt32();
447 int colorFormat = data.readInt32();
448 bool metaOnly = (data.readInt32() != 0);
449 ALOGV("getFrameAtIndex: frameIndex(%d), numFrames(%d), colorFormat(%d), metaOnly(%d)",
450 frameIndex, numFrames, colorFormat, metaOnly);
451#ifndef DISABLE_GROUP_SCHEDULE_HACK
452 setSchedPolicy(data);
453#endif
454 std::vector<sp<IMemory> > frames;
455 status_t err = getFrameAtIndex(
456 &frames, frameIndex, numFrames, colorFormat, metaOnly);
457 reply->writeInt32(err);
458 if (OK == err) {
459 reply->writeInt32(frames.size());
460 for (size_t i = 0; i < frames.size(); i++) {
461 reply->writeStrongBinder(IInterface::asBinder(frames[i]));
462 }
463 }
464#ifndef DISABLE_GROUP_SCHEDULE_HACK
465 restoreSchedPolicy();
466#endif
467 return NO_ERROR;
468 } break;
Dave Sparksec4dde72009-11-23 16:51:15 -0800469 case EXTRACT_ALBUM_ART: {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800470 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Dave Sparksec4dde72009-11-23 16:51:15 -0800471#ifndef DISABLE_GROUP_SCHEDULE_HACK
472 setSchedPolicy(data);
473#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800474 sp<IMemory> albumArt = extractAlbumArt();
475 if (albumArt != 0) { // Don't send NULL across the binder interface
476 reply->writeInt32(NO_ERROR);
Marco Nelissen06b46062014-11-14 07:58:25 -0800477 reply->writeStrongBinder(IInterface::asBinder(albumArt));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800478 } else {
479 reply->writeInt32(UNKNOWN_ERROR);
480 }
Dave Sparksec4dde72009-11-23 16:51:15 -0800481#ifndef DISABLE_GROUP_SCHEDULE_HACK
482 restoreSchedPolicy();
483#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800484 return NO_ERROR;
485 } break;
486 case EXTRACT_METADATA: {
487 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
Dave Sparksec4dde72009-11-23 16:51:15 -0800488#ifndef DISABLE_GROUP_SCHEDULE_HACK
489 setSchedPolicy(data);
490#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800491 int keyCode = data.readInt32();
492 const char* value = extractMetadata(keyCode);
493 if (value != NULL) { // Don't send NULL across the binder interface
494 reply->writeInt32(NO_ERROR);
495 reply->writeCString(value);
496 } else {
497 reply->writeInt32(UNKNOWN_ERROR);
498 }
Dave Sparksec4dde72009-11-23 16:51:15 -0800499#ifndef DISABLE_GROUP_SCHEDULE_HACK
500 restoreSchedPolicy();
501#endif
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800502 return NO_ERROR;
503 } break;
504 default:
505 return BBinder::onTransact(code, data, reply, flags);
506 }
507}
508
509// ----------------------------------------------------------------------------
510
Glenn Kasten40bc9062015-03-20 09:09:33 -0700511} // namespace android