blob: a268e494a3e4f0f814f14f408564f8739a05dc35 [file] [log] [blame]
Phil Burkc0c70e32017-02-09 13:18:38 -08001/*
2 * Copyright (C) 2017 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
18#define LOG_TAG "AAudio"
19//#define LOG_NDEBUG 0
20#include <utils/Log.h>
21
Phil Burk11e8d332017-05-24 09:59:02 -070022#include <binder/IInterface.h>
Phil Burkc0c70e32017-02-09 13:18:38 -080023#include <binder/IServiceManager.h>
Phil Burk11e8d332017-05-24 09:59:02 -070024#include <binder/ProcessState.h>
Phil Burkc0c70e32017-02-09 13:18:38 -080025#include <utils/Mutex.h>
26#include <utils/RefBase.h>
Phil Burk9b3f8ef2017-05-16 11:37:43 -070027#include <utils/Singleton.h>
Phil Burk11e8d332017-05-24 09:59:02 -070028#include <media/AudioSystem.h>
Phil Burkc0c70e32017-02-09 13:18:38 -080029
30#include <aaudio/AAudio.h>
31
32#include "AudioEndpointParcelable.h"
Phil Burk11e8d332017-05-24 09:59:02 -070033#include "binding/AAudioBinderClient.h"
34//#include "binding/AAudioStreamRequest.h"
35//#include "binding/AAudioStreamConfiguration.h"
36//#include "binding/IAAudioService.h"
37//#include "binding/AAudioServiceMessage.h"
Phil Burkc0c70e32017-02-09 13:18:38 -080038
Phil Burk11e8d332017-05-24 09:59:02 -070039//#include "AAudioServiceInterface.h"
Phil Burkc0c70e32017-02-09 13:18:38 -080040
41using android::String16;
42using android::IServiceManager;
43using android::defaultServiceManager;
44using android::interface_cast;
Phil Burk11e8d332017-05-24 09:59:02 -070045using android::IInterface;
Phil Burkc0c70e32017-02-09 13:18:38 -080046using android::IAAudioService;
47using android::Mutex;
48using android::sp;
Phil Burk11e8d332017-05-24 09:59:02 -070049using android::wp;
Phil Burkc0c70e32017-02-09 13:18:38 -080050
51using namespace aaudio;
52
Phil Burk9b3f8ef2017-05-16 11:37:43 -070053ANDROID_SINGLETON_STATIC_INSTANCE(AAudioBinderClient);
54
Phil Burk11e8d332017-05-24 09:59:02 -070055AAudioBinderClient::AAudioBinderClient()
56 : AAudioServiceInterface()
57 , Singleton<AAudioBinderClient>() {
58
59 mAAudioClient = new AAudioClient(this);
Phil Burkc7abac42017-07-17 11:13:37 -070060 ALOGV("AAudioBinderClient() created mAAudioClient = %p", mAAudioClient.get());
Phil Burk11e8d332017-05-24 09:59:02 -070061}
62
63AAudioBinderClient::~AAudioBinderClient() {
64 Mutex::Autolock _l(mServiceLock);
65 if (mAAudioService != 0) {
66 IInterface::asBinder(mAAudioService)->unlinkToDeath(mAAudioClient);
67 }
68}
69
Phil Burkc0c70e32017-02-09 13:18:38 -080070// TODO Share code with other service clients.
71// Helper function to get access to the "AAudioService" service.
72// This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp
Phil Burk11e8d332017-05-24 09:59:02 -070073const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
74 sp<IAAudioService> aaudioService;
75 bool needToRegister = false;
76 {
77 Mutex::Autolock _l(mServiceLock);
78 if (mAAudioService == 0) {
79 sp<IBinder> binder;
80 sp<IServiceManager> sm = defaultServiceManager();
81 // Try several times to get the service.
82 int retries = 4;
83 do {
84 binder = sm->getService(String16(AAUDIO_SERVICE_NAME)); // This will wait a while.
85 if (binder != 0) {
86 break;
87 }
88 } while (retries-- > 0);
89
Phil Burkc0c70e32017-02-09 13:18:38 -080090 if (binder != 0) {
Phil Burk11e8d332017-05-24 09:59:02 -070091 // Ask for notification if the service dies.
92 status_t status = binder->linkToDeath(mAAudioClient);
Phil Burkc7abac42017-07-17 11:13:37 -070093 // TODO review what we should do if this fails
94 if (status != NO_ERROR) {
95 ALOGE("getAAudioService: linkToDeath(mAAudioClient = %p) returned %d",
96 mAAudioClient.get(), status);
97 }
Phil Burk11e8d332017-05-24 09:59:02 -070098 mAAudioService = interface_cast<IAAudioService>(binder);
99 needToRegister = true;
100 // Make sure callbacks can be received by mAAudioClient
101 android::ProcessState::self()->startThreadPool();
102 } else {
103 ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME);
Phil Burkc0c70e32017-02-09 13:18:38 -0800104 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800105 }
Phil Burk11e8d332017-05-24 09:59:02 -0700106 aaudioService = mAAudioService;
Phil Burkc0c70e32017-02-09 13:18:38 -0800107 }
Phil Burk11e8d332017-05-24 09:59:02 -0700108 // Do this outside the mutex lock.
109 if (needToRegister && aaudioService != 0) { // new client?
110 aaudioService->registerClient(mAAudioClient);
111 }
112 return aaudioService;
Phil Burkc0c70e32017-02-09 13:18:38 -0800113}
114
Phil Burk11e8d332017-05-24 09:59:02 -0700115void AAudioBinderClient::dropAAudioService() {
116 Mutex::Autolock _l(mServiceLock);
117 mAAudioService.clear(); // force a reconnect
Phil Burk71f35bb2017-04-13 16:05:07 -0700118}
Phil Burkc0c70e32017-02-09 13:18:38 -0800119
Phil Burkc0c70e32017-02-09 13:18:38 -0800120
121/**
122* @param request info needed to create the stream
123* @param configuration contains information about the created stream
124* @return handle to the stream or a negative error
125*/
126aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
127 AAudioStreamConfiguration &configurationOutput) {
Phil Burk71f35bb2017-04-13 16:05:07 -0700128 aaudio_handle_t stream;
129 for (int i = 0; i < 2; i++) {
130 const sp<IAAudioService> &service = getAAudioService();
131 if (service == 0) {
132 return AAUDIO_ERROR_NO_SERVICE;
133 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800134
Phil Burk71f35bb2017-04-13 16:05:07 -0700135 stream = service->openStream(request, configurationOutput);
136
137 if (stream == AAUDIO_ERROR_NO_SERVICE) {
138 ALOGE("AAudioBinderClient: lost connection to AAudioService.");
139 dropAAudioService(); // force a reconnect
140 } else {
141 break;
142 }
143 }
144 return stream;
Phil Burkc0c70e32017-02-09 13:18:38 -0800145}
146
147aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800148 const sp<IAAudioService> &service = getAAudioService();
149 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
150 return service->closeStream(streamHandle);
151}
152
153/* Get an immutable description of the in-memory queues
154* used to communicate with the underlying HAL or Service.
155*/
156aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
157 AudioEndpointParcelable &parcelable) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800158 const sp<IAAudioService> &service = getAAudioService();
159 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
160 return service->getStreamDescription(streamHandle, parcelable);
161}
162
Phil Burkc0c70e32017-02-09 13:18:38 -0800163aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
164 const sp<IAAudioService> &service = getAAudioService();
165 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
166 return service->startStream(streamHandle);
167}
168
Phil Burkc0c70e32017-02-09 13:18:38 -0800169aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
170 const sp<IAAudioService> &service = getAAudioService();
171 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
Phil Burk71f35bb2017-04-13 16:05:07 -0700172 return service->pauseStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800173}
174
Phil Burk71f35bb2017-04-13 16:05:07 -0700175aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
176 const sp<IAAudioService> &service = getAAudioService();
177 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
178 return service->stopStream(streamHandle);
179}
180
Phil Burkc0c70e32017-02-09 13:18:38 -0800181aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
182 const sp<IAAudioService> &service = getAAudioService();
183 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
Phil Burk71f35bb2017-04-13 16:05:07 -0700184 return service->flushStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800185}
186
187/**
188* Manage the specified thread as a low latency audio thread.
189*/
190aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800191 pid_t clientThreadId,
192 int64_t periodNanoseconds) {
193 const sp<IAAudioService> &service = getAAudioService();
194 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
195 return service->registerAudioThread(streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800196 clientThreadId,
197 periodNanoseconds);
198}
199
200aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800201 pid_t clientThreadId) {
202 const sp<IAAudioService> &service = getAAudioService();
203 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
204 return service->unregisterAudioThread(streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800205 clientThreadId);
206}