blob: 671cd6fb04e7876201a473c202a3d9e9e0a37841 [file] [log] [blame]
/*
* Copyright 2018 Google Inc. All Rights Reserved.
*
* 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.
*/
#define LOG_TAG "oslo_sound_model"
#include <ctype.h>
#include <cutils/properties.h>
#include <hardware/sound_trigger.h>
#include <inttypes.h>
#include <log/log.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
#include "oslo_sound_model_control.h"
#include "sound_trigger_hw_iaxxx.h"
using android::sp;
using android::hardware::Return;
using android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
using android::hardware::soundtrigger::V2_0::SoundModelHandle;
using android::hardware::soundtrigger::V2_0::SoundModelType;
#define OSLO_SOUND_MODEL_HANDLE_PROP "vendor.oslo.sm.hndl"
static SoundModelHandle osloSoundModelHandle = 0;
static bool strToUuid(const char* uuid_str, sound_trigger_uuid_t* uuid) {
if (uuid_str == NULL) {
ALOGI("Invalid str_to_uuid input.");
return false;
}
int tmp[10];
if (sscanf(uuid_str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5,
tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
ALOGI("Invalid UUID, got: %s", uuid_str);
return false;
}
uuid->timeLow = (unsigned int)tmp[0];
uuid->timeMid = (unsigned short)tmp[1];
uuid->timeHiAndVersion = (unsigned short)tmp[2];
uuid->clockSeq = (unsigned short)tmp[3];
uuid->node[0] = (unsigned char)tmp[4];
uuid->node[1] = (unsigned char)tmp[5];
uuid->node[2] = (unsigned char)tmp[6];
uuid->node[3] = (unsigned char)tmp[7];
uuid->node[4] = (unsigned char)tmp[8];
uuid->node[5] = (unsigned char)tmp[9];
return true;
}
/**
* Loads oslo sound model via the SoundTrigger HAL HIDL service.
*
* @return true if oslo was enabled successfully, false otherwise.
*/
static bool osloLoadSoundModel(SoundModelHandle *hndl) {
ALOGD("Loading oslo sound model");
sound_trigger_uuid_t uuid;
strToUuid(SENSOR_MANAGER_MODEL, &uuid);
ISoundTriggerHw::SoundModel soundModel;
soundModel.type = SoundModelType::GENERIC;
soundModel.vendorUuid.timeLow = uuid.timeLow;
soundModel.vendorUuid.timeMid = uuid.timeMid;
soundModel.vendorUuid.versionAndTimeHigh = uuid.timeHiAndVersion;
soundModel.vendorUuid.variantAndClockSeqHigh = uuid.clockSeq;
memcpy(&soundModel.vendorUuid.node[0], &uuid.node[0], sizeof(uuid.node));
soundModel.data.resize(1); // Insert a dummy byte to bypass HAL NULL checks.
bool loaded = false;
sp<ISoundTriggerHw> stHal = ISoundTriggerHw::getService();
if (stHal == nullptr) {
ALOGE("Failed to get ST HAL service for oslo load");
} else {
int32_t loadResult;
Return<void> hidlResult = stHal->loadSoundModel(soundModel, NULL, 0,
[&](int32_t retval, SoundModelHandle handle) {
loadResult = retval;
*hndl = handle;
});
if (hidlResult.isOk()) {
if (loadResult == 0) {
ALOGI("Loaded oslo %d", *hndl);
loaded = true;
} else {
ALOGE("Failed to load oslo with %" PRId32, loadResult);
}
} else {
ALOGE("Failed to load oslo due to hidl error %s",
hidlResult.description().c_str());
}
}
return loaded;
}
/**
* Unloads oslo sound model via the SoundTrigger HAL HIDL service.
*/
static void osloUnloadSoundModel(SoundModelHandle hndl) {
ALOGD("Unloading oslo sound model %d", hndl);
sp<ISoundTriggerHw> stHal = ISoundTriggerHw::getService();
if (stHal == nullptr) {
ALOGE("Failed to get ST HAL service for oslo unload");
} else {
Return<int32_t> hidlResult = stHal->unloadSoundModel(hndl);
if (hidlResult.isOk()) {
if (hidlResult == 0) {
ALOGI("Unloaded oslo");
} else {
ALOGE("Failed to unload oslo with %" PRId32, int32_t(hidlResult));
}
} else {
ALOGE("Failed to unload oslo due to hidl error %s",
hidlResult.description().c_str());
}
}
}
void osloSoundModelEnable(bool enable) {
if (enable) {
if (!osloLoadSoundModel(&osloSoundModelHandle)) {
ALOGE("%s: Failed to load oslo sound model", __func__);
}
}
else {
if (osloSoundModelHandle == 0) {
char prop[PROPERTY_VALUE_MAX];
property_get(OSLO_SOUND_MODEL_HANDLE_PROP, prop, "0");
osloSoundModelHandle = atoi(prop);
}
if (osloSoundModelHandle != 0) {
osloUnloadSoundModel(osloSoundModelHandle);
osloSoundModelHandle = 0;
}
}
property_set(OSLO_SOUND_MODEL_HANDLE_PROP,
std::to_string(osloSoundModelHandle).c_str());
}