/*
 * 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 "../includes/common.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "binding/IAAudioService.h"

using namespace android;
using namespace aaudio;

typedef struct _thread_args {
    aaudio_handle_t aaudioHandle;
    sp<IAAudioService> aas;
} thread_args;

static void* closeStreamThread(void *arg) {
    thread_args *threadArgs = (thread_args*) arg;
    if (threadArgs) {
        if (threadArgs->aas) {
            threadArgs->aas->closeStream(threadArgs->aaudioHandle);
        }
    }
    return nullptr;
}

static void* startStreamThread(void *arg) {
    thread_args *threadArgs = (thread_args*) arg;
    if (threadArgs) {
        if (threadArgs->aas) {
            threadArgs->aas->startStream(threadArgs->aaudioHandle);
        }
    }
    return nullptr;
}

int main() {
    thread_args targs;

    sp < IServiceManager > sm = defaultServiceManager();
    sp < IBinder > binder = sm->getService(String16("media.aaudio"));
    targs.aas = interface_cast < IAAudioService > (binder);
    if (!(targs.aas)) {
        return EXIT_FAILURE;
    }
    aaudio::AAudioStreamRequest request;
    request.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED);
    request.getConfiguration().setDeviceId(0);
    request.getConfiguration().setSampleRate(AAUDIO_UNSPECIFIED);

    time_t currentTime = start_timer();
    while (timer_active(currentTime)) {
        pthread_t pt[2];

        aaudio::AAudioStreamConfiguration configurationOutput;
        targs.aaudioHandle = targs.aas->openStream(request,
                                                   configurationOutput);
        pthread_create(&pt[0], nullptr, closeStreamThread, &targs); /* close stream */
        pthread_create(&pt[1], nullptr, startStreamThread, &targs); /* start stream */

        sleep(5);
    }
    return EXIT_SUCCESS;
}
