1b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent/*
2b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
3b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Copyright 2014, The Android Open Source Project
4b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
5b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License");
6b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** you may not use this file except in compliance with the License.
7b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** You may obtain a copy of the License at
8b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
9b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**     http://www.apache.org/licenses/LICENSE-2.0
10b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
11b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Unless required by applicable law or agreed to in writing, software
12b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS,
13b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** See the License for the specific language governing permissions and
15b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** limitations under the License.
16b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent*/
17b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
18b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "ISoundTrigger"
19b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Log.h>
20b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Errors.h>
21b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IMemory.h>
22b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTrigger.h>
23b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerHwService.h>
24b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerClient.h>
25b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <system/sound_trigger.h>
26b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
27b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentnamespace android {
28b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
29b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentenum {
30b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    DETACH = IBinder::FIRST_CALL_TRANSACTION,
31b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    LOAD_SOUND_MODEL,
32b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    UNLOAD_SOUND_MODEL,
33b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    START_RECOGNITION,
34b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    STOP_RECOGNITION,
35b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent};
36b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
37b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentclass BpSoundTrigger: public BpInterface<ISoundTrigger>
38b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
39b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentpublic:
40b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    BpSoundTrigger(const sp<IBinder>& impl)
41b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        : BpInterface<ISoundTrigger>(impl)
42b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
43b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
44b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    void detach()
46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        ALOGV("detach");
48b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
49b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
50b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        remote()->transact(DETACH, data, &reply);
51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    status_t loadSoundModel(const sp<IMemory>&  modelMemory,
54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                    sound_model_handle_t *handle)
55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (modelMemory == 0 || handle == NULL) {
57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BAD_VALUE;
58b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
59b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
60b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
61b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeStrongBinder(modelMemory->asBinder());
62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply);
63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status != NO_ERROR ||
64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                (status = (status_t)reply.readInt32()) != NO_ERROR) {
65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return status;
66b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        reply.read(handle, sizeof(sound_model_handle_t));
68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t unloadSoundModel(sound_model_handle_t handle)
72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_model_handle_t));
76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply);
77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status != NO_ERROR) {
78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t startRecognition(sound_model_handle_t handle,
84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                      const sp<IMemory>& dataMemory)
85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
87b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
88b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_model_handle_t));
89b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (dataMemory == 0) {
90b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.writeInt32(0);
91b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } else {
92b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.writeInt32(dataMemory->size());
93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
94b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeStrongBinder(dataMemory->asBinder());
95b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(START_RECOGNITION, data, &reply);
96b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status != NO_ERROR) {
97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
99b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
100b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
101b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t stopRecognition(sound_model_handle_t handle)
103b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
104b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
105b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_model_handle_t));
107b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(STOP_RECOGNITION, data, &reply);
108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status != NO_ERROR) {
109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
110b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent};
115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
116b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentIMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger");
117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------
119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t BnSoundTrigger::onTransact(
121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    switch(code) {
124b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case DETACH: {
125b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGV("DETACH");
126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            detach();
128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } break;
130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case LOAD_SOUND_MODEL: {
131b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
132b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<IMemory> modelMemory = interface_cast<IMemory>(
133b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                data.readStrongBinder());
134b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
135b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = loadSoundModel(modelMemory, &handle);
136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (status == NO_ERROR) {
138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->write(&handle, sizeof(sound_model_handle_t));
139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case UNLOAD_SOUND_MODEL: {
143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_model_handle_t));
146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = unloadSoundModel(handle);
147b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case START_RECOGNITION: {
151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_model_handle_t));
154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<IMemory> dataMemory;
155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (data.readInt32() != 0) {
156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                dataMemory = interface_cast<IMemory>(data.readStrongBinder());
157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = startRecognition(handle, dataMemory);
159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case STOP_RECOGNITION: {
163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_model_handle_t));
166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = stopRecognition(handle);
167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        default:
171b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BBinder::onTransact(code, data, reply, flags);
172b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
173b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
174b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
175b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------------
176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android
178