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 /** 73 * Open the device. 74 */ 75 virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) = 0; 76 77 virtual aaudio_result_t close(); 78 79 /** 80 * Start the flow of audio data. 81 * 82 * This is not guaranteed to be synchronous but it currently is. 83 * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. 84 */ 85 virtual aaudio_result_t start(); 86 87 /** 88 * Stop the flow of data so that start() can resume without loss of data. 89 * 90 * This is not guaranteed to be synchronous but it currently is. 91 * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete. 92 */ 93 virtual aaudio_result_t pause(); 94 95 /** 96 * Stop the flow of data after the currently queued data has finished playing. 97 * 98 * This is not guaranteed to be synchronous but it currently is. 99 * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete. 100 * 101 */ 102 virtual aaudio_result_t stop(); 103 104 aaudio_result_t stopTimestampThread(); 105 106 /** 107 * Discard any data held by the underlying HAL or Service. 108 * 109 * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete. 110 */ 111 virtual aaudio_result_t flush(); 112 113 startClient(const android::AudioClient & client __unused,audio_port_handle_t * clientHandle __unused)114 virtual aaudio_result_t startClient(const android::AudioClient& client __unused, 115 audio_port_handle_t *clientHandle __unused) { 116 ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 117 return AAUDIO_ERROR_UNAVAILABLE; 118 } 119 stopClient(audio_port_handle_t clientHandle __unused)120 virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) { 121 ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 122 return AAUDIO_ERROR_UNAVAILABLE; 123 } 124 isRunning()125 bool isRunning() const { 126 return mState == AAUDIO_STREAM_STATE_STARTED; 127 } 128 129 // ------------------------------------------------------------------- 130 131 /** 132 * Send a message to the client with an int64_t data value. 133 */ 134 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 135 int64_t dataLong = 0); 136 /** 137 * Send a message to the client with an double data value. 138 */ 139 aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 140 double dataDouble); 141 142 /** 143 * Fill in a parcelable description of stream. 144 */ 145 aaudio_result_t getDescription(AudioEndpointParcelable &parcelable); 146 147 setRegisteredThread(pid_t pid)148 void setRegisteredThread(pid_t pid) { 149 mRegisteredClientThread = pid; 150 } 151 getRegisteredThread()152 pid_t getRegisteredThread() const { 153 return mRegisteredClientThread; 154 } 155 getFramesPerBurst()156 int32_t getFramesPerBurst() const { 157 return mFramesPerBurst; 158 } 159 160 void run() override; // to implement Runnable 161 162 void disconnect(); 163 getAudioClient()164 const android::AudioClient &getAudioClient() { 165 return mMmapClient; 166 } 167 getOwnerUserId()168 uid_t getOwnerUserId() const { 169 return mMmapClient.clientUid; 170 } 171 getOwnerProcessId()172 pid_t getOwnerProcessId() const { 173 return mMmapClient.clientPid; 174 } 175 getHandle()176 aaudio_handle_t getHandle() const { 177 return mHandle; 178 } setHandle(aaudio_handle_t handle)179 void setHandle(aaudio_handle_t handle) { 180 mHandle = handle; 181 } 182 getPortHandle()183 audio_port_handle_t getPortHandle() const { 184 return mClientHandle; 185 } 186 getState()187 aaudio_stream_state_t getState() const { 188 return mState; 189 } 190 191 void onVolumeChanged(float volume); 192 193 /** 194 * Set false when the stream is started. 195 * Set true when data is first read from the stream. 196 * @param b 197 */ setFlowing(bool b)198 void setFlowing(bool b) { 199 mFlowing = b; 200 } 201 isFlowing()202 bool isFlowing() const { 203 return mFlowing; 204 } 205 206 /** 207 * Set false when the stream should not longer be processed. 208 * This may be caused by a message queue overflow. 209 * Set true when stream is started. 210 * @param suspended 211 */ setSuspended(bool suspended)212 void setSuspended(bool suspended) { 213 mSuspended = suspended; 214 } 215 isSuspended()216 bool isSuspended() const { 217 return mSuspended; 218 } 219 220 /** 221 * Atomically increment the number of active references to the stream by AAudioService. 222 * 223 * This is called under a global lock in AAudioStreamTracker. 224 * 225 * @return value after the increment 226 */ 227 int32_t incrementServiceReferenceCount_l(); 228 229 /** 230 * Atomically decrement the number of active references to the stream by AAudioService. 231 * This should only be called after incrementServiceReferenceCount_l(). 232 * 233 * This is called under a global lock in AAudioStreamTracker. 234 * 235 * @return value after the decrement 236 */ 237 int32_t decrementServiceReferenceCount_l(); 238 isCloseNeeded()239 bool isCloseNeeded() const { 240 return mCloseNeeded.load(); 241 } 242 243 /** 244 * Mark this stream as needing to be closed. 245 * Once marked for closing, it cannot be unmarked. 246 */ markCloseNeeded()247 void markCloseNeeded() { 248 mCloseNeeded.store(true); 249 } 250 getTypeText()251 virtual const char *getTypeText() const { return "Base"; } 252 253 protected: 254 255 /** 256 * Open the device. 257 */ 258 aaudio_result_t open(const aaudio::AAudioStreamRequest &request, 259 aaudio_sharing_mode_t sharingMode); 260 setState(aaudio_stream_state_t state)261 void setState(aaudio_stream_state_t state) { 262 mState = state; 263 } 264 265 /** 266 * Device specific startup. 267 * @return AAUDIO_OK or negative error. 268 */ 269 virtual aaudio_result_t startDevice(); 270 271 aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command); 272 273 aaudio_result_t sendCurrentTimestamp(); 274 275 aaudio_result_t sendXRunCount(int32_t xRunCount); 276 277 /** 278 * @param positionFrames 279 * @param timeNanos 280 * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error 281 */ 282 virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0; 283 284 virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0; 285 286 virtual aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) = 0; 287 288 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 289 290 pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID; 291 292 SharedRingBuffer* mUpMessageQueue; 293 std::mutex mUpMessageQueueLock; 294 295 AAudioThread mTimestampThread; 296 // This is used by one thread to tell another thread to exit. So it must be atomic. 297 std::atomic<bool> mThreadEnabled{false}; 298 299 int32_t mFramesPerBurst = 0; 300 android::AudioClient mMmapClient; // set in open, used in MMAP start() 301 // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger. 302 audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE; 303 304 SimpleDoubleBuffer<Timestamp> mAtomicStreamTimestamp; 305 306 android::AAudioService &mAudioService; 307 308 // The mServiceEndpoint variable can be accessed by multiple threads. 309 // So we access it by locally promoting a weak pointer to a smart pointer, 310 // which is thread-safe. 311 android::sp<AAudioServiceEndpoint> mServiceEndpoint; 312 android::wp<AAudioServiceEndpoint> mServiceEndpointWeak; 313 314 private: 315 316 /** 317 * @return true if the queue is getting full. 318 */ 319 bool isUpMessageQueueBusy(); 320 321 aaudio_handle_t mHandle = -1; 322 bool mFlowing = false; 323 324 // This is modified under a global lock in AAudioStreamTracker. 325 int32_t mCallingCount = 0; 326 327 // This indicates that a stream that is being referenced by a binder call needs to closed. 328 std::atomic<bool> mCloseNeeded{false}; 329 330 // This indicate that a running stream should not be processed because of an error, 331 // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded. 332 std::atomic<bool> mSuspended{false}; 333 }; 334 335 } /* namespace aaudio */ 336 337 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 338