IEffect.cpp revision d71a1be83ff31cdb6599c351f9832cefc8d447ba
1/*
2**
3** Copyright 2010, 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//#define LOG_NDEBUG 0
19#define LOG_TAG "IEffect"
20#include <utils/Log.h>
21#include <stdint.h>
22#include <sys/types.h>
23#include <binder/Parcel.h>
24#include <media/IEffect.h>
25
26namespace android {
27
28enum {
29    ENABLE = IBinder::FIRST_CALL_TRANSACTION,
30    DISABLE,
31    COMMAND,
32    DISCONNECT,
33    GET_CBLK
34};
35
36class BpEffect: public BpInterface<IEffect>
37{
38public:
39    BpEffect(const sp<IBinder>& impl)
40        : BpInterface<IEffect>(impl)
41    {
42    }
43
44    status_t enable()
45    {
46        LOGV("enable");
47        Parcel data, reply;
48        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
49        remote()->transact(ENABLE, data, &reply);
50        return reply.readInt32();
51    }
52
53    status_t disable()
54    {
55        LOGV("disable");
56        Parcel data, reply;
57        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
58        remote()->transact(DISABLE, data, &reply);
59        return reply.readInt32();
60    }
61
62    status_t command(int cmdCode, int cmdSize, void *pCmdData, int *pReplySize, void *pReplyData)
63    {
64        LOGV("command");
65        Parcel data, reply;
66        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
67        data.writeInt32(cmdCode);
68        int size = cmdSize;
69        if (pCmdData == NULL) {
70            size = 0;
71        }
72        data.writeInt32(size);
73        if (size) {
74            data.write(pCmdData, size);
75        }
76        if (pReplySize == NULL) {
77            size = 0;
78        } else {
79            size = *pReplySize;
80        }
81        data.writeInt32(size);
82        remote()->transact(COMMAND, data, &reply);
83        status_t status = reply.readInt32();
84        size = reply.readInt32();
85        if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
86            reply.read(pReplyData, size);
87            *pReplySize = size;
88        }
89        return status;
90    }
91
92    void disconnect()
93    {
94        LOGV("disconnect");
95        Parcel data, reply;
96        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
97        remote()->transact(DISCONNECT, data, &reply);
98        return;
99    }
100
101    virtual sp<IMemory> getCblk() const
102    {
103        Parcel data, reply;
104        sp<IMemory> cblk;
105        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
106        status_t status = remote()->transact(GET_CBLK, data, &reply);
107        if (status == NO_ERROR) {
108            cblk = interface_cast<IMemory>(reply.readStrongBinder());
109        }
110        return cblk;
111    }
112 };
113
114IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect");
115
116// ----------------------------------------------------------------------
117
118status_t BnEffect::onTransact(
119    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
120{
121    switch(code) {
122        case ENABLE: {
123            LOGV("ENABLE");
124            CHECK_INTERFACE(IEffect, data, reply);
125            reply->writeInt32(enable());
126            return NO_ERROR;
127        } break;
128
129        case DISABLE: {
130            LOGV("DISABLE");
131            CHECK_INTERFACE(IEffect, data, reply);
132            reply->writeInt32(disable());
133            return NO_ERROR;
134        } break;
135
136        case COMMAND: {
137            LOGV("COMMAND");
138            CHECK_INTERFACE(IEffect, data, reply);
139            int cmdCode = data.readInt32();
140            int cmdSize = data.readInt32();
141            char *cmd = NULL;
142            if (cmdSize) {
143                cmd = (char *)malloc(cmdSize);
144                data.read(cmd, cmdSize);
145            }
146            int replySize = data.readInt32();
147            int replySz = replySize;
148            char *resp = NULL;
149            if (replySize) {
150                resp = (char *)malloc(replySize);
151            }
152            status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
153            reply->writeInt32(status);
154            if (replySz < replySize) {
155                replySize = replySz;
156            }
157            reply->writeInt32(replySize);
158            if (replySize) {
159                reply->write(resp, replySize);
160            }
161            if (cmd) {
162                free(cmd);
163            }
164            if (resp) {
165                free(resp);
166            }
167            return NO_ERROR;
168        } break;
169
170        case DISCONNECT: {
171            LOGV("DISCONNECT");
172            CHECK_INTERFACE(IEffect, data, reply);
173            disconnect();
174            return NO_ERROR;
175        } break;
176
177        case GET_CBLK: {
178             CHECK_INTERFACE(IEffect, data, reply);
179             reply->writeStrongBinder(getCblk()->asBinder());
180             return NO_ERROR;
181         } break;
182
183        default:
184            return BBinder::onTransact(code, data, reply, flags);
185    }
186}
187
188// ----------------------------------------------------------------------------
189
190}; // namespace android
191
192