blob: b087100b1ec0051e9cd76e2a20aa864d05c5d215 [file] [log] [blame]
The Android Open Source Project2729ea92008-10-21 07:00:00 -07001/*
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