blob: 725ba36c99585201eebf25f6bd01063fc443a778 [file] [log] [blame]
/**
* Copyright (C) 2020 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.
*/
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <media/IAudioPolicyService.h>
#include "../includes/common.h"
using namespace android;
#define MAX_NUMBER_OF_AUDIO_SESSIONS 1024
#define MAX_NUMBER_OF_THREADS 5
#define MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS 2
#define SLEEP_TIME_IN_SECONDS 5
struct pocAudioSessionCtxt {
sp<IAudioPolicyService> audioService;
audio_session_t audioSession[MAX_NUMBER_OF_AUDIO_SESSIONS];
volatile bool startThread;
};
static void* acquireSoundTriggerSessionThread(void *arg) {
int i = 0;
pocAudioSessionCtxt *ctxt = (pocAudioSessionCtxt *) arg;
if (!ctxt) {
return nullptr;
}
time_t currentTime = start_timer();
while (timer_active(currentTime)) {
if (ctxt->startThread == true && ctxt->audioService != nullptr) {
audio_io_handle_t ioHandle = 0;
audio_devices_t device = 0;
ctxt->audioService->acquireSoundTriggerSession(
&(ctxt->audioSession[++i]), &ioHandle, &device);
if (i >= MAX_NUMBER_OF_AUDIO_SESSIONS) {
i = 0;
}
}
}
return nullptr;
}
static void* releaseSoundTriggerSessionThread(void *arg) {
int i = 0;
pocAudioSessionCtxt *ctxt = (pocAudioSessionCtxt *) arg;
if (!ctxt) {
return nullptr;
}
time_t currentTime = start_timer();
while (timer_active(currentTime)) {
if (ctxt->startThread == true && ctxt->audioService != nullptr) {
ctxt->audioService->releaseSoundTriggerSession(
ctxt->audioSession[++i]);
if (i >= MAX_NUMBER_OF_AUDIO_SESSIONS) {
i = 0;
}
}
}
return nullptr;
}
class MyDeathRecipient : public IBinder::DeathRecipient {
public:
MyDeathRecipient() {
}
virtual void binderDied(const wp<IBinder>& who __unused) {
exit(EXIT_SUCCESS);
}
};
int main() {
pocAudioSessionCtxt ctxt;
pthread_t thread[MAX_NUMBER_OF_THREADS];
ctxt.startThread = false;
for (int i = 0; i < MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS; ++i) {
pthread_create(&thread[i], nullptr, acquireSoundTriggerSessionThread,
&ctxt);
}
for (int i = MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS;
i < MAX_NUMBER_OF_THREADS; ++i) {
pthread_create(&thread[i], nullptr, releaseSoundTriggerSessionThread,
&ctxt);
}
sp < IServiceManager > sm = defaultServiceManager();
sp < IBinder > binder = sm->getService(String16("media.audio_policy"));
if (binder == nullptr) {
return EXIT_FAILURE;
}
ctxt.audioService = interface_cast < IAudioPolicyService > (binder);
if (ctxt.audioService == nullptr) {
return EXIT_FAILURE;
}
sp<MyDeathRecipient> deathRecipient = new MyDeathRecipient();
binder->linkToDeath(deathRecipient);
ctxt.startThread = true;
for (int i = 0; i < MAX_NUMBER_OF_THREADS; ++i) {
pthread_join(thread[i], nullptr);
}
return EXIT_SUCCESS;
}