| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 1 | /* | 
 | 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 Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 22 | #include <binder/IInterface.h> | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 23 | #include <binder/IServiceManager.h> | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 24 | #include <binder/ProcessState.h> | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 25 | #include <utils/Mutex.h> | 
 | 26 | #include <utils/RefBase.h> | 
| Phil Burk | 9b3f8ef | 2017-05-16 11:37:43 -0700 | [diff] [blame] | 27 | #include <utils/Singleton.h> | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 28 | #include <media/AudioSystem.h> | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 29 |  | 
 | 30 | #include <aaudio/AAudio.h> | 
 | 31 |  | 
 | 32 | #include "AudioEndpointParcelable.h" | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 33 | #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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 38 |  | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 39 | //#include "AAudioServiceInterface.h" | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 40 |  | 
 | 41 | using android::String16; | 
 | 42 | using android::IServiceManager; | 
 | 43 | using android::defaultServiceManager; | 
 | 44 | using android::interface_cast; | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 45 | using android::IInterface; | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 46 | using android::IAAudioService; | 
 | 47 | using android::Mutex; | 
 | 48 | using android::sp; | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 49 | using android::wp; | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 50 |  | 
 | 51 | using namespace aaudio; | 
 | 52 |  | 
| Phil Burk | 9b3f8ef | 2017-05-16 11:37:43 -0700 | [diff] [blame] | 53 | ANDROID_SINGLETON_STATIC_INSTANCE(AAudioBinderClient); | 
 | 54 |  | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 55 | AAudioBinderClient::AAudioBinderClient() | 
 | 56 |         : AAudioServiceInterface() | 
 | 57 |         , Singleton<AAudioBinderClient>() { | 
 | 58 |  | 
 | 59 |     mAAudioClient = new AAudioClient(this); | 
| Phil Burk | c7abac4 | 2017-07-17 11:13:37 -0700 | [diff] [blame] | 60 |     ALOGV("AAudioBinderClient() created mAAudioClient = %p", mAAudioClient.get()); | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 61 | } | 
 | 62 |  | 
 | 63 | AAudioBinderClient::~AAudioBinderClient() { | 
 | 64 |     Mutex::Autolock _l(mServiceLock); | 
 | 65 |     if (mAAudioService != 0) { | 
 | 66 |         IInterface::asBinder(mAAudioService)->unlinkToDeath(mAAudioClient); | 
 | 67 |     } | 
 | 68 | } | 
 | 69 |  | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 70 | // 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 Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 73 | const 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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 90 |             if (binder != 0) { | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 91 |                 // Ask for notification if the service dies. | 
 | 92 |                 status_t status = binder->linkToDeath(mAAudioClient); | 
| Phil Burk | c7abac4 | 2017-07-17 11:13:37 -0700 | [diff] [blame] | 93 |                 // 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 Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 98 |                 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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 104 |             } | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 105 |         } | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 106 |         aaudioService = mAAudioService; | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 107 |     } | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 108 |     // Do this outside the mutex lock. | 
 | 109 |     if (needToRegister && aaudioService != 0) { // new client? | 
 | 110 |         aaudioService->registerClient(mAAudioClient); | 
 | 111 |     } | 
 | 112 |     return aaudioService; | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 113 | } | 
 | 114 |  | 
| Phil Burk | 11e8d33 | 2017-05-24 09:59:02 -0700 | [diff] [blame] | 115 | void AAudioBinderClient::dropAAudioService() { | 
 | 116 |     Mutex::Autolock _l(mServiceLock); | 
 | 117 |     mAAudioService.clear(); // force a reconnect | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 118 | } | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 119 |  | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 120 |  | 
 | 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 | */ | 
 | 126 | aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request, | 
 | 127 |                                                AAudioStreamConfiguration &configurationOutput) { | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 128 |     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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 134 |  | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 135 |         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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 145 | } | 
 | 146 |  | 
 | 147 | aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) { | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 148 |     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 | */ | 
 | 156 | aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle, | 
 | 157 |                                                          AudioEndpointParcelable &parcelable) { | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 158 |     const sp<IAAudioService> &service = getAAudioService(); | 
 | 159 |     if (service == 0) return AAUDIO_ERROR_NO_SERVICE; | 
 | 160 |     return service->getStreamDescription(streamHandle, parcelable); | 
 | 161 | } | 
 | 162 |  | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 163 | aaudio_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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 169 | aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) { | 
 | 170 |     const sp<IAAudioService> &service = getAAudioService(); | 
 | 171 |     if (service == 0) return AAUDIO_ERROR_NO_SERVICE; | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 172 |     return service->pauseStream(streamHandle); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 173 | } | 
 | 174 |  | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 175 | aaudio_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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 181 | aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) { | 
 | 182 |     const sp<IAAudioService> &service = getAAudioService(); | 
 | 183 |     if (service == 0) return AAUDIO_ERROR_NO_SERVICE; | 
| Phil Burk | 71f35bb | 2017-04-13 16:05:07 -0700 | [diff] [blame] | 184 |     return service->flushStream(streamHandle); | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 185 | } | 
 | 186 |  | 
 | 187 | /** | 
 | 188 | * Manage the specified thread as a low latency audio thread. | 
 | 189 | */ | 
 | 190 | aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle, | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 191 |                                                         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 Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 196 |                                         clientThreadId, | 
 | 197 |                                         periodNanoseconds); | 
 | 198 | } | 
 | 199 |  | 
 | 200 | aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle, | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 201 |                                                           pid_t clientThreadId) { | 
 | 202 |     const sp<IAAudioService> &service = getAAudioService(); | 
 | 203 |     if (service == 0) return AAUDIO_ERROR_NO_SERVICE; | 
 | 204 |     return service->unregisterAudioThread(streamHandle, | 
| Phil Burk | c0c70e3 | 2017-02-09 13:18:38 -0800 | [diff] [blame] | 205 |                                           clientThreadId); | 
 | 206 | } |