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 #ifndef ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H 18 #define ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H 19 20 #include <utils/RefBase.h> 21 #include <utils/Singleton.h> 22 23 #include <aaudio/AAudio.h> 24 #include <binder/IInterface.h> 25 26 #include "aaudio/BnAAudioClient.h" 27 #include "aaudio/IAAudioService.h" 28 #include "AAudioServiceInterface.h" 29 #include "binding/AAudioBinderAdapter.h" 30 #include "binding/AAudioStreamRequest.h" 31 #include "binding/AudioEndpointParcelable.h" 32 #include "core/AAudioStreamParameters.h" 33 34 /** 35 * Implements the AAudioServiceInterface by talking to the service through Binder. 36 */ 37 38 namespace aaudio { 39 40 class AAudioBinderClient : public virtual android::RefBase 41 , public AAudioServiceInterface 42 , public android::Singleton<AAudioBinderClient> { 43 44 public: 45 46 AAudioBinderClient(); 47 48 virtual ~AAudioBinderClient(); 49 registerClient(const android::sp<IAAudioClient> & client __unused)50 void registerClient(const android::sp<IAAudioClient>& client __unused) override {} 51 52 /** 53 * @param request info needed to create the stream 54 * @param configuration contains resulting information about the created stream 55 * @return handle to the stream or a negative error 56 */ 57 aaudio_handle_t openStream(const AAudioStreamRequest &request, 58 AAudioStreamConfiguration &configurationOutput) override; 59 60 aaudio_result_t closeStream(aaudio_handle_t streamHandle) override; 61 62 /* Get an immutable description of the in-memory queues 63 * used to communicate with the underlying HAL or Service. 64 */ 65 aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, 66 AudioEndpointParcelable &endpointOut) override; 67 68 /** 69 * Start the flow of data. 70 * This is asynchronous. When complete, the service will send a STARTED event. 71 */ 72 aaudio_result_t startStream(aaudio_handle_t streamHandle) override; 73 74 /** 75 * Stop the flow of data such that start() can resume without loss of data. 76 * This is asynchronous. When complete, the service will send a PAUSED event. 77 */ 78 aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override; 79 80 aaudio_result_t stopStream(aaudio_handle_t streamHandle) override; 81 82 /** 83 * Discard any data held by the underlying HAL or Service. 84 * This is asynchronous. When complete, the service will send a FLUSHED event. 85 */ 86 aaudio_result_t flushStream(aaudio_handle_t streamHandle) override; 87 88 /** 89 * Manage the specified thread as a low latency audio thread. 90 * TODO Consider passing this information as part of the startStream() call. 91 */ 92 aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, 93 pid_t clientThreadId, 94 int64_t periodNanoseconds) override; 95 96 aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, 97 pid_t clientThreadId) override; 98 startClient(aaudio_handle_t streamHandle __unused,const android::AudioClient & client __unused,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)99 aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, 100 const android::AudioClient& client __unused, 101 const audio_attributes_t *attr __unused, 102 audio_port_handle_t *clientHandle __unused) override { 103 return AAUDIO_ERROR_UNAVAILABLE; 104 } 105 stopClient(aaudio_handle_t streamHandle __unused,audio_port_handle_t clientHandle __unused)106 aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, 107 audio_port_handle_t clientHandle __unused) override { 108 return AAUDIO_ERROR_UNAVAILABLE; 109 } 110 onStreamChange(aaudio_handle_t handle,int32_t opcode,int32_t value)111 void onStreamChange(aaudio_handle_t handle, int32_t opcode, int32_t value) { 112 // TODO This is just a stub so we can have a client Binder to pass to the service. 113 // TODO Implemented in a later CL. 114 ALOGW("onStreamChange called!"); 115 } 116 117 class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient { 118 public: AAudioClient(android::wp<AAudioBinderClient> aaudioBinderClient)119 AAudioClient(android::wp<AAudioBinderClient> aaudioBinderClient) 120 : mBinderClient(aaudioBinderClient) { 121 } 122 123 // implement DeathRecipient binderDied(const android::wp<android::IBinder> & who __unused)124 virtual void binderDied(const android::wp<android::IBinder>& who __unused) { 125 android::sp<AAudioBinderClient> client = mBinderClient.promote(); 126 if (client.get() != nullptr) { 127 client->dropAAudioService(); 128 } 129 ALOGW("AAudio service binderDied()!"); 130 } 131 132 // implement BnAAudioClient onStreamChange(int32_t handle,int32_t opcode,int32_t value)133 android::binder::Status onStreamChange(int32_t handle, int32_t opcode, int32_t value) { 134 static_assert(std::is_same_v<aaudio_handle_t, int32_t>); 135 android::sp<AAudioBinderClient> client = mBinderClient.promote(); 136 if (client.get() != nullptr) { 137 client->onStreamChange(handle, opcode, value); 138 } 139 return android::binder::Status::ok(); 140 } 141 private: 142 android::wp<AAudioBinderClient> mBinderClient; 143 }; 144 145 // This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface 146 // conventions (translating between data types and respective parcelables, translating error 147 // codes and calling conventions). 148 // The adapter also owns the underlying service object and is responsible to unlink its death 149 // listener when destroyed. 150 class Adapter : public AAudioBinderAdapter { 151 public: Adapter(const android::sp<IAAudioService> & delegate,const android::sp<AAudioClient> & aaudioClient)152 Adapter(const android::sp<IAAudioService>& delegate, 153 const android::sp<AAudioClient>& aaudioClient) 154 : AAudioBinderAdapter(delegate.get()), 155 mDelegate(delegate), 156 mAAudioClient(aaudioClient) {} 157 ~Adapter()158 virtual ~Adapter() { 159 if (mDelegate != nullptr) { 160 android::IInterface::asBinder(mDelegate)->unlinkToDeath(mAAudioClient); 161 } 162 } 163 164 // This should never be called (call is rejected at the AudioBinderClient level). startClient(aaudio_handle_t streamHandle __unused,const android::AudioClient & client __unused,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)165 aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, 166 const android::AudioClient& client __unused, 167 const audio_attributes_t* attr __unused, 168 audio_port_handle_t* clientHandle __unused) override { 169 LOG_ALWAYS_FATAL("Shouldn't get here"); 170 return AAUDIO_ERROR_UNAVAILABLE; 171 } 172 173 // This should never be called (call is rejected at the AudioBinderClient level). stopClient(aaudio_handle_t streamHandle __unused,audio_port_handle_t clientHandle __unused)174 aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, 175 audio_port_handle_t clientHandle __unused) override { 176 LOG_ALWAYS_FATAL("Shouldn't get here"); 177 return AAUDIO_ERROR_UNAVAILABLE; 178 } 179 180 private: 181 android::sp<IAAudioService> mDelegate; 182 android::sp<AAudioClient> mAAudioClient; 183 }; 184 185 private: 186 android::Mutex mServiceLock; 187 std::shared_ptr<AAudioServiceInterface> mAdapter; 188 android::sp<AAudioClient> mAAudioClient; 189 190 std::shared_ptr<AAudioServiceInterface> getAAudioService(); 191 192 void dropAAudioService(); 193 194 }; 195 196 197 } /* namespace aaudio */ 198 199 #endif //ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H 200