1 /* 2 * Copyright (C) 2016 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 AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 18 #define AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 19 20 #include <assert.h> 21 #include <mutex> 22 23 #include <android-base/thread_annotations.h> 24 #include <media/AidlConversion.h> 25 #include <media/AudioClient.h> 26 #include <utils/RefBase.h> 27 28 #include "fifo/FifoBuffer.h" 29 #include "binding/AudioEndpointParcelable.h" 30 #include "binding/AAudioServiceMessage.h" 31 #include "binding/AAudioStreamRequest.h" 32 #include "core/AAudioStreamParameters.h" 33 #include "utility/AAudioUtilities.h" 34 #include "utility/AudioClock.h" 35 36 #include "AAudioCommandQueue.h" 37 #include "AAudioThread.h" 38 #include "SharedRingBuffer.h" 39 #include "TimestampScheduler.h" 40 41 namespace android { 42 class AAudioService; 43 } 44 45 namespace aaudio { 46 47 class AAudioServiceEndpoint; 48 49 // We expect the queue to only have a few commands. 50 // This should be way more than we need. 51 #define QUEUE_UP_CAPACITY_COMMANDS (128) 52 53 /** 54 * Each instance of AAudioServiceStreamBase corresponds to a client stream. 55 * It uses a subclass of AAudioServiceEndpoint to communicate with the underlying device or port. 56 */ 57 class AAudioServiceStreamBase 58 : public virtual android::RefBase 59 , public AAudioStreamParameters 60 , public Runnable { 61 62 public: 63 explicit AAudioServiceStreamBase(android::AAudioService &aAudioService); 64 65 ~AAudioServiceStreamBase() override; 66 67 enum { 68 ILLEGAL_THREAD_ID = 0 69 }; 70 71 static std::string dumpHeader(); 72 73 // does not include EOL 74 virtual std::string dump() const; 75 76 /** 77 * Open the device. 78 */ 79 virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) 80 EXCLUDES(mUpMessageQueueLock); 81 82 // We log the CLOSE from the close() method. We needed this separate method to log the OPEN 83 // because we had to wait until we generated the handle. 84 void logOpen(aaudio_handle_t streamHandle); 85 86 aaudio_result_t close() EXCLUDES(mLock); 87 88 /** 89 * Start the flow of audio data. 90 * 91 * This is not guaranteed to be synchronous but it currently is. 92 * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. 93 */ 94 aaudio_result_t start() EXCLUDES(mLock); 95 96 /** 97 * Stop the flow of data so that start() can resume without loss of data. 98 * 99 * This is not guaranteed to be synchronous but it currently is. 100 * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete. 101 */ 102 aaudio_result_t pause() EXCLUDES(mLock); 103 104 /** 105 * Stop the flow of data after the currently queued data has finished playing. 106 * 107 * This is not guaranteed to be synchronous but it currently is. 108 * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete. 109 * 110 */ 111 aaudio_result_t stop() EXCLUDES(mLock); 112 113 /** 114 * Discard any data held by the underlying HAL or Service. 115 * 116 * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete. 117 */ 118 aaudio_result_t flush() EXCLUDES(mLock); 119 120 /** 121 * Exit standby mode. The MMAP buffer will be reallocated. 122 */ 123 aaudio_result_t exitStandby(AudioEndpointParcelable *parcelable) EXCLUDES(mLock); 124 startClient(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)125 virtual aaudio_result_t startClient(const android::AudioClient& client, 126 const audio_attributes_t *attr __unused, 127 audio_port_handle_t *clientHandle __unused) { 128 ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 129 return AAUDIO_ERROR_UNAVAILABLE; 130 } 131 stopClient(audio_port_handle_t clientHandle __unused)132 virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) { 133 ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 134 return AAUDIO_ERROR_UNAVAILABLE; 135 } 136 137 aaudio_result_t registerAudioThread(pid_t clientThreadId, int priority) EXCLUDES(mLock); 138 139 aaudio_result_t unregisterAudioThread(pid_t clientThreadId) EXCLUDES(mLock); 140 isRunning()141 bool isRunning() const { 142 return mState == AAUDIO_STREAM_STATE_STARTED; 143 } 144 145 /** 146 * Fill in a parcelable description of stream. 147 */ 148 aaudio_result_t getDescription(AudioEndpointParcelable &parcelable) EXCLUDES(mLock); 149 setRegisteredThread(pid_t pid)150 void setRegisteredThread(pid_t pid) { 151 mRegisteredClientThread = pid; 152 } 153 getRegisteredThread()154 pid_t getRegisteredThread() const { 155 return mRegisteredClientThread; 156 } 157 getFramesPerBurst()158 int32_t getFramesPerBurst() const { 159 return mFramesPerBurst; 160 } 161 162 void run() override; // to implement Runnable 163 164 void disconnect() EXCLUDES(mLock); 165 getAudioClient()166 const android::AudioClient &getAudioClient() { 167 return mMmapClient; 168 } 169 getOwnerUserId()170 uid_t getOwnerUserId() const { 171 return VALUE_OR_FATAL(android::aidl2legacy_int32_t_uid_t( 172 mMmapClient.attributionSource.uid)); 173 } 174 getOwnerProcessId()175 pid_t getOwnerProcessId() const { 176 return VALUE_OR_FATAL(android::aidl2legacy_int32_t_pid_t( 177 mMmapClient.attributionSource.pid)); 178 } 179 getHandle()180 aaudio_handle_t getHandle() const { 181 return mHandle; 182 } setHandle(aaudio_handle_t handle)183 void setHandle(aaudio_handle_t handle) { 184 mHandle = handle; 185 } 186 getPortHandle()187 audio_port_handle_t getPortHandle() const { 188 return mClientHandle; 189 } 190 getState()191 aaudio_stream_state_t getState() const { 192 return mState; 193 } 194 195 void onVolumeChanged(float volume); 196 197 /** 198 * Set false when the stream is started. 199 * Set true when data is first read from the stream. 200 * @param b 201 */ setFlowing(bool b)202 void setFlowing(bool b) { 203 mFlowing = b; 204 } 205 isFlowing()206 bool isFlowing() const { 207 return mFlowing; 208 } 209 210 /** 211 * Set false when the stream should not longer be processed. 212 * This may be caused by a message queue overflow. 213 * Set true when stream is started. 214 * @param suspended 215 */ setSuspended(bool suspended)216 void setSuspended(bool suspended) { 217 mSuspended = suspended; 218 } 219 isSuspended()220 bool isSuspended() const { 221 return mSuspended; 222 } 223 getTypeText()224 virtual const char *getTypeText() const { return "Base"; } 225 226 protected: 227 228 /** 229 * Open the device. 230 */ 231 aaudio_result_t open(const aaudio::AAudioStreamRequest &request, 232 aaudio_sharing_mode_t sharingMode); 233 234 aaudio_result_t start_l() REQUIRES(mLock); 235 virtual aaudio_result_t close_l() REQUIRES(mLock); 236 virtual aaudio_result_t pause_l() REQUIRES(mLock); 237 virtual aaudio_result_t stop_l() REQUIRES(mLock); 238 void disconnect_l() REQUIRES(mLock); 239 aaudio_result_t flush_l() REQUIRES(mLock); 240 241 class RegisterAudioThreadParam : public AAudioCommandParam { 242 public: RegisterAudioThreadParam(pid_t ownerPid,pid_t clientThreadId,int priority)243 RegisterAudioThreadParam(pid_t ownerPid, pid_t clientThreadId, int priority) 244 : AAudioCommandParam(), mOwnerPid(ownerPid), 245 mClientThreadId(clientThreadId), mPriority(priority) { } 246 ~RegisterAudioThreadParam() override = default; 247 248 pid_t mOwnerPid; 249 pid_t mClientThreadId; 250 int mPriority; 251 }; 252 aaudio_result_t registerAudioThread_l( 253 pid_t ownerPid, pid_t clientThreadId, int priority) REQUIRES(mLock); 254 255 class UnregisterAudioThreadParam : public AAudioCommandParam { 256 public: UnregisterAudioThreadParam(pid_t clientThreadId)257 explicit UnregisterAudioThreadParam(pid_t clientThreadId) 258 : AAudioCommandParam(), mClientThreadId(clientThreadId) { } 259 ~UnregisterAudioThreadParam() override = default; 260 261 pid_t mClientThreadId; 262 }; 263 aaudio_result_t unregisterAudioThread_l(pid_t clientThreadId) REQUIRES(mLock); 264 265 class GetDescriptionParam : public AAudioCommandParam { 266 public: GetDescriptionParam(AudioEndpointParcelable * parcelable)267 explicit GetDescriptionParam(AudioEndpointParcelable* parcelable) 268 : AAudioCommandParam(), mParcelable(parcelable) { } 269 ~GetDescriptionParam() override = default; 270 271 AudioEndpointParcelable* mParcelable; 272 }; 273 aaudio_result_t getDescription_l(AudioEndpointParcelable* parcelable) 274 REQUIRES(mLock) EXCLUDES(mUpMessageQueueLock); 275 276 void setState(aaudio_stream_state_t state); 277 278 /** 279 * Device specific startup. 280 * @return AAUDIO_OK or negative error. 281 */ 282 virtual aaudio_result_t startDevice_l() REQUIRES(mLock); 283 284 aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command) 285 EXCLUDES(mUpMessageQueueLock); 286 287 aaudio_result_t sendCurrentTimestamp_l() REQUIRES(mLock); 288 289 aaudio_result_t sendXRunCount(int32_t xRunCount); 290 291 aaudio_result_t sendStartClientCommand(const android::AudioClient& client, 292 const audio_attributes_t *attr, 293 audio_port_handle_t *clientHandle) EXCLUDES(mLock); 294 295 aaudio_result_t sendStopClientCommand(audio_port_handle_t clientHandle) EXCLUDES(mLock); 296 297 /** 298 * @param positionFrames 299 * @param timeNanos 300 * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error 301 */ 302 virtual aaudio_result_t getFreeRunningPosition_l( 303 int64_t *positionFrames, int64_t *timeNanos) = 0; 304 305 virtual aaudio_result_t getHardwareTimestamp_l(int64_t *positionFrames, int64_t *timeNanos) = 0; 306 307 virtual aaudio_result_t getAudioDataDescription_l(AudioEndpointParcelable* parcelable) = 0; 308 309 310 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 311 isDisconnected_l()312 bool isDisconnected_l() const REQUIRES(mLock) { 313 return mDisconnected; 314 } setDisconnected_l(bool flag)315 void setDisconnected_l(bool flag) REQUIRES(mLock) { 316 mDisconnected = flag; 317 } 318 319 // If you implemented this method then please also override isStandbyImplemented(). standby_l()320 virtual aaudio_result_t standby_l() REQUIRES(mLock) { 321 return AAUDIO_ERROR_UNIMPLEMENTED; 322 } isStandbyImplemented()323 virtual bool isStandbyImplemented() { 324 return false; 325 } 326 327 class ExitStandbyParam : public AAudioCommandParam { 328 public: ExitStandbyParam(AudioEndpointParcelable * parcelable)329 explicit ExitStandbyParam(AudioEndpointParcelable* parcelable) 330 : AAudioCommandParam(), mParcelable(parcelable) { } 331 ~ExitStandbyParam() override = default; 332 333 AudioEndpointParcelable* mParcelable; 334 }; exitStandby_l(AudioEndpointParcelable * parcelable __unused)335 virtual aaudio_result_t exitStandby_l( 336 AudioEndpointParcelable* parcelable __unused) REQUIRES(mLock) { 337 return AAUDIO_ERROR_UNAVAILABLE; 338 } isStandby_l()339 bool isStandby_l() const REQUIRES(mLock) { 340 return mStandby; 341 } setStandby_l(bool standby)342 void setStandby_l(bool standby) REQUIRES(mLock) { 343 mStandby = standby; 344 } 345 isIdle_l()346 bool isIdle_l() const REQUIRES(mLock) { 347 return mState == AAUDIO_STREAM_STATE_OPEN || mState == AAUDIO_STREAM_STATE_PAUSED 348 || mState == AAUDIO_STREAM_STATE_STOPPED; 349 } 350 nextDataReportTime_l()351 virtual int64_t nextDataReportTime_l() REQUIRES(mLock) { 352 return std::numeric_limits<int64_t>::max(); 353 } reportData_l()354 virtual void reportData_l() REQUIRES(mLock) { return; } 355 356 class StartClientParam : public AAudioCommandParam { 357 public: StartClientParam(const android::AudioClient & client,const audio_attributes_t * attr,audio_port_handle_t * clientHandle)358 StartClientParam(const android::AudioClient& client, const audio_attributes_t* attr, 359 audio_port_handle_t* clientHandle) 360 : AAudioCommandParam(), mClient(client), mAttr(attr), mClientHandle(clientHandle) { 361 } 362 ~StartClientParam() override = default; 363 364 android::AudioClient mClient; 365 const audio_attributes_t* mAttr; 366 audio_port_handle_t* mClientHandle; 367 }; startClient_l(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)368 virtual aaudio_result_t startClient_l( 369 const android::AudioClient& client, 370 const audio_attributes_t *attr __unused, 371 audio_port_handle_t *clientHandle __unused) REQUIRES(mLock) { 372 ALOGD("AAudioServiceStreamBase::startClient_l(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 373 return AAUDIO_ERROR_UNAVAILABLE; 374 } 375 376 class StopClientParam : public AAudioCommandParam { 377 public: StopClientParam(audio_port_handle_t clientHandle)378 explicit StopClientParam(audio_port_handle_t clientHandle) 379 : AAudioCommandParam(), mClientHandle(clientHandle) { 380 } 381 ~StopClientParam() override = default; 382 383 audio_port_handle_t mClientHandle; 384 }; stopClient_l(audio_port_handle_t clientHandle)385 virtual aaudio_result_t stopClient_l(audio_port_handle_t clientHandle) REQUIRES(mLock) { 386 ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 387 return AAUDIO_ERROR_UNAVAILABLE; 388 } 389 390 pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID; 391 392 std::mutex mUpMessageQueueLock; 393 std::shared_ptr<SharedRingBuffer> mUpMessageQueue PT_GUARDED_BY(mUpMessageQueueLock); 394 395 enum : int32_t { 396 START, 397 PAUSE, 398 STOP, 399 FLUSH, 400 CLOSE, 401 DISCONNECT, 402 REGISTER_AUDIO_THREAD, 403 UNREGISTER_AUDIO_THREAD, 404 GET_DESCRIPTION, 405 EXIT_STANDBY, 406 START_CLIENT, 407 STOP_CLIENT, 408 }; 409 AAudioThread mCommandThread; 410 std::atomic_bool mThreadEnabled{false}; 411 AAudioCommandQueue mCommandQueue; 412 413 int32_t mFramesPerBurst = 0; 414 android::AudioClient mMmapClient; // set in open, used in MMAP start() 415 // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger. 416 audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE; 417 418 SimpleDoubleBuffer<Timestamp> mAtomicStreamTimestamp; 419 420 android::AAudioService &mAudioService; 421 422 // The mServiceEndpoint variable can be accessed by multiple threads. 423 // So we access it by locally promoting a weak pointer to a smart pointer, 424 // which is thread-safe. 425 android::sp<AAudioServiceEndpoint> mServiceEndpoint; 426 android::wp<AAudioServiceEndpoint> mServiceEndpointWeak; 427 428 std::string mMetricsId; // set once during open() 429 430 private: 431 432 aaudio_result_t stopTimestampThread(); 433 434 /** 435 * Send a message to the client with an int64_t data value. 436 */ 437 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 438 int64_t dataLong = 0); 439 /** 440 * Send a message to the client with a double data value. 441 */ 442 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 443 double dataDouble); 444 445 aaudio_result_t sendCommand(aaudio_command_opcode opCode, 446 std::shared_ptr<AAudioCommandParam> param = nullptr, 447 bool waitForReply = false, 448 int64_t timeoutNanos = 0); 449 450 void stopCommandThread(); 451 452 aaudio_result_t closeAndClear(); 453 454 /** 455 * @return true if the queue is getting full. 456 */ 457 bool isUpMessageQueueBusy() EXCLUDES(mUpMessageQueueLock); 458 459 aaudio_handle_t mHandle = -1; 460 bool mFlowing = false; 461 462 // This indicate that a running stream should not be processed because of an error, 463 // for example a full message queue. 464 std::atomic<bool> mSuspended{false}; 465 GUARDED_BY(mLock)466 bool mDisconnected GUARDED_BY(mLock) {false}; 467 468 bool mStandby GUARDED_BY(mLock) = false; 469 470 protected: 471 // Locking order is important. 472 // Acquire mLock before acquiring AAudioServiceEndpoint::mLockStreams 473 // The lock will be held by the command thread. All operations needing the lock must run from 474 // the command thread. 475 std::mutex mLock; // Prevent start/stop/close etcetera from colliding 476 }; 477 478 } /* namespace aaudio */ 479 480 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 481