Home | History | Annotate | Download | only in oboeservice
      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      * 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      */
    212     void setSuspended(bool suspended) {
    213         mSuspended = suspended;
    214     }
    215 
    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 
    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      */
    247     void markCloseNeeded() {
    248         mCloseNeeded.store(true);
    249     }
    250 
    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 
    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