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:
40090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit 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());
6106b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        data.writeStrongBinder(IInterface::asBinder(modelMemory));
62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply);
63014620f143eda403795642dab116fb82bda54200Eric Laurent        if (status != NO_ERROR) {
64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return status;
65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
66014620f143eda403795642dab116fb82bda54200Eric Laurent        status = (status_t)reply.readInt32();
67014620f143eda403795642dab116fb82bda54200Eric Laurent        if (status == NO_ERROR) {
68014620f143eda403795642dab116fb82bda54200Eric Laurent            reply.read(handle, sizeof(sound_model_handle_t));
69014620f143eda403795642dab116fb82bda54200Eric Laurent        }
70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t unloadSoundModel(sound_model_handle_t handle)
74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_model_handle_t));
78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply);
79014620f143eda403795642dab116fb82bda54200Eric Laurent        if (status == NO_ERROR) {
80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t startRecognition(sound_model_handle_t handle,
86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                      const sp<IMemory>& dataMemory)
87b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
88b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
89b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
90b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_model_handle_t));
91b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (dataMemory == 0) {
92b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.writeInt32(0);
93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } else {
94b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.writeInt32(dataMemory->size());
95b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
9606b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        data.writeStrongBinder(IInterface::asBinder(dataMemory));
97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(START_RECOGNITION, data, &reply);
98014620f143eda403795642dab116fb82bda54200Eric Laurent        if (status == NO_ERROR) {
99b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
100b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
101b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
103b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
104b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t stopRecognition(sound_model_handle_t handle)
105b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
107b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_model_handle_t));
109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(STOP_RECOGNITION, data, &reply);
110014620f143eda403795642dab116fb82bda54200Eric Laurent        if (status == NO_ERROR) {
111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
116b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent};
117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentIMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger");
119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------
121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t BnSoundTrigger::onTransact(
123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
124b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
125b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    switch(code) {
126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case DETACH: {
127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGV("DETACH");
128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            detach();
130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
131b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } break;
132b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case LOAD_SOUND_MODEL: {
133b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
134b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<IMemory> modelMemory = interface_cast<IMemory>(
135b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                data.readStrongBinder());
136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = loadSoundModel(modelMemory, &handle);
138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (status == NO_ERROR) {
140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->write(&handle, sizeof(sound_model_handle_t));
141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case UNLOAD_SOUND_MODEL: {
145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
147b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_model_handle_t));
148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = unloadSoundModel(handle);
149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case START_RECOGNITION: {
153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_model_handle_t));
156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<IMemory> dataMemory;
157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (data.readInt32() != 0) {
158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                dataMemory = interface_cast<IMemory>(data.readStrongBinder());
159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = startRecognition(handle, dataMemory);
161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case STOP_RECOGNITION: {
165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTrigger, data, reply);
166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_model_handle_t handle;
167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_model_handle_t));
168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = stopRecognition(handle);
169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
171b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
172b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        default:
173b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BBinder::onTransact(code, data, reply, flags);
174b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
175b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------------
178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android
180