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 111 aaudio_result_t exitStandby(aaudio_handle_t streamHandle, 112 AudioEndpointParcelable &endpointOut) override; 113 onStreamChange(aaudio_handle_t,int32_t,int32_t)114 void onStreamChange(aaudio_handle_t /*handle*/, int32_t /*opcode*/, int32_t /*value*/) { 115 // TODO This is just a stub so we can have a client Binder to pass to the service. 116 // TODO Implemented in a later CL. 117 ALOGW("onStreamChange called!"); 118 } 119 120 class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient { 121 public: AAudioClient(const android::wp<AAudioBinderClient> & aaudioBinderClient)122 explicit AAudioClient(const android::wp<AAudioBinderClient>& aaudioBinderClient) 123 : mBinderClient(aaudioBinderClient) { 124 } 125 126 // implement DeathRecipient binderDied(const android::wp<android::IBinder> & who __unused)127 virtual void binderDied(const android::wp<android::IBinder>& who __unused) { 128 android::sp<AAudioBinderClient> client = mBinderClient.promote(); 129 if (client.get() != nullptr) { 130 client->dropAAudioService(); 131 } 132 ALOGW("AAudio service binderDied()!"); 133 } 134 135 // implement BnAAudioClient onStreamChange(int32_t handle,int32_t opcode,int32_t value)136 android::binder::Status onStreamChange(int32_t handle, int32_t opcode, int32_t value) { 137 static_assert(std::is_same_v<aaudio_handle_t, int32_t>); 138 android::sp<AAudioBinderClient> client = mBinderClient.promote(); 139 if (client.get() != nullptr) { 140 client->onStreamChange(handle, opcode, value); 141 } 142 return android::binder::Status::ok(); 143 } 144 private: 145 android::wp<AAudioBinderClient> mBinderClient; 146 }; 147 148 // This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface 149 // conventions (translating between data types and respective parcelables, translating error 150 // codes and calling conventions). 151 // The adapter also owns the underlying service object and is responsible to unlink its death 152 // listener when destroyed. 153 class Adapter : public AAudioBinderAdapter { 154 public: Adapter(const android::sp<IAAudioService> & delegate,android::sp<AAudioClient> aaudioClient)155 Adapter(const android::sp<IAAudioService>& delegate, 156 android::sp<AAudioClient> aaudioClient) 157 : AAudioBinderAdapter(delegate.get()), 158 mDelegate(delegate), 159 mAAudioClient(std::move(aaudioClient)) {} 160 ~Adapter()161 virtual ~Adapter() { 162 if (mDelegate != nullptr) { 163 android::IInterface::asBinder(mDelegate)->unlinkToDeath(mAAudioClient); 164 } 165 } 166 167 // 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)168 aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, 169 const android::AudioClient& client __unused, 170 const audio_attributes_t* attr __unused, 171 audio_port_handle_t* clientHandle __unused) override { 172 LOG_ALWAYS_FATAL("Shouldn't get here"); 173 return AAUDIO_ERROR_UNAVAILABLE; 174 } 175 176 // This should never be called (call is rejected at the AudioBinderClient level). stopClient(aaudio_handle_t streamHandle __unused,audio_port_handle_t clientHandle __unused)177 aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, 178 audio_port_handle_t clientHandle __unused) override { 179 LOG_ALWAYS_FATAL("Shouldn't get here"); 180 return AAUDIO_ERROR_UNAVAILABLE; 181 } 182 183 private: 184 android::sp<IAAudioService> mDelegate; 185 android::sp<AAudioClient> mAAudioClient; 186 }; 187 188 private: 189 android::Mutex mServiceLock; 190 std::shared_ptr<AAudioServiceInterface> mAdapter; 191 android::sp<AAudioClient> mAAudioClient; 192 193 std::shared_ptr<AAudioServiceInterface> getAAudioService(); 194 195 void dropAAudioService(); 196 197 }; 198 199 200 } /* namespace aaudio */ 201 202 #endif //ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H 203