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 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 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 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 148 void setRegisteredThread(pid_t pid) { 149 mRegisteredClientThread = pid; 150 } 151 152 pid_t getRegisteredThread() const { 153 return mRegisteredClientThread; 154 } 155 156 int32_t getFramesPerBurst() const { 157 return mFramesPerBurst; 158 } 159 160 void run() override; // to implement Runnable 161 162 void disconnect(); 163 164 const android::AudioClient &getAudioClient() { 165 return mMmapClient; 166 } 167 168 uid_t getOwnerUserId() const { 169 return mMmapClient.clientUid; 170 } 171 172 pid_t getOwnerProcessId() const { 173 return mMmapClient.clientPid; 174 } 175 176 aaudio_handle_t getHandle() const { 177 return mHandle; 178 } 179 void setHandle(aaudio_handle_t handle) { 180 mHandle = handle; 181 } 182 183 audio_port_handle_t getPortHandle() const { 184 return mClientHandle; 185 } 186 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 */ 198 void setFlowing(bool b) { 199 mFlowing = b; 200 } 201 202 bool isFlowing() const { 203 return mFlowing; 204 } 205 206 /** 207 * Atomically increment the number of active references to the stream by AAudioService. 208 * 209 * This is called under a global lock in AAudioStreamTracker. 210 * 211 * @return value after the increment 212 */ 213 int32_t incrementServiceReferenceCount_l(); 214 215 /** 216 * Atomically decrement the number of active references to the stream by AAudioService. 217 * This should only be called after incrementServiceReferenceCount_l(). 218 * 219 * This is called under a global lock in AAudioStreamTracker. 220 * 221 * @return value after the decrement 222 */ 223 int32_t decrementServiceReferenceCount_l(); 224 225 bool isCloseNeeded() const { 226 return mCloseNeeded.load(); 227 } 228 229 /** 230 * Mark this stream as needing to be closed. 231 * Once marked for closing, it cannot be unmarked. 232 */ 233 void markCloseNeeded() { 234 mCloseNeeded.store(true); 235 } 236 237 virtual const char *getTypeText() const { return "Base"; } 238 239 protected: 240 241 /** 242 * Open the device. 243 */ 244 aaudio_result_t open(const aaudio::AAudioStreamRequest &request, 245 aaudio_sharing_mode_t sharingMode); 246 247 void setState(aaudio_stream_state_t state) { 248 mState = state; 249 } 250 251 /** 252 * Device specific startup. 253 * @return AAUDIO_OK or negative error. 254 */ 255 virtual aaudio_result_t startDevice(); 256 257 aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command); 258 259 aaudio_result_t sendCurrentTimestamp(); 260 261 aaudio_result_t sendXRunCount(int32_t xRunCount); 262 263 /** 264 * @param positionFrames 265 * @param timeNanos 266 * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error 267 */ 268 virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0; 269 270 virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0; 271 272 virtual aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) = 0; 273 274 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 275 276 pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID; 277 278 SharedRingBuffer* mUpMessageQueue; 279 std::mutex mUpMessageQueueLock; 280 281 AAudioThread mTimestampThread; 282 // This is used by one thread to tell another thread to exit. So it must be atomic. 283 std::atomic<bool> mThreadEnabled{false}; 284 285 int32_t mFramesPerBurst = 0; 286 android::AudioClient mMmapClient; // set in open, used in MMAP start() 287 // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger. 288 audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE; 289 290 SimpleDoubleBuffer<Timestamp> mAtomicTimestamp; 291 292 android::AAudioService &mAudioService; 293 294 // The mServiceEndpoint variable can be accessed by multiple threads. 295 // So we access it by locally promoting a weak pointer to a smart pointer, 296 // which is thread-safe. 297 android::sp<AAudioServiceEndpoint> mServiceEndpoint; 298 android::wp<AAudioServiceEndpoint> mServiceEndpointWeak; 299 300 private: 301 aaudio_handle_t mHandle = -1; 302 bool mFlowing = false; 303 304 // This is modified under a global lock in AAudioStreamTracker. 305 int32_t mCallingCount = 0; 306 307 std::atomic<bool> mCloseNeeded{false}; 308 }; 309 310 } /* namespace aaudio */ 311 312 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 313