1b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen/*
2b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * Copyright (C) 2009 The Android Open Source Project
3b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *
4b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
5b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * you may not use this file except in compliance with the License.
6b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * You may obtain a copy of the License at
7b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *
8b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
9b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *
10b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * Unless required by applicable law or agreed to in writing, software
11b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
12b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * See the License for the specific language governing permissions and
14b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * limitations under the License.
15b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen */
16b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
17b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen//#define LOG_NDEBUG 0
18b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define LOG_TAG "BpMediaExtractor"
19b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <utils/Log.h>
20b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
21b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <stdint.h>
22b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <sys/types.h>
23b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
2469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen#include <binder/IPCThreadState.h>
25b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <binder/Parcel.h>
26b596c34e953f167030bf695d1f813e99d238abddray-cy.lee#include <binder/PermissionCache.h>
27b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/IMediaExtractor.h>
28b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/stagefright/MetaData.h>
29b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
30b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissennamespace android {
31b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
32b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenenum {
33b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    COUNTTRACKS = IBinder::FIRST_CALL_TRANSACTION,
34b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    GETTRACK,
35b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    GETTRACKMETADATA,
36b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    GETMETADATA,
37b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    FLAGS,
389dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang    SETMEDIACAS,
39ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick    NAME,
402a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen    GETMETRICS
41b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen};
42b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
43b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenclass BpMediaExtractor : public BpInterface<IMediaExtractor> {
44b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenpublic:
4564a2870d8515fd914638c60803db86dbd92f5b06Chih-Hung Hsieh    explicit BpMediaExtractor(const sp<IBinder>& impl)
46b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        : BpInterface<IMediaExtractor>(impl)
47b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    {
48b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
49b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
50b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual size_t countTracks() {
51b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("countTracks");
52b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
53b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
54b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(COUNTTRACKS, data, &reply);
55b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        size_t numTracks = 0;
56b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret == NO_ERROR) {
57b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            numTracks = reply.readUint32();
58b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
59b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return numTracks;
60b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
61b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual sp<IMediaSource> getTrack(size_t index) {
62b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("getTrack(%zu)", index);
63b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
64b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
65b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeUint32(index);
66b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(GETTRACK, data, &reply);
67b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret == NO_ERROR) {
68b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return interface_cast<IMediaSource>(reply.readStrongBinder());
69b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
70b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return NULL;
71b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
72b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
73b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual sp<MetaData> getTrackMetaData(
74b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            size_t index, uint32_t flags) {
75b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("getTrackMetaData(%zu, %u)", index, flags);
76b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
77b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
78b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeUint32(index);
79b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeUint32(flags);
80b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(GETTRACKMETADATA, data, &reply);
81b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret == NO_ERROR) {
82b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return MetaData::createFromParcel(reply);
83b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
84b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return NULL;
85b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
86b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
87b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual sp<MetaData> getMetaData() {
88b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("getMetaData");
89b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
90b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
91b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(GETMETADATA, data, &reply);
92b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret == NO_ERROR) {
93b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return MetaData::createFromParcel(reply);
94b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
95b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return NULL;
96b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
97b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
98ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick    virtual status_t getMetrics(Parcel * reply) {
99ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        Parcel data;
100ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
101ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        status_t ret = remote()->transact(GETMETRICS, data, reply);
102ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        if (ret == NO_ERROR) {
103ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick            return OK;
104ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        }
105ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        return UNKNOWN_ERROR;
106ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick    }
107ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick
108b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual uint32_t flags() const {
109b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("flags NOT IMPLEMENTED");
110b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return 0;
111b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
112b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
113d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    virtual status_t setMediaCas(const HInterfaceToken &casToken) {
1149dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        ALOGV("setMediaCas");
1159dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang
1169dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        Parcel data, reply;
1179dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
118d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        data.writeByteVector(casToken);
1199dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang
1209dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        status_t err = remote()->transact(SETMEDIACAS, data, &reply);
1219dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        if (err != NO_ERROR) {
1229dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            return err;
1239dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        }
1249dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        return reply.readInt32();
1259dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang    }
1269dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang
127b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual const char * name() {
128b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("name NOT IMPLEMENTED");
129b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return NULL;
130b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
131b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen};
132b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
133b2487f03f12dcafdb801fc0007c8df8412397f44Marco NelissenIMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
134b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
135b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#undef LOG_TAG
136b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define LOG_TAG "BnMediaExtractor"
137b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
138b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatus_t BnMediaExtractor::onTransact(
139b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
140b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen{
141b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    switch (code) {
142b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case COUNTTRACKS: {
143b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("countTracks");
144b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaExtractor, data, reply);
145b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            size_t numTracks = countTracks();
146b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (numTracks > INT32_MAX) {
147b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                numTracks = 0;
148b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
149b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            reply->writeUint32(uint32_t(numTracks));
150b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return NO_ERROR;
151b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
152b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case GETTRACK: {
153b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("getTrack()");
154b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaExtractor, data, reply);
155b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            uint32_t idx;
156b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (data.readUint32(&idx) == NO_ERROR) {
15769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen                const sp<IMediaSource> track = getTrack(size_t(idx));
15869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen                registerMediaSource(this, track);
15969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen                return reply->writeStrongBinder(IInterface::asBinder(track));
160b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
161b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return UNKNOWN_ERROR;
162b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
163b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case GETTRACKMETADATA: {
164b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("getTrackMetaData");
165b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaExtractor, data, reply);
166b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            uint32_t idx;
167b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            uint32_t flags;
168b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (data.readUint32(&idx) == NO_ERROR &&
169b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                    data.readUint32(&flags) == NO_ERROR) {
170b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                sp<MetaData> meta = getTrackMetaData(idx, flags);
1710d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                if (meta == NULL) {
1720d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                    return UNKNOWN_ERROR;
1730d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                }
174b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                meta->writeToParcel(*reply);
175b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                return NO_ERROR;
176b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
177b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return UNKNOWN_ERROR;
178b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
179b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case GETMETADATA: {
180b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("getMetaData");
181b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaExtractor, data, reply);
182b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            sp<MetaData> meta = getMetaData();
183b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (meta != NULL) {
184b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                meta->writeToParcel(*reply);
185b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                return NO_ERROR;
186b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
187b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return UNKNOWN_ERROR;
188b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
189ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        case GETMETRICS: {
190ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick            CHECK_INTERFACE(IMediaExtractor, data, reply);
191ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick            status_t ret = getMetrics(reply);
192ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick            return ret;
193ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick        }
1949dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        case SETMEDIACAS: {
1959dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            ALOGV("setMediaCas");
1969dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            CHECK_INTERFACE(IMediaExtractor, data, reply);
1979dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang
198d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            HInterfaceToken casToken;
199d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            status_t err = data.readByteVector(&casToken);
2009dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            if (err != NO_ERROR) {
201d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                ALOGE("Error reading casToken from parcel");
2029dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang                return err;
2039dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            }
2049dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang
205d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            reply->writeInt32(setMediaCas(casToken));
2069dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            return OK;
2079dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        }
208b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        default:
209b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return BBinder::onTransact(code, data, reply, flags);
210b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
211b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
212b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
21369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissentypedef struct {
21469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 mime;
21569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 name;
21669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 sourceDescription;
21769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    pid_t owner;
21869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    wp<IMediaExtractor> extractor;
21969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    Vector<wp<IMediaSource>> tracks;
22069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    Vector<String8> trackDescriptions;
22169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 toString() const;
22269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen} ExtractorInstance;
22369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
22469d3d8a9540b0da787ea0beccad2517f057dd54dMarco NelissenString8 ExtractorInstance::toString() const {
22569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 str = name;
22669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    str.append(" for mime ");
22769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    str.append(mime);
22869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    str.append(", source ");
22969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    str.append(sourceDescription);
23069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    str.append(String8::format(", pid %d: ", owner));
23169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    if (extractor.promote() == NULL) {
23269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        str.append("deleted\n");
23369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    } else {
23469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        str.append("active\n");
23569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
23669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    for (size_t i = 0; i < tracks.size(); i++) {
23769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        const String8 desc = trackDescriptions.itemAt(i);
23869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        str.appendFormat("    track {%s} ", desc.string());
239460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen        wp<IMediaSource> wSource = tracks.itemAt(i);
240460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen        if (wSource == NULL) {
241460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            str.append(": null\n");
24269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        } else {
243460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            const sp<IMediaSource> source = wSource.promote();
244460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            if (source == NULL) {
245460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen                str.append(": deleted\n");
246460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            } else {
247460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen                str.appendFormat(": active\n");
248460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            }
24969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        }
25069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
25169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    return str;
25269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen}
25369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
2548d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissenstatic Vector<ExtractorInstance> sExtractors;
2558d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissenstatic Mutex sExtractorsLock;
25669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
25769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissenvoid registerMediaSource(
25869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        const sp<IMediaExtractor> &ex,
25969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        const sp<IMediaSource> &source) {
2608d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen    Mutex::Autolock lock(sExtractorsLock);
2618d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen    for (size_t i = 0; i < sExtractors.size(); i++) {
2628d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen        ExtractorInstance &instance = sExtractors.editItemAt(i);
26369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        sp<IMediaExtractor> extractor = instance.extractor.promote();
26469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        if (extractor != NULL && extractor == ex) {
26569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen            if (instance.tracks.size() > 5) {
26669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen                instance.tracks.resize(5);
267460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen                instance.trackDescriptions.resize(5);
26869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen            }
26969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen            instance.tracks.push_front(source);
270460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            if (source != NULL) {
271460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen                instance.trackDescriptions.push_front(source->getFormat()->toString());
272460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            } else {
273460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen                instance.trackDescriptions.push_front(String8::empty());
274460b7e88f1e7d13e934c9596fbd799c39e63d788Marco Nelissen            }
27569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen            break;
27669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        }
27769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
27869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen}
27969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
28069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissenvoid registerMediaExtractor(
28169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        const sp<IMediaExtractor> &extractor,
282a321469104536544d1cf0c0098d14bbf14186e88Marco Nelissen        const sp<DataSource> &source,
28369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        const char *mime) {
28469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    ExtractorInstance ex;
28569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    ex.mime = mime == NULL ? "NULL" : mime;
28669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    ex.name = extractor->name();
28769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    ex.sourceDescription = source->toString();
28869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    ex.owner = IPCThreadState::self()->getCallingPid();
28969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    ex.extractor = extractor;
29069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
2918d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen    {
2928d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen        Mutex::Autolock lock(sExtractorsLock);
2938d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen        if (sExtractors.size() > 10) {
2948d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen            sExtractors.resize(10);
2958d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen        }
2968d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen        sExtractors.push_front(ex);
29769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
29869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen}
29969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
30069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissenstatus_t dumpExtractors(int fd, const Vector<String16>&) {
30169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 out;
302b596c34e953f167030bf695d1f813e99d238abddray-cy.lee    const IPCThreadState* ipc = IPCThreadState::self();
303b596c34e953f167030bf695d1f813e99d238abddray-cy.lee    const int pid = ipc->getCallingPid();
304b596c34e953f167030bf695d1f813e99d238abddray-cy.lee    const int uid = ipc->getCallingUid();
305b596c34e953f167030bf695d1f813e99d238abddray-cy.lee    if (!PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
306b596c34e953f167030bf695d1f813e99d238abddray-cy.lee        out.appendFormat("Permission Denial: "
307b596c34e953f167030bf695d1f813e99d238abddray-cy.lee                "can't dump MediaExtractor from pid=%d, uid=%d\n", pid, uid);
308b596c34e953f167030bf695d1f813e99d238abddray-cy.lee    } else {
309b596c34e953f167030bf695d1f813e99d238abddray-cy.lee        out.append("Recent extractors, most recent first:\n");
310b596c34e953f167030bf695d1f813e99d238abddray-cy.lee        {
311b596c34e953f167030bf695d1f813e99d238abddray-cy.lee            Mutex::Autolock lock(sExtractorsLock);
312b596c34e953f167030bf695d1f813e99d238abddray-cy.lee            for (size_t i = 0; i < sExtractors.size(); i++) {
313b596c34e953f167030bf695d1f813e99d238abddray-cy.lee                const ExtractorInstance &instance = sExtractors.itemAt(i);
314b596c34e953f167030bf695d1f813e99d238abddray-cy.lee                out.append("  ");
315b596c34e953f167030bf695d1f813e99d238abddray-cy.lee                out.append(instance.toString());
316b596c34e953f167030bf695d1f813e99d238abddray-cy.lee            }
3178d27f5e1be1d301e0427f483493390419fe36acfMarco Nelissen        }
31869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
31969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    write(fd, out.string(), out.size());
32069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    return OK;
32169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen}
32269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
323b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
324b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}  // namespace android
325b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
326