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