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