blob: 001569ce0ac9321a306ddae56b98c1498d8a8bc2 [file] [log] [blame]
Phil Burk2355edb2016-12-26 13:54:02 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OboeService"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20
21#include <time.h>
22#include <pthread.h>
23
24#include <oboe/OboeDefinitions.h>
25
26#include "HandleTracker.h"
27#include "IOboeAudioService.h"
28#include "OboeService.h"
29#include "OboeAudioService.h"
30#include "OboeServiceStreamFakeHal.h"
31
32using namespace android;
33using namespace oboe;
34
35typedef enum
36{
Phil Burkdec33ab2017-01-17 14:48:16 -080037 OBOE_HANDLE_TYPE_DUMMY1, // TODO remove DUMMYs
38 OBOE_HANDLE_TYPE_DUMMY2, // make server handles different than client
Phil Burk2355edb2016-12-26 13:54:02 -080039 OBOE_HANDLE_TYPE_STREAM,
40 OBOE_HANDLE_TYPE_COUNT
41} oboe_service_handle_type_t;
42static_assert(OBOE_HANDLE_TYPE_COUNT <= HANDLE_TRACKER_MAX_TYPES, "Too many handle types.");
43
Phil Burkdec33ab2017-01-17 14:48:16 -080044android::OboeAudioService::OboeAudioService()
45 : BnOboeAudioService() {
46}
47
48OboeAudioService::~OboeAudioService() {
49}
50
Phil Burk2355edb2016-12-26 13:54:02 -080051oboe_handle_t OboeAudioService::openStream(oboe::OboeStreamRequest &request,
52 oboe::OboeStreamConfiguration &configuration) {
53 OboeServiceStreamBase *serviceStream = new OboeServiceStreamFakeHal();
54 ALOGD("OboeAudioService::openStream(): created serviceStream = %p", serviceStream);
55 oboe_result_t result = serviceStream->open(request, configuration);
56 if (result < 0) {
57 ALOGE("OboeAudioService::openStream(): open returned %d", result);
58 return result;
59 } else {
60 OboeStream handle = mHandleTracker.put(OBOE_HANDLE_TYPE_STREAM, serviceStream);
61 ALOGD("OboeAudioService::openStream(): handle = 0x%08X", handle);
62 if (handle < 0) {
63 delete serviceStream;
64 }
65 return handle;
66 }
67}
68
69oboe_result_t OboeAudioService::closeStream(oboe_handle_t streamHandle) {
70 OboeServiceStreamBase *serviceStream = (OboeServiceStreamBase *)
71 mHandleTracker.remove(OBOE_HANDLE_TYPE_STREAM,
72 streamHandle);
Phil Burkdec33ab2017-01-17 14:48:16 -080073 ALOGD("OboeAudioService.closeStream(0x%08X)", streamHandle);
Phil Burk2355edb2016-12-26 13:54:02 -080074 if (serviceStream != nullptr) {
75 ALOGD("OboeAudioService::closeStream(): deleting serviceStream = %p", serviceStream);
76 delete serviceStream;
77 return OBOE_OK;
78 }
79 return OBOE_ERROR_INVALID_HANDLE;
80}
81
82OboeServiceStreamBase *OboeAudioService::convertHandleToServiceStream(
83 oboe_handle_t streamHandle) const {
84 return (OboeServiceStreamBase *) mHandleTracker.get(OBOE_HANDLE_TYPE_STREAM,
85 (oboe_handle_t)streamHandle);
86}
87
88oboe_result_t OboeAudioService::getStreamDescription(
89 oboe_handle_t streamHandle,
90 oboe::AudioEndpointParcelable &parcelable) {
Phil Burk2355edb2016-12-26 13:54:02 -080091 OboeServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
Phil Burkdec33ab2017-01-17 14:48:16 -080092 ALOGD("OboeAudioService::getStreamDescription(), serviceStream = %p", serviceStream);
Phil Burk2355edb2016-12-26 13:54:02 -080093 if (serviceStream == nullptr) {
94 return OBOE_ERROR_INVALID_HANDLE;
95 }
96 return serviceStream->getDescription(parcelable);
97}
98
99oboe_result_t OboeAudioService::startStream(oboe_handle_t streamHandle) {
100 OboeServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
Phil Burkdec33ab2017-01-17 14:48:16 -0800101 ALOGD("OboeAudioService::startStream(), serviceStream = %p", serviceStream);
Phil Burk2355edb2016-12-26 13:54:02 -0800102 if (serviceStream == nullptr) {
103 return OBOE_ERROR_INVALID_HANDLE;
104 }
Phil Burkdec33ab2017-01-17 14:48:16 -0800105 oboe_result_t result = serviceStream->start();
106 return result;
Phil Burk2355edb2016-12-26 13:54:02 -0800107}
108
109oboe_result_t OboeAudioService::pauseStream(oboe_handle_t streamHandle) {
110 OboeServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
Phil Burkdec33ab2017-01-17 14:48:16 -0800111 ALOGD("OboeAudioService::pauseStream(), serviceStream = %p", serviceStream);
Phil Burk2355edb2016-12-26 13:54:02 -0800112 if (serviceStream == nullptr) {
113 return OBOE_ERROR_INVALID_HANDLE;
114 }
Phil Burkdec33ab2017-01-17 14:48:16 -0800115 oboe_result_t result = serviceStream->pause();
116 return result;
Phil Burk2355edb2016-12-26 13:54:02 -0800117}
118
119oboe_result_t OboeAudioService::flushStream(oboe_handle_t streamHandle) {
120 OboeServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
Phil Burkdec33ab2017-01-17 14:48:16 -0800121 ALOGD("OboeAudioService::flushStream(), serviceStream = %p", serviceStream);
Phil Burk2355edb2016-12-26 13:54:02 -0800122 if (serviceStream == nullptr) {
123 return OBOE_ERROR_INVALID_HANDLE;
124 }
125 return serviceStream->flush();
126}
127
Phil Burk2355edb2016-12-26 13:54:02 -0800128oboe_result_t OboeAudioService::registerAudioThread(oboe_handle_t streamHandle,
129 pid_t clientThreadId,
130 oboe_nanoseconds_t periodNanoseconds) {
131 OboeServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
Phil Burkdec33ab2017-01-17 14:48:16 -0800132 ALOGD("OboeAudioService::registerAudioThread(), serviceStream = %p", serviceStream);
Phil Burk2355edb2016-12-26 13:54:02 -0800133 if (serviceStream == nullptr) {
134 ALOGE("OboeAudioService::registerAudioThread(), serviceStream == nullptr");
135 return OBOE_ERROR_INVALID_HANDLE;
136 }
137 if (serviceStream->getRegisteredThread() != OboeServiceStreamBase::ILLEGAL_THREAD_ID) {
138 ALOGE("OboeAudioService::registerAudioThread(), thread already registered");
139 return OBOE_ERROR_INVALID_ORDER;
140 }
141 serviceStream->setRegisteredThread(clientThreadId);
142 // Boost client thread to SCHED_FIFO
143 struct sched_param sp;
144 memset(&sp, 0, sizeof(sp));
145 sp.sched_priority = 2; // TODO use 'requestPriority' function from frameworks/av/media/utils
146 int err = sched_setscheduler(clientThreadId, SCHED_FIFO, &sp);
147 if (err != 0){
148 ALOGE("OboeAudioService::sched_setscheduler() failed, errno = %d, priority = %d",
149 errno, sp.sched_priority);
150 return OBOE_ERROR_INTERNAL;
151 } else {
152 return OBOE_OK;
153 }
154}
155
156oboe_result_t OboeAudioService::unregisterAudioThread(oboe_handle_t streamHandle,
157 pid_t clientThreadId) {
158 OboeServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
159 ALOGI("OboeAudioService::unregisterAudioThread(), serviceStream = %p", serviceStream);
160 if (serviceStream == nullptr) {
161 ALOGE("OboeAudioService::unregisterAudioThread(), serviceStream == nullptr");
162 return OBOE_ERROR_INVALID_HANDLE;
163 }
164 if (serviceStream->getRegisteredThread() != clientThreadId) {
165 ALOGE("OboeAudioService::unregisterAudioThread(), wrong thread");
166 return OBOE_ERROR_ILLEGAL_ARGUMENT;
167 }
168 serviceStream->setRegisteredThread(0);
169 return OBOE_OK;
170}