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 <media/AudioClient.h> 24 #include <utils/RefBase.h> 25 26 #include "fifo/FifoBuffer.h" 27 #include "binding/IAAudioService.h" 28 #include "binding/AudioEndpointParcelable.h" 29 #include "binding/AAudioServiceMessage.h" 30 #include "utility/AAudioUtilities.h" 31 #include "utility/AudioClock.h" 32 33 #include "SharedRingBuffer.h" 34 #include "AAudioThread.h" 35 36 namespace android { 37 class AAudioService; 38 } 39 40 namespace aaudio { 41 42 class AAudioServiceEndpoint; 43 44 // We expect the queue to only have a few commands. 45 // This should be way more than we need. 46 #define QUEUE_UP_CAPACITY_COMMANDS (128) 47 48 /** 49 * Each instance of AAudioServiceStreamBase corresponds to a client stream. 50 * It uses a subclass of AAudioServiceEndpoint to communicate with the underlying device or port. 51 */ 52 class AAudioServiceStreamBase 53 : public virtual android::RefBase 54 , public AAudioStreamParameters 55 , public Runnable { 56 57 public: 58 explicit AAudioServiceStreamBase(android::AAudioService &aAudioService); 59 60 virtual ~AAudioServiceStreamBase(); 61 62 enum { 63 ILLEGAL_THREAD_ID = 0 64 }; 65 66 static std::string dumpHeader(); 67 68 // does not include EOL 69 virtual std::string dump() const; 70 71 /** 72 * Open the device. 73 */ 74 virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) = 0; 75 76 // We log the CLOSE from the close() method. We needed this separate method to log the OPEN 77 // because we had to wait until we generated the handle. 78 void logOpen(aaudio_handle_t streamHandle); 79 80 aaudio_result_t close(); 81 82 /** 83 * Start the flow of audio data. 84 * 85 * This is not guaranteed to be synchronous but it currently is. 86 * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. 87 */ 88 aaudio_result_t start(); 89 90 /** 91 * Stop the flow of data so that start() can resume without loss of data. 92 * 93 * This is not guaranteed to be synchronous but it currently is. 94 * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete. 95 */ 96 aaudio_result_t pause(); 97 98 /** 99 * Stop the flow of data after the currently queued data has finished playing. 100 * 101 * This is not guaranteed to be synchronous but it currently is. 102 * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete. 103 * 104 */ 105 aaudio_result_t stop(); 106 107 /** 108 * Discard any data held by the underlying HAL or Service. 109 * 110 * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete. 111 */ 112 aaudio_result_t flush(); 113 startClient(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)114 virtual aaudio_result_t startClient(const android::AudioClient& client, 115 const audio_attributes_t *attr __unused, 116 audio_port_handle_t *clientHandle __unused) { 117 ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 118 return AAUDIO_ERROR_UNAVAILABLE; 119 } 120 stopClient(audio_port_handle_t clientHandle __unused)121 virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) { 122 ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 123 return AAUDIO_ERROR_UNAVAILABLE; 124 } 125 126 aaudio_result_t registerAudioThread(pid_t clientThreadId, int priority); 127 128 aaudio_result_t unregisterAudioThread(pid_t clientThreadId); 129 isRunning()130 bool isRunning() const { 131 return mState == AAUDIO_STREAM_STATE_STARTED; 132 } 133 134 /** 135 * Fill in a parcelable description of stream. 136 */ 137 aaudio_result_t getDescription(AudioEndpointParcelable &parcelable); 138 setRegisteredThread(pid_t pid)139 void setRegisteredThread(pid_t pid) { 140 mRegisteredClientThread = pid; 141 } 142 getRegisteredThread()143 pid_t getRegisteredThread() const { 144 return mRegisteredClientThread; 145 } 146 getFramesPerBurst()147 int32_t getFramesPerBurst() const { 148 return mFramesPerBurst; 149 } 150 151 void run() override; // to implement Runnable 152 153 void disconnect(); 154 getAudioClient()155 const android::AudioClient &getAudioClient() { 156 return mMmapClient; 157 } 158 getOwnerUserId()159 uid_t getOwnerUserId() const { 160 return mMmapClient.clientUid; 161 } 162 getOwnerProcessId()163 pid_t getOwnerProcessId() const { 164 return mMmapClient.clientPid; 165 } 166 getHandle()167 aaudio_handle_t getHandle() const { 168 return mHandle; 169 } setHandle(aaudio_handle_t handle)170 void setHandle(aaudio_handle_t handle) { 171 mHandle = handle; 172 } 173 getPortHandle()174 audio_port_handle_t getPortHandle() const { 175 return mClientHandle; 176 } 177 getState()178 aaudio_stream_state_t getState() const { 179 return mState; 180 } 181 182 void onVolumeChanged(float volume); 183 184 /** 185 * Set false when the stream is started. 186 * Set true when data is first read from the stream. 187 * @param b 188 */ setFlowing(bool b)189 void setFlowing(bool b) { 190 mFlowing = b; 191 } 192 isFlowing()193 bool isFlowing() const { 194 return mFlowing; 195 } 196 197 /** 198 * Set false when the stream should not longer be processed. 199 * This may be caused by a message queue overflow. 200 * Set true when stream is started. 201 * @param suspended 202 */ setSuspended(bool suspended)203 void setSuspended(bool suspended) { 204 mSuspended = suspended; 205 } 206 isSuspended()207 bool isSuspended() const { 208 return mSuspended; 209 } 210 211 /** 212 * Atomically increment the number of active references to the stream by AAudioService. 213 * 214 * This is called under a global lock in AAudioStreamTracker. 215 * 216 * @return value after the increment 217 */ 218 int32_t incrementServiceReferenceCount_l(); 219 220 /** 221 * Atomically decrement the number of active references to the stream by AAudioService. 222 * This should only be called after incrementServiceReferenceCount_l(). 223 * 224 * This is called under a global lock in AAudioStreamTracker. 225 * 226 * @return value after the decrement 227 */ 228 int32_t decrementServiceReferenceCount_l(); 229 isCloseNeeded()230 bool isCloseNeeded() const { 231 return mCloseNeeded.load(); 232 } 233 234 /** 235 * Mark this stream as needing to be closed. 236 * Once marked for closing, it cannot be unmarked. 237 */ markCloseNeeded()238 void markCloseNeeded() { 239 mCloseNeeded.store(true); 240 } 241 getTypeText()242 virtual const char *getTypeText() const { return "Base"; } 243 244 protected: 245 246 /** 247 * Open the device. 248 */ 249 aaudio_result_t open(const aaudio::AAudioStreamRequest &request, 250 aaudio_sharing_mode_t sharingMode); 251 252 // These must be called under mLock 253 virtual aaudio_result_t close_l(); 254 virtual aaudio_result_t pause_l(); 255 virtual aaudio_result_t stop_l(); 256 void disconnect_l(); 257 258 void setState(aaudio_stream_state_t state); 259 260 /** 261 * Device specific startup. 262 * @return AAUDIO_OK or negative error. 263 */ 264 virtual aaudio_result_t startDevice(); 265 266 aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command); 267 268 aaudio_result_t sendCurrentTimestamp(); 269 270 aaudio_result_t sendXRunCount(int32_t xRunCount); 271 272 /** 273 * @param positionFrames 274 * @param timeNanos 275 * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error 276 */ 277 virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0; 278 279 virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0; 280 281 virtual aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) = 0; 282 283 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 284 285 pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID; 286 287 SharedRingBuffer* mUpMessageQueue; 288 std::mutex mUpMessageQueueLock; 289 290 AAudioThread mTimestampThread; 291 // This is used by one thread to tell another thread to exit. So it must be atomic. 292 std::atomic<bool> mThreadEnabled{false}; 293 294 int32_t mFramesPerBurst = 0; 295 android::AudioClient mMmapClient; // set in open, used in MMAP start() 296 // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger. 297 audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE; 298 299 SimpleDoubleBuffer<Timestamp> mAtomicStreamTimestamp; 300 301 android::AAudioService &mAudioService; 302 303 // The mServiceEndpoint variable can be accessed by multiple threads. 304 // So we access it by locally promoting a weak pointer to a smart pointer, 305 // which is thread-safe. 306 android::sp<AAudioServiceEndpoint> mServiceEndpoint; 307 android::wp<AAudioServiceEndpoint> mServiceEndpointWeak; 308 309 std::string mMetricsId; // set once during open() 310 311 private: 312 313 aaudio_result_t stopTimestampThread(); 314 315 /** 316 * Send a message to the client with an int64_t data value. 317 */ 318 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 319 int64_t dataLong = 0); 320 /** 321 * Send a message to the client with a double data value. 322 */ 323 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 324 double dataDouble); 325 326 /** 327 * @return true if the queue is getting full. 328 */ 329 bool isUpMessageQueueBusy(); 330 331 aaudio_handle_t mHandle = -1; 332 bool mFlowing = false; 333 334 // This is modified under a global lock in AAudioStreamTracker. 335 int32_t mCallingCount = 0; 336 337 // This indicates that a stream that is being referenced by a binder call needs to closed. 338 std::atomic<bool> mCloseNeeded{false}; 339 340 // This indicate that a running stream should not be processed because of an error, 341 // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded. 342 std::atomic<bool> mSuspended{false}; 343 344 // Locking order is important. 345 // Always acquire mLock before acquiring AAudioServiceEndpoint::mLockStreams 346 std::mutex mLock; // Prevent start/stop/close etcetera from colliding 347 }; 348 349 } /* namespace aaudio */ 350 351 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 352