IMediaPlayerService.cpp revision 2729ea9262ca60d93047e984739887cfc89e82eb
1/*
2**
3** Copyright 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
22#include <utils/IMemory.h>
23#include <media/IMediaPlayerService.h>
24
25namespace android {
26
27enum {
28    CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
29    CREATE_FD,
30    DECODE_URL,
31    DECODE_FD,
32};
33
34class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
35{
36public:
37    BpMediaPlayerService(const sp<IBinder>& impl)
38        : BpInterface<IMediaPlayerService>(impl)
39    {
40    }
41
42    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
43    {
44        Parcel data, reply;
45        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
46        data.writeInt32(pid);
47        data.writeStrongBinder(client->asBinder());
48        data.writeCString(url);
49        remote()->transact(CREATE_URL, data, &reply);
50        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
51    }
52
53    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length)
54    {
55        Parcel data, reply;
56        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
57        data.writeInt32(pid);
58        data.writeStrongBinder(client->asBinder());
59        data.writeFileDescriptor(fd);
60        data.writeInt64(offset);
61        data.writeInt64(length);
62        remote()->transact(CREATE_FD, data, &reply);
63        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
64    }
65
66    virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels)
67    {
68        Parcel data, reply;
69        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
70        data.writeCString(url);
71        remote()->transact(DECODE_URL, data, &reply);
72        *pSampleRate = uint32_t(reply.readInt32());
73        *pNumChannels = reply.readInt32();
74        return interface_cast<IMemory>(reply.readStrongBinder());
75    }
76
77    virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels)
78    {
79        Parcel data, reply;
80        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
81        data.writeFileDescriptor(fd);
82        data.writeInt64(offset);
83        data.writeInt64(length);
84        remote()->transact(DECODE_FD, data, &reply);
85        *pSampleRate = uint32_t(reply.readInt32());
86        *pNumChannels = reply.readInt32();
87        return interface_cast<IMemory>(reply.readStrongBinder());
88    }
89};
90
91IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.hardware.IMediaPlayerService");
92
93// ----------------------------------------------------------------------
94
95#define CHECK_INTERFACE(interface, data, reply) \
96        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
97            LOGW("Call incorrectly routed to " #interface); \
98            return PERMISSION_DENIED; \
99        } } while (0)
100
101status_t BnMediaPlayerService::onTransact(
102    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
103{
104    switch(code) {
105        case CREATE_URL: {
106            CHECK_INTERFACE(IMediaPlayerService, data, reply);
107            pid_t pid = data.readInt32();
108            sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
109            const char* url = data.readCString();
110            sp<IMediaPlayer> player = create(pid, client, url);
111            reply->writeStrongBinder(player->asBinder());
112            return NO_ERROR;
113        } break;
114        case CREATE_FD: {
115            CHECK_INTERFACE(IMediaPlayerService, data, reply);
116            pid_t pid = data.readInt32();
117            sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
118            int fd = dup(data.readFileDescriptor());
119            int64_t offset = data.readInt64();
120            int64_t length = data.readInt64();
121            sp<IMediaPlayer> player = create(pid, client, fd, offset, length);
122            reply->writeStrongBinder(player->asBinder());
123            return NO_ERROR;
124        } break;
125        case DECODE_URL: {
126            CHECK_INTERFACE(IMediaPlayerService, data, reply);
127            const char* url = data.readCString();
128            uint32_t sampleRate;
129            int numChannels;
130            sp<IMemory> player = decode(url, &sampleRate, &numChannels);
131            reply->writeInt32(sampleRate);
132            reply->writeInt32(numChannels);
133            reply->writeStrongBinder(player->asBinder());
134            return NO_ERROR;
135        } break;
136        case DECODE_FD: {
137            CHECK_INTERFACE(IMediaPlayerService, data, reply);
138            int fd = dup(data.readFileDescriptor());
139            int64_t offset = data.readInt64();
140            int64_t length = data.readInt64();
141            uint32_t sampleRate;
142            int numChannels;
143            sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels);
144            reply->writeInt32(sampleRate);
145            reply->writeInt32(numChannels);
146            reply->writeStrongBinder(player->asBinder());
147            return NO_ERROR;
148        } break;
149        default:
150            return BBinder::onTransact(code, data, reply, flags);
151    }
152}
153
154// ----------------------------------------------------------------------------
155
156}; // namespace android
157
158