Home | History | Annotate | Download | only in soundtrigger
      1 /*
      2 **
      3 ** Copyright 2014, 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_TAG "BpSoundTriggerHwService"
     19 //#define LOG_NDEBUG 0
     20 
     21 #include <utils/Log.h>
     22 #include <utils/Errors.h>
     23 
     24 #include <stdint.h>
     25 #include <sys/types.h>
     26 #include <binder/IMemory.h>
     27 #include <binder/Parcel.h>
     28 #include <binder/IPCThreadState.h>
     29 #include <binder/IServiceManager.h>
     30 
     31 #include <soundtrigger/ISoundTriggerHwService.h>
     32 #include <soundtrigger/ISoundTrigger.h>
     33 #include <soundtrigger/ISoundTriggerClient.h>
     34 
     35 namespace android {
     36 
     37 enum {
     38     LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
     39     ATTACH,
     40     SET_CAPTURE_STATE,
     41 };
     42 
     43 #define MAX_ITEMS_PER_LIST 1024
     44 
     45 class BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
     46 {
     47 public:
     48     explicit BpSoundTriggerHwService(const sp<IBinder>& impl)
     49         : BpInterface<ISoundTriggerHwService>(impl)
     50     {
     51     }
     52 
     53     virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
     54                                  uint32_t *numModules)
     55     {
     56         if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
     57             return BAD_VALUE;
     58         }
     59         Parcel data, reply;
     60         data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
     61         unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
     62         data.writeInt32(numModulesReq);
     63         status_t status = remote()->transact(LIST_MODULES, data, &reply);
     64         if (status == NO_ERROR) {
     65             status = (status_t)reply.readInt32();
     66             *numModules = (unsigned int)reply.readInt32();
     67         }
     68         ALOGV("listModules() status %d got *numModules %d", status, *numModules);
     69         if (status == NO_ERROR) {
     70             if (numModulesReq > *numModules) {
     71                 numModulesReq = *numModules;
     72             }
     73             if (numModulesReq > 0) {
     74                 reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor));
     75             }
     76         }
     77         return status;
     78     }
     79 
     80     virtual status_t attach(const sound_trigger_module_handle_t handle,
     81                             const sp<ISoundTriggerClient>& client,
     82                             sp<ISoundTrigger>& module)
     83     {
     84         Parcel data, reply;
     85         data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
     86         data.write(&handle, sizeof(sound_trigger_module_handle_t));
     87         data.writeStrongBinder(IInterface::asBinder(client));
     88         status_t status = remote()->transact(ATTACH, data, &reply);
     89         if (status != NO_ERROR) {
     90             return status;
     91         }
     92         status = reply.readInt32();
     93         if (reply.readInt32() != 0) {
     94             module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
     95         }
     96         return status;
     97     }
     98 
     99     virtual status_t setCaptureState(bool active)
    100     {
    101         Parcel data, reply;
    102         data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
    103         data.writeInt32(active);
    104         status_t status = remote()->transact(SET_CAPTURE_STATE, data, &reply);
    105         if (status == NO_ERROR) {
    106             status = reply.readInt32();
    107         }
    108         return status;
    109     }
    110 
    111 };
    112 
    113 IMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
    114 
    115 // ----------------------------------------------------------------------
    116 
    117 status_t BnSoundTriggerHwService::onTransact(
    118     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    119 {
    120     switch(code) {
    121         case LIST_MODULES: {
    122             CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
    123             unsigned int numModulesReq = data.readInt32();
    124             if (numModulesReq > MAX_ITEMS_PER_LIST) {
    125                 numModulesReq = MAX_ITEMS_PER_LIST;
    126             }
    127             unsigned int numModules = numModulesReq;
    128             struct sound_trigger_module_descriptor *modules =
    129                     (struct sound_trigger_module_descriptor *)calloc(numModulesReq,
    130                                                    sizeof(struct sound_trigger_module_descriptor));
    131             if (modules == NULL) {
    132                 reply->writeInt32(NO_MEMORY);
    133                 reply->writeInt32(0);
    134                 return NO_ERROR;
    135             }
    136             status_t status = listModules(modules, &numModules);
    137             reply->writeInt32(status);
    138             reply->writeInt32(numModules);
    139             ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
    140 
    141             if (status == NO_ERROR) {
    142                 if (numModulesReq > numModules) {
    143                     numModulesReq = numModules;
    144                 }
    145                 reply->write(modules,
    146                              numModulesReq * sizeof(struct sound_trigger_module_descriptor));
    147             }
    148             free(modules);
    149             return NO_ERROR;
    150         }
    151 
    152         case ATTACH: {
    153             CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
    154             sound_trigger_module_handle_t handle;
    155             data.read(&handle, sizeof(sound_trigger_module_handle_t));
    156             sp<ISoundTriggerClient> client =
    157                     interface_cast<ISoundTriggerClient>(data.readStrongBinder());
    158             sp<ISoundTrigger> module;
    159             status_t status = attach(handle, client, module);
    160             reply->writeInt32(status);
    161             if (module != 0) {
    162                 reply->writeInt32(1);
    163                 reply->writeStrongBinder(IInterface::asBinder(module));
    164             } else {
    165                 reply->writeInt32(0);
    166             }
    167             return NO_ERROR;
    168         } break;
    169 
    170         case SET_CAPTURE_STATE: {
    171             CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
    172             reply->writeInt32(setCaptureState((bool)data.readInt32()));
    173             return NO_ERROR;
    174         } break;
    175 
    176         default:
    177             return BBinder::onTransact(code, data, reply, flags);
    178     }
    179 }
    180 
    181 // ----------------------------------------------------------------------------
    182 
    183 }; // namespace android
    184