/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
#include <utils/Vector.h>
//#include <binder/AppOpsManager.h>
#include <binder/MemoryDealer.h>
#include <binder/BinderService.h>
#include <binder/IAppOpsCallback.h>
#include <soundtrigger/ISoundTriggerHwService.h>
#include <soundtrigger/ISoundTrigger.h>
#include <soundtrigger/ISoundTriggerClient.h>
#include <system/sound_trigger.h>
#include "SoundTriggerHalInterface.h"
namespace android {
class MemoryHeapBase;
class SoundTriggerHwService :
public BinderService<SoundTriggerHwService>,
public BnSoundTriggerHwService
{
friend class BinderService<SoundTriggerHwService>;
public:
class Module;
class ModuleClient;
static char const* getServiceName() { return "media.sound_trigger_hw"; }
SoundTriggerHwService();
virtual ~SoundTriggerHwService();
// ISoundTriggerHwService
virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
uint32_t *numModules);
virtual status_t attach(const sound_trigger_module_handle_t handle,
const sp<ISoundTriggerClient>& client,
sp<ISoundTrigger>& module);
virtual status_t setCaptureState(bool active);
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags);
virtual status_t dump(int fd, const Vector<String16>& args);
class Model : public RefBase {
public:
enum {
STATE_IDLE,
STATE_ACTIVE
};
Model(sound_model_handle_t handle, audio_session_t session, audio_io_handle_t ioHandle,
audio_devices_t device, sound_trigger_sound_model_type_t type,
sp<ModuleClient>& moduleClient);
~Model() {}
sound_model_handle_t mHandle;
int mState;
audio_session_t mCaptureSession;
audio_io_handle_t mCaptureIOHandle;
audio_devices_t mCaptureDevice;
sound_trigger_sound_model_type_t mType;
struct sound_trigger_recognition_config mConfig;
sp<ModuleClient> mModuleClient;
};
class CallbackEvent : public RefBase {
public:
typedef enum {
TYPE_RECOGNITION,
TYPE_SOUNDMODEL,
TYPE_SERVICE_STATE,
} event_type;
CallbackEvent(event_type type, sp<IMemory> memory);
virtual ~CallbackEvent();
void setModule(wp<Module> module) { mModule = module; }
void setModuleClient(wp<ModuleClient> moduleClient) { mModuleClient = moduleClient; }
event_type mType;
sp<IMemory> mMemory;
wp<Module> mModule;
wp<ModuleClient> mModuleClient;
};
class Module : public RefBase {
public:
Module(const sp<SoundTriggerHwService>& service,
const sp<SoundTriggerHalInterface>& halInterface,
sound_trigger_module_descriptor descriptor);
virtual ~Module();
virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
sp<ModuleClient> moduleClient,
sound_model_handle_t *handle);
virtual status_t unloadSoundModel(sound_model_handle_t handle);
virtual status_t startRecognition(sound_model_handle_t handle,
const sp<IMemory>& dataMemory);
virtual status_t stopRecognition(sound_model_handle_t handle);
sp<SoundTriggerHalInterface> halInterface() const { return mHalInterface; }
struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
wp<SoundTriggerHwService> service() const { return mService; }
bool isConcurrentCaptureAllowed() const { return mDescriptor.properties.concurrent_capture; }
sp<Model> getModel(sound_model_handle_t handle);
void setCaptureState_l(bool active);
sp<ModuleClient> addClient(const sp<ISoundTriggerClient>& client);
void detach(const sp<ModuleClient>& moduleClient);
void onCallbackEvent(const sp<CallbackEvent>& event);
private:
status_t unloadSoundModel_l(sound_model_handle_t handle);
Mutex mLock;
wp<SoundTriggerHwService> mService;
sp<SoundTriggerHalInterface> mHalInterface;
struct sound_trigger_module_descriptor mDescriptor;
Vector< sp<ModuleClient> > mModuleClients;
DefaultKeyedVector< sound_model_handle_t, sp<Model> > mModels;
sound_trigger_service_state_t mServiceState;
}; // class Module
class ModuleClient : public virtual RefBase,
public BnSoundTrigger,
public IBinder::DeathRecipient {
public:
ModuleClient(const sp<Module>& module,
const sp<ISoundTriggerClient>& client);
virtual ~ModuleClient();
virtual void detach();
virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
sound_model_handle_t *handle);
virtual status_t unloadSoundModel(sound_model_handle_t handle);
virtual status_t startRecognition(sound_model_handle_t handle,
const sp<IMemory>& dataMemory);
virtual status_t stopRecognition(sound_model_handle_t handle);
virtual status_t dump(int fd, const Vector<String16>& args);
virtual void onFirstRef();
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
void onCallbackEvent(const sp<CallbackEvent>& event);
void setCaptureState_l(bool active);
sp<ISoundTriggerClient> client() const { return mClient; }
private:
mutable Mutex mLock;
wp<Module> mModule;
sp<ISoundTriggerClient> mClient;
}; // class ModuleClient
class CallbackThread : public Thread {
public:
explicit CallbackThread(const wp<SoundTriggerHwService>& service);
virtual ~CallbackThread();
// Thread virtuals
virtual bool threadLoop();
// RefBase
virtual void onFirstRef();
void exit();
void sendCallbackEvent(const sp<CallbackEvent>& event);
private:
wp<SoundTriggerHwService> mService;
Condition mCallbackCond;
Mutex mCallbackLock;
Vector< sp<CallbackEvent> > mEventQueue;
};
static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie);
sp<IMemory> prepareRecognitionEvent_l(struct sound_trigger_recognition_event *event);
void sendRecognitionEvent(struct sound_trigger_recognition_event *event, Module *module);
static void soundModelCallback(struct sound_trigger_model_event *event, void *cookie);
sp<IMemory> prepareSoundModelEvent_l(struct sound_trigger_model_event *event);
void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module);
sp<IMemory> prepareServiceStateEvent_l(sound_trigger_service_state_t state);
void sendServiceStateEvent_l(sound_trigger_service_state_t state, Module *module);
void sendServiceStateEvent_l(sound_trigger_service_state_t state,
ModuleClient *moduleClient);
void sendCallbackEvent_l(const sp<CallbackEvent>& event);
void onCallbackEvent(const sp<CallbackEvent>& event);
private:
virtual void onFirstRef();
Mutex mServiceLock;
volatile int32_t mNextUniqueId;
DefaultKeyedVector< sound_trigger_module_handle_t, sp<Module> > mModules;
sp<CallbackThread> mCallbackThread;
sp<MemoryDealer> mMemoryDealer;
bool mCaptureState;
};
} // namespace android
#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H