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 "ISoundTrigger"
     19 #include <utils/Log.h>
     20 #include <utils/Errors.h>
     21 #include <binder/IMemory.h>
     22 #include <soundtrigger/ISoundTrigger.h>
     23 #include <soundtrigger/ISoundTriggerHwService.h>
     24 #include <soundtrigger/ISoundTriggerClient.h>
     25 #include <system/sound_trigger.h>
     26 
     27 namespace android {
     28 
     29 enum {
     30     DETACH = IBinder::FIRST_CALL_TRANSACTION,
     31     LOAD_SOUND_MODEL,
     32     UNLOAD_SOUND_MODEL,
     33     START_RECOGNITION,
     34     STOP_RECOGNITION,
     35     GET_MODEL_STATE,
     36 };
     37 
     38 class BpSoundTrigger: public BpInterface<ISoundTrigger>
     39 {
     40 public:
     41     explicit BpSoundTrigger(const sp<IBinder>& impl)
     42         : BpInterface<ISoundTrigger>(impl)
     43     {
     44     }
     45 
     46     void detach()
     47     {
     48         ALOGV("detach");
     49         Parcel data, reply;
     50         data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
     51         remote()->transact(DETACH, data, &reply);
     52     }
     53 
     54     status_t loadSoundModel(const sp<IMemory>&  modelMemory,
     55                                     sound_model_handle_t *handle)
     56     {
     57         if (modelMemory == 0 || handle == NULL) {
     58             return BAD_VALUE;
     59         }
     60         Parcel data, reply;
     61         data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
     62         data.writeStrongBinder(IInterface::asBinder(modelMemory));
     63         status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply);
     64         if (status != NO_ERROR) {
     65             return status;
     66         }
     67         status = (status_t)reply.readInt32();
     68         if (status == NO_ERROR) {
     69             reply.read(handle, sizeof(sound_model_handle_t));
     70         }
     71         return status;
     72     }
     73 
     74     virtual status_t unloadSoundModel(sound_model_handle_t handle)
     75     {
     76         Parcel data, reply;
     77         data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
     78         data.write(&handle, sizeof(sound_model_handle_t));
     79         status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply);
     80         if (status == NO_ERROR) {
     81             status = (status_t)reply.readInt32();
     82         }
     83         return status;
     84     }
     85 
     86     virtual status_t startRecognition(sound_model_handle_t handle,
     87                                       const sp<IMemory>& dataMemory)
     88     {
     89         Parcel data, reply;
     90         data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
     91         data.write(&handle, sizeof(sound_model_handle_t));
     92         if (dataMemory == 0) {
     93             data.writeInt32(0);
     94         } else {
     95             data.writeInt32(dataMemory->size());
     96         }
     97         data.writeStrongBinder(IInterface::asBinder(dataMemory));
     98         status_t status = remote()->transact(START_RECOGNITION, data, &reply);
     99         if (status == NO_ERROR) {
    100             status = (status_t)reply.readInt32();
    101         }
    102         return status;
    103     }
    104 
    105     virtual status_t stopRecognition(sound_model_handle_t handle)
    106     {
    107         Parcel data, reply;
    108         data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
    109         data.write(&handle, sizeof(sound_model_handle_t));
    110         status_t status = remote()->transact(STOP_RECOGNITION, data, &reply);
    111         if (status == NO_ERROR) {
    112             status = (status_t)reply.readInt32();
    113         }
    114         return status;
    115     }
    116 
    117     virtual status_t getModelState(sound_model_handle_t handle)
    118     {
    119         Parcel data, reply;
    120         data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
    121         data.write(&handle, sizeof(sound_model_handle_t));
    122         status_t status = remote()->transact(GET_MODEL_STATE, data, &reply);
    123         if (status == NO_ERROR) {
    124             status = (status_t)reply.readInt32();
    125         }
    126         return status;
    127     }
    128 
    129 };
    130 
    131 IMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger");
    132 
    133 // ----------------------------------------------------------------------
    134 
    135 status_t BnSoundTrigger::onTransact(
    136     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    137 {
    138     switch(code) {
    139         case DETACH: {
    140             ALOGV("DETACH");
    141             CHECK_INTERFACE(ISoundTrigger, data, reply);
    142             detach();
    143             return NO_ERROR;
    144         } break;
    145         case LOAD_SOUND_MODEL: {
    146             CHECK_INTERFACE(ISoundTrigger, data, reply);
    147             sp<IMemory> modelMemory = interface_cast<IMemory>(
    148                 data.readStrongBinder());
    149             sound_model_handle_t handle;
    150             status_t status = loadSoundModel(modelMemory, &handle);
    151             reply->writeInt32(status);
    152             if (status == NO_ERROR) {
    153                 reply->write(&handle, sizeof(sound_model_handle_t));
    154             }
    155             return NO_ERROR;
    156         }
    157         case UNLOAD_SOUND_MODEL: {
    158             CHECK_INTERFACE(ISoundTrigger, data, reply);
    159             sound_model_handle_t handle;
    160             data.read(&handle, sizeof(sound_model_handle_t));
    161             status_t status = unloadSoundModel(handle);
    162             reply->writeInt32(status);
    163             return NO_ERROR;
    164         }
    165         case START_RECOGNITION: {
    166             CHECK_INTERFACE(ISoundTrigger, data, reply);
    167             sound_model_handle_t handle;
    168             data.read(&handle, sizeof(sound_model_handle_t));
    169             sp<IMemory> dataMemory;
    170             if (data.readInt32() != 0) {
    171                 dataMemory = interface_cast<IMemory>(data.readStrongBinder());
    172             }
    173             status_t status = startRecognition(handle, dataMemory);
    174             reply->writeInt32(status);
    175             return NO_ERROR;
    176         }
    177         case STOP_RECOGNITION: {
    178             CHECK_INTERFACE(ISoundTrigger, data, reply);
    179             sound_model_handle_t handle;
    180             data.read(&handle, sizeof(sound_model_handle_t));
    181             status_t status = stopRecognition(handle);
    182             reply->writeInt32(status);
    183             return NO_ERROR;
    184         }
    185         case GET_MODEL_STATE: {
    186             CHECK_INTERFACE(ISoundTrigger, data, reply);
    187             sound_model_handle_t handle;
    188             status_t status = UNKNOWN_ERROR;
    189             status_t ret = data.read(&handle, sizeof(sound_model_handle_t));
    190             if (ret == NO_ERROR) {
    191                 status = getModelState(handle);
    192             }
    193             reply->writeInt32(status);
    194             return ret;
    195         }
    196         default:
    197             return BBinder::onTransact(code, data, reply, flags);
    198     }
    199 }
    200 
    201 // ----------------------------------------------------------------------------
    202 
    203 }; // namespace android
    204