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         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(uint32_t cmdCode,
     63                      uint32_t cmdSize,
     64                      void *pCmdData,
     65                      uint32_t *pReplySize,
     66                      void *pReplyData)
     67     {
     68         LOGV("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         remote()->transact(COMMAND, data, &reply);
     87         status_t status = reply.readInt32();
     88         size = reply.readInt32();
     89         if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
     90             reply.read(pReplyData, size);
     91             *pReplySize = size;
     92         }
     93         return status;
     94     }
     95 
     96     void disconnect()
     97     {
     98         LOGV("disconnect");
     99         Parcel data, reply;
    100         data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
    101         remote()->transact(DISCONNECT, data, &reply);
    102         return;
    103     }
    104 
    105     virtual sp<IMemory> getCblk() const
    106     {
    107         Parcel data, reply;
    108         sp<IMemory> cblk;
    109         data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
    110         status_t status = remote()->transact(GET_CBLK, data, &reply);
    111         if (status == NO_ERROR) {
    112             cblk = interface_cast<IMemory>(reply.readStrongBinder());
    113         }
    114         return cblk;
    115     }
    116  };
    117 
    118 IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect");
    119 
    120 // ----------------------------------------------------------------------
    121 
    122 status_t BnEffect::onTransact(
    123     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    124 {
    125     switch(code) {
    126         case ENABLE: {
    127             LOGV("ENABLE");
    128             CHECK_INTERFACE(IEffect, data, reply);
    129             reply->writeInt32(enable());
    130             return NO_ERROR;
    131         } break;
    132 
    133         case DISABLE: {
    134             LOGV("DISABLE");
    135             CHECK_INTERFACE(IEffect, data, reply);
    136             reply->writeInt32(disable());
    137             return NO_ERROR;
    138         } break;
    139 
    140         case COMMAND: {
    141             LOGV("COMMAND");
    142             CHECK_INTERFACE(IEffect, data, reply);
    143             uint32_t cmdCode = data.readInt32();
    144             uint32_t cmdSize = data.readInt32();
    145             char *cmd = NULL;
    146             if (cmdSize) {
    147                 cmd = (char *)malloc(cmdSize);
    148                 data.read(cmd, cmdSize);
    149             }
    150             uint32_t replySize = data.readInt32();
    151             uint32_t replySz = replySize;
    152             char *resp = NULL;
    153             if (replySize) {
    154                 resp = (char *)malloc(replySize);
    155             }
    156             status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
    157             reply->writeInt32(status);
    158             if (replySz < replySize) {
    159                 replySize = replySz;
    160             }
    161             reply->writeInt32(replySize);
    162             if (replySize) {
    163                 reply->write(resp, replySize);
    164             }
    165             if (cmd) {
    166                 free(cmd);
    167             }
    168             if (resp) {
    169                 free(resp);
    170             }
    171             return NO_ERROR;
    172         } break;
    173 
    174         case DISCONNECT: {
    175             LOGV("DISCONNECT");
    176             CHECK_INTERFACE(IEffect, data, reply);
    177             disconnect();
    178             return NO_ERROR;
    179         } break;
    180 
    181         case GET_CBLK: {
    182              CHECK_INTERFACE(IEffect, data, reply);
    183              reply->writeStrongBinder(getCblk()->asBinder());
    184              return NO_ERROR;
    185          } break;
    186 
    187         default:
    188             return BBinder::onTransact(code, data, reply, flags);
    189     }
    190 }
    191 
    192 // ----------------------------------------------------------------------------
    193 
    194 }; // namespace android
    195 
    196