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             if (cblk != 0 && cblk->pointer() == NULL) {
    121                 cblk.clear();
    122             }
    123         }
    124         return cblk;
    125     }
    126  };
    127 
    128 IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect");
    129 
    130 // ----------------------------------------------------------------------
    131 
    132 status_t BnEffect::onTransact(
    133     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    134 {
    135     switch (code) {
    136         case ENABLE: {
    137             ALOGV("ENABLE");
    138             CHECK_INTERFACE(IEffect, data, reply);
    139             reply->writeInt32(enable());
    140             return NO_ERROR;
    141         } break;
    142 
    143         case DISABLE: {
    144             ALOGV("DISABLE");
    145             CHECK_INTERFACE(IEffect, data, reply);
    146             reply->writeInt32(disable());
    147             return NO_ERROR;
    148         } break;
    149 
    150         case COMMAND: {
    151             ALOGV("COMMAND");
    152             CHECK_INTERFACE(IEffect, data, reply);
    153             uint32_t cmdCode = data.readInt32();
    154             uint32_t cmdSize = data.readInt32();
    155             char *cmd = NULL;
    156             if (cmdSize) {
    157                 cmd = (char *)malloc(cmdSize);
    158                 data.read(cmd, cmdSize);
    159             }
    160             uint32_t replySize = data.readInt32();
    161             uint32_t replySz = replySize;
    162             char *resp = NULL;
    163             if (replySize) {
    164                 resp = (char *)malloc(replySize);
    165             }
    166             status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
    167             reply->writeInt32(status);
    168             if (replySz < replySize) {
    169                 replySize = replySz;
    170             }
    171             reply->writeInt32(replySize);
    172             if (replySize) {
    173                 reply->write(resp, replySize);
    174             }
    175             if (cmd) {
    176                 free(cmd);
    177             }
    178             if (resp) {
    179                 free(resp);
    180             }
    181             return NO_ERROR;
    182         } break;
    183 
    184         case DISCONNECT: {
    185             ALOGV("DISCONNECT");
    186             CHECK_INTERFACE(IEffect, data, reply);
    187             disconnect();
    188             return NO_ERROR;
    189         } break;
    190 
    191         case GET_CBLK: {
    192             CHECK_INTERFACE(IEffect, data, reply);
    193             reply->writeStrongBinder(getCblk()->asBinder());
    194             return NO_ERROR;
    195         } break;
    196 
    197         default:
    198             return BBinder::onTransact(code, data, reply, flags);
    199     }
    200 }
    201 
    202 // ----------------------------------------------------------------------------
    203 
    204 }; // namespace android
    205