blob: 64643345f9fba4661c3b8b92d5594c537e238b1a [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);
60 ALOGD("AAudioBinderClient() created mAAudioClient = %p", mAAudioClient.get());
61}
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);
93 ALOGD("getAAudioService: linkToDeath(mAAudioClient = %p) returned %d",
94 mAAudioClient.get(), status);
95 mAAudioService = interface_cast<IAAudioService>(binder);
96 needToRegister = true;
97 // Make sure callbacks can be received by mAAudioClient
98 android::ProcessState::self()->startThreadPool();
99 } else {
100 ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME);
Phil Burkc0c70e32017-02-09 13:18:38 -0800101 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800102 }
Phil Burk11e8d332017-05-24 09:59:02 -0700103 aaudioService = mAAudioService;
Phil Burkc0c70e32017-02-09 13:18:38 -0800104 }
Phil Burk11e8d332017-05-24 09:59:02 -0700105 // Do this outside the mutex lock.
106 if (needToRegister && aaudioService != 0) { // new client?
107 aaudioService->registerClient(mAAudioClient);
108 }
109 return aaudioService;
Phil Burkc0c70e32017-02-09 13:18:38 -0800110}
111
Phil Burk11e8d332017-05-24 09:59:02 -0700112void AAudioBinderClient::dropAAudioService() {
113 Mutex::Autolock _l(mServiceLock);
114 mAAudioService.clear(); // force a reconnect
Phil Burk71f35bb2017-04-13 16:05:07 -0700115}
Phil Burkc0c70e32017-02-09 13:18:38 -0800116
Phil Burkc0c70e32017-02-09 13:18:38 -0800117
118/**
119* @param request info needed to create the stream
120* @param configuration contains information about the created stream
121* @return handle to the stream or a negative error
122*/
123aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
124 AAudioStreamConfiguration &configurationOutput) {
Phil Burk71f35bb2017-04-13 16:05:07 -0700125 aaudio_handle_t stream;
126 for (int i = 0; i < 2; i++) {
127 const sp<IAAudioService> &service = getAAudioService();
128 if (service == 0) {
129 return AAUDIO_ERROR_NO_SERVICE;
130 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800131
Phil Burk71f35bb2017-04-13 16:05:07 -0700132 stream = service->openStream(request, configurationOutput);
133
134 if (stream == AAUDIO_ERROR_NO_SERVICE) {
135 ALOGE("AAudioBinderClient: lost connection to AAudioService.");
136 dropAAudioService(); // force a reconnect
137 } else {
138 break;
139 }
140 }
141 return stream;
Phil Burkc0c70e32017-02-09 13:18:38 -0800142}
143
144aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800145 const sp<IAAudioService> &service = getAAudioService();
146 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
147 return service->closeStream(streamHandle);
148}
149
150/* Get an immutable description of the in-memory queues
151* used to communicate with the underlying HAL or Service.
152*/
153aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
154 AudioEndpointParcelable &parcelable) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800155 const sp<IAAudioService> &service = getAAudioService();
156 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
157 return service->getStreamDescription(streamHandle, parcelable);
158}
159
Phil Burkc0c70e32017-02-09 13:18:38 -0800160aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
161 const sp<IAAudioService> &service = getAAudioService();
162 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
163 return service->startStream(streamHandle);
164}
165
Phil Burkc0c70e32017-02-09 13:18:38 -0800166aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
167 const sp<IAAudioService> &service = getAAudioService();
168 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
Phil Burk71f35bb2017-04-13 16:05:07 -0700169 return service->pauseStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800170}
171
Phil Burk71f35bb2017-04-13 16:05:07 -0700172aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
173 const sp<IAAudioService> &service = getAAudioService();
174 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
175 return service->stopStream(streamHandle);
176}
177
Phil Burkc0c70e32017-02-09 13:18:38 -0800178aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
179 const sp<IAAudioService> &service = getAAudioService();
180 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
Phil Burk71f35bb2017-04-13 16:05:07 -0700181 return service->flushStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800182}
183
184/**
185* Manage the specified thread as a low latency audio thread.
186*/
187aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800188 pid_t clientThreadId,
189 int64_t periodNanoseconds) {
190 const sp<IAAudioService> &service = getAAudioService();
191 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
192 return service->registerAudioThread(streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800193 clientThreadId,
194 periodNanoseconds);
195}
196
197aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800198 pid_t clientThreadId) {
199 const sp<IAAudioService> &service = getAAudioService();
200 if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
201 return service->unregisterAudioThread(streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800202 clientThreadId);
203}