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 virtual ~AAudioServiceStreamBase(); 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) = 0; 80 81 // We log the CLOSE from the close() method. We needed this separate method to log the OPEN 82 // because we had to wait until we generated the handle. 83 void logOpen(aaudio_handle_t streamHandle); 84 85 aaudio_result_t close() EXCLUDES(mLock); 86 87 /** 88 * Start the flow of audio data. 89 * 90 * This is not guaranteed to be synchronous but it currently is. 91 * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. 92 */ 93 aaudio_result_t start() EXCLUDES(mLock); 94 95 /** 96 * Stop the flow of data so that start() can resume without loss of data. 97 * 98 * This is not guaranteed to be synchronous but it currently is. 99 * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete. 100 */ 101 aaudio_result_t pause() EXCLUDES(mLock); 102 103 /** 104 * Stop the flow of data after the currently queued data has finished playing. 105 * 106 * This is not guaranteed to be synchronous but it currently is. 107 * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete. 108 * 109 */ 110 aaudio_result_t stop() EXCLUDES(mLock); 111 112 /** 113 * Discard any data held by the underlying HAL or Service. 114 * 115 * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete. 116 */ 117 aaudio_result_t flush() EXCLUDES(mLock); 118 119 /** 120 * Exit standby mode. The MMAP buffer will be reallocated. 121 */ 122 aaudio_result_t exitStandby(AudioEndpointParcelable *parcelable) EXCLUDES(mLock); 123 startClient(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)124 virtual aaudio_result_t startClient(const android::AudioClient& client, 125 const audio_attributes_t *attr __unused, 126 audio_port_handle_t *clientHandle __unused) { 127 ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 128 return AAUDIO_ERROR_UNAVAILABLE; 129 } 130 stopClient(audio_port_handle_t clientHandle __unused)131 virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) { 132 ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 133 return AAUDIO_ERROR_UNAVAILABLE; 134 } 135 136 aaudio_result_t registerAudioThread(pid_t clientThreadId, int priority) EXCLUDES(mLock); 137 138 aaudio_result_t unregisterAudioThread(pid_t clientThreadId) EXCLUDES(mLock); 139 isRunning()140 bool isRunning() const { 141 return mState == AAUDIO_STREAM_STATE_STARTED; 142 } 143 144 /** 145 * Fill in a parcelable description of stream. 146 */ 147 aaudio_result_t getDescription(AudioEndpointParcelable &parcelable) EXCLUDES(mLock); 148 setRegisteredThread(pid_t pid)149 void setRegisteredThread(pid_t pid) { 150 mRegisteredClientThread = pid; 151 } 152 getRegisteredThread()153 pid_t getRegisteredThread() const { 154 return mRegisteredClientThread; 155 } 156 getFramesPerBurst()157 int32_t getFramesPerBurst() const { 158 return mFramesPerBurst; 159 } 160 161 void run() override; // to implement Runnable 162 163 void disconnect() EXCLUDES(mLock); 164 getAudioClient()165 const android::AudioClient &getAudioClient() { 166 return mMmapClient; 167 } 168 getOwnerUserId()169 uid_t getOwnerUserId() const { 170 return VALUE_OR_FATAL(android::aidl2legacy_int32_t_uid_t( 171 mMmapClient.attributionSource.uid)); 172 } 173 getOwnerProcessId()174 pid_t getOwnerProcessId() const { 175 return VALUE_OR_FATAL(android::aidl2legacy_int32_t_pid_t( 176 mMmapClient.attributionSource.pid)); 177 } 178 getHandle()179 aaudio_handle_t getHandle() const { 180 return mHandle; 181 } setHandle(aaudio_handle_t handle)182 void setHandle(aaudio_handle_t handle) { 183 mHandle = handle; 184 } 185 getPortHandle()186 audio_port_handle_t getPortHandle() const { 187 return mClientHandle; 188 } 189 getState()190 aaudio_stream_state_t getState() const { 191 return mState; 192 } 193 194 void onVolumeChanged(float volume); 195 196 /** 197 * Set false when the stream is started. 198 * Set true when data is first read from the stream. 199 * @param b 200 */ setFlowing(bool b)201 void setFlowing(bool b) { 202 mFlowing = b; 203 } 204 isFlowing()205 bool isFlowing() const { 206 return mFlowing; 207 } 208 209 /** 210 * Set false when the stream should not longer be processed. 211 * This may be caused by a message queue overflow. 212 * Set true when stream is started. 213 * @param suspended 214 */ setSuspended(bool suspended)215 void setSuspended(bool suspended) { 216 mSuspended = suspended; 217 } 218 isSuspended()219 bool isSuspended() const { 220 return mSuspended; 221 } 222 isCloseNeeded()223 bool isCloseNeeded() const { 224 return mCloseNeeded.load(); 225 } 226 227 /** 228 * Mark this stream as needing to be closed. 229 * Once marked for closing, it cannot be unmarked. 230 */ markCloseNeeded()231 void markCloseNeeded() { 232 mCloseNeeded.store(true); 233 } 234 getTypeText()235 virtual const char *getTypeText() const { return "Base"; } 236 237 protected: 238 239 /** 240 * Open the device. 241 */ 242 aaudio_result_t open(const aaudio::AAudioStreamRequest &request, 243 aaudio_sharing_mode_t sharingMode); 244 245 aaudio_result_t start_l() REQUIRES(mLock); 246 virtual aaudio_result_t close_l() REQUIRES(mLock); 247 virtual aaudio_result_t pause_l() REQUIRES(mLock); 248 virtual aaudio_result_t stop_l() REQUIRES(mLock); 249 void disconnect_l() REQUIRES(mLock); 250 aaudio_result_t flush_l() REQUIRES(mLock); 251 252 class RegisterAudioThreadParam : public AAudioCommandParam { 253 public: RegisterAudioThreadParam(pid_t ownerPid,pid_t clientThreadId,int priority)254 RegisterAudioThreadParam(pid_t ownerPid, pid_t clientThreadId, int priority) 255 : AAudioCommandParam(), mOwnerPid(ownerPid), 256 mClientThreadId(clientThreadId), mPriority(priority) { } 257 ~RegisterAudioThreadParam() = default; 258 259 pid_t mOwnerPid; 260 pid_t mClientThreadId; 261 int mPriority; 262 }; 263 aaudio_result_t registerAudioThread_l( 264 pid_t ownerPid, pid_t clientThreadId, int priority) REQUIRES(mLock); 265 266 class UnregisterAudioThreadParam : public AAudioCommandParam { 267 public: UnregisterAudioThreadParam(pid_t clientThreadId)268 UnregisterAudioThreadParam(pid_t clientThreadId) 269 : AAudioCommandParam(), mClientThreadId(clientThreadId) { } 270 ~UnregisterAudioThreadParam() = default; 271 272 pid_t mClientThreadId; 273 }; 274 aaudio_result_t unregisterAudioThread_l(pid_t clientThreadId) REQUIRES(mLock); 275 276 class GetDescriptionParam : public AAudioCommandParam { 277 public: GetDescriptionParam(AudioEndpointParcelable * parcelable)278 GetDescriptionParam(AudioEndpointParcelable* parcelable) 279 : AAudioCommandParam(), mParcelable(parcelable) { } 280 ~GetDescriptionParam() = default; 281 282 AudioEndpointParcelable* mParcelable; 283 }; 284 aaudio_result_t getDescription_l(AudioEndpointParcelable* parcelable) REQUIRES(mLock); 285 286 void setState(aaudio_stream_state_t state); 287 288 /** 289 * Device specific startup. 290 * @return AAUDIO_OK or negative error. 291 */ 292 virtual aaudio_result_t startDevice(); 293 294 aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command); 295 296 aaudio_result_t sendCurrentTimestamp_l() REQUIRES(mLock); 297 298 aaudio_result_t sendXRunCount(int32_t xRunCount); 299 300 /** 301 * @param positionFrames 302 * @param timeNanos 303 * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error 304 */ 305 virtual aaudio_result_t getFreeRunningPosition_l( 306 int64_t *positionFrames, int64_t *timeNanos) = 0; 307 308 virtual aaudio_result_t getHardwareTimestamp_l(int64_t *positionFrames, int64_t *timeNanos) = 0; 309 310 virtual aaudio_result_t getAudioDataDescription_l(AudioEndpointParcelable* parcelable) = 0; 311 312 313 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 314 isDisconnected_l()315 bool isDisconnected_l() const REQUIRES(mLock) { 316 return mDisconnected; 317 } setDisconnected_l(bool flag)318 void setDisconnected_l(bool flag) REQUIRES(mLock) { 319 mDisconnected = flag; 320 } 321 standby_l()322 virtual aaudio_result_t standby_l() REQUIRES(mLock) { 323 return AAUDIO_ERROR_UNIMPLEMENTED; 324 } 325 class ExitStandbyParam : public AAudioCommandParam { 326 public: ExitStandbyParam(AudioEndpointParcelable * parcelable)327 ExitStandbyParam(AudioEndpointParcelable* parcelable) 328 : AAudioCommandParam(), mParcelable(parcelable) { } 329 ~ExitStandbyParam() = default; 330 331 AudioEndpointParcelable* mParcelable; 332 }; exitStandby_l(AudioEndpointParcelable * parcelable __unused)333 virtual aaudio_result_t exitStandby_l( 334 AudioEndpointParcelable* parcelable __unused) REQUIRES(mLock) { 335 return AAUDIO_ERROR_UNAVAILABLE; 336 } isStandby_l()337 bool isStandby_l() const REQUIRES(mLock) { 338 return mStandby; 339 } setStandby_l(bool standby)340 void setStandby_l(bool standby) REQUIRES(mLock) { 341 mStandby = standby; 342 } 343 isIdle_l()344 bool isIdle_l() const REQUIRES(mLock) { 345 return mState == AAUDIO_STREAM_STATE_OPEN || mState == AAUDIO_STREAM_STATE_PAUSED 346 || mState == AAUDIO_STREAM_STATE_STOPPED; 347 } 348 349 pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID; 350 351 std::mutex mUpMessageQueueLock; 352 std::shared_ptr<SharedRingBuffer> mUpMessageQueue; 353 354 enum : int32_t { 355 START, 356 PAUSE, 357 STOP, 358 FLUSH, 359 CLOSE, 360 DISCONNECT, 361 REGISTER_AUDIO_THREAD, 362 UNREGISTER_AUDIO_THREAD, 363 GET_DESCRIPTION, 364 EXIT_STANDBY, 365 }; 366 AAudioThread mCommandThread; 367 std::atomic<bool> mThreadEnabled{false}; 368 AAudioCommandQueue mCommandQueue; 369 370 int32_t mFramesPerBurst = 0; 371 android::AudioClient mMmapClient; // set in open, used in MMAP start() 372 // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger. 373 audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE; 374 375 SimpleDoubleBuffer<Timestamp> mAtomicStreamTimestamp; 376 377 android::AAudioService &mAudioService; 378 379 // The mServiceEndpoint variable can be accessed by multiple threads. 380 // So we access it by locally promoting a weak pointer to a smart pointer, 381 // which is thread-safe. 382 android::sp<AAudioServiceEndpoint> mServiceEndpoint; 383 android::wp<AAudioServiceEndpoint> mServiceEndpointWeak; 384 385 std::string mMetricsId; // set once during open() 386 387 private: 388 389 aaudio_result_t stopTimestampThread(); 390 391 /** 392 * Send a message to the client with an int64_t data value. 393 */ 394 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 395 int64_t dataLong = 0); 396 /** 397 * Send a message to the client with a double data value. 398 */ 399 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 400 double dataDouble); 401 402 aaudio_result_t sendCommand(aaudio_command_opcode opCode, 403 std::shared_ptr<AAudioCommandParam> param = nullptr, 404 bool waitForReply = false, 405 int64_t timeoutNanos = 0); 406 407 aaudio_result_t closeAndClear(); 408 409 /** 410 * @return true if the queue is getting full. 411 */ 412 bool isUpMessageQueueBusy(); 413 414 aaudio_handle_t mHandle = -1; 415 bool mFlowing = false; 416 417 // This indicates that a stream that is being referenced by a binder call 418 // and needs to closed. 419 std::atomic<bool> mCloseNeeded{false}; // TODO remove 420 421 // This indicate that a running stream should not be processed because of an error, 422 // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded. 423 std::atomic<bool> mSuspended{false}; 424 GUARDED_BY(mLock)425 bool mDisconnected GUARDED_BY(mLock) {false}; 426 427 bool mStandby GUARDED_BY(mLock) = false; 428 429 protected: 430 // Locking order is important. 431 // Acquire mLock before acquiring AAudioServiceEndpoint::mLockStreams 432 // The lock will be held by the command thread. All operations needing the lock must run from 433 // the command thread. 434 std::mutex mLock; // Prevent start/stop/close etcetera from colliding 435 }; 436 437 } /* namespace aaudio */ 438 439 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 440