refactor code for updating frame counters

Use virtual close().
Add updateFramesRead() and ...Written()
diff --git a/include/oboe/AudioStream.h b/include/oboe/AudioStream.h
index 894db84..b6c8d10 100644
--- a/include/oboe/AudioStream.h
+++ b/include/oboe/AudioStream.h
@@ -66,7 +66,7 @@
     /**
      * Close the stream and deallocate any resources from the open() call.
      */
-    virtual Result close() = 0;
+    virtual Result close();
 
     /**
      * Start the stream. This will block until the stream has been started, an error occurs
@@ -229,7 +229,7 @@
      *
      * @return the number of frames written so far
      */
-    virtual int64_t getFramesWritten() { return mFramesWritten; }
+    virtual int64_t getFramesWritten();
 
     /**
      * The number of audio frames read from the stream.
@@ -237,7 +237,7 @@
      *
      * @return the number of frames read so far
      */
-    virtual int64_t getFramesRead() { return mFramesRead; }
+    virtual int64_t getFramesRead();
 
     /**
      * Calculate the latency of a stream based on getTimestamp().
@@ -396,6 +396,16 @@
     AudioFormat mNativeFormat = AudioFormat::Invalid;
 
     /**
+     * Update mFramesWritten.
+     */
+    virtual void updateFramesWritten() = 0;
+
+    /**
+     * Update mFramesRead.
+     */
+    virtual void updateFramesRead() = 0;
+
+    /**
      * Number of frames which have been written into the stream
      *
      * TODO these should be atomic like in AAudio
diff --git a/src/aaudio/AudioStreamAAudio.cpp b/src/aaudio/AudioStreamAAudio.cpp
index 1a233a6..953cf43 100644
--- a/src/aaudio/AudioStreamAAudio.cpp
+++ b/src/aaudio/AudioStreamAAudio.cpp
@@ -228,9 +228,7 @@
     // which could otherwise cause the requestStop() to crash.
     std::lock_guard<std::mutex> lock(mLock);
 
-    // Update frame counter variables to avoid retrograde motion.
-    getFramesWritten();
-    getFramesRead();
+    AudioStream::close();
 
     // This will delete the AAudio stream object so we need to null out the pointer.
     AAudioStream *stream = mAAudioStream.exchange(nullptr);
@@ -443,20 +441,18 @@
     return mFramesPerBurst;
 }
 
-int64_t AudioStreamAAudio::getFramesRead() {
+void AudioStreamAAudio::updateFramesRead() {
     AAudioStream *stream = mAAudioStream.load();
     if (stream != nullptr) {
         mFramesRead = mLibLoader->stream_getFramesRead(stream);
     }
-    return mFramesRead;
 }
 
-int64_t AudioStreamAAudio::getFramesWritten() {
+void AudioStreamAAudio::updateFramesWritten() {
     AAudioStream *stream = mAAudioStream.load();
     if (stream != nullptr) {
         mFramesWritten = mLibLoader->stream_getFramesWritten(stream);
     }
-    return mFramesWritten;
 }
 
 ResultWithValue<int32_t> AudioStreamAAudio::getXRunCount() const {
diff --git a/src/aaudio/AudioStreamAAudio.h b/src/aaudio/AudioStreamAAudio.h
index 5f5aeff..f9a4c47 100644
--- a/src/aaudio/AudioStreamAAudio.h
+++ b/src/aaudio/AudioStreamAAudio.h
@@ -74,9 +74,6 @@
     ResultWithValue<int32_t> getXRunCount() const override;
     bool isXRunCountSupported() const override { return true; }
 
-    int64_t getFramesRead() override;
-    int64_t getFramesWritten() override;
-
     ResultWithValue<double> calculateLatencyMillis() override;
 
     Result waitForStateChange(StreamState currentState,
@@ -109,6 +106,9 @@
 protected:
     Result convertApplicationDataToNative(int32_t numFrames); // TODO remove?
 
+    void updateFramesRead() override;
+    void updateFramesWritten() override;
+
 private:
 
     float               *mFloatCallbackBuffer;
diff --git a/src/common/AudioStream.cpp b/src/common/AudioStream.cpp
index d750460..0673512 100644
--- a/src/common/AudioStream.cpp
+++ b/src/common/AudioStream.cpp
@@ -34,6 +34,13 @@
     return Result::OK;
 }
 
+Result AudioStream::close() {
+    // Update local counters so they can be read after the close.
+    updateFramesWritten();
+    updateFramesRead();
+    return Result::OK;
+}
+
 DataCallbackResult AudioStream::fireCallback(void *audioData, int32_t numFrames) {
     int scheduler = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK; // for current thread
     if (scheduler != mPreviousScheduler) {
@@ -119,4 +126,14 @@
     return convertFormatToSizeInBytes(mFormat);
 }
 
+int64_t AudioStream::getFramesRead() {
+    updateFramesRead();
+    return mFramesRead;
+}
+
+int64_t AudioStream::getFramesWritten() {
+    updateFramesWritten();
+    return mFramesWritten;
+}
+
 } // namespace oboe
\ No newline at end of file
diff --git a/src/opensles/AudioInputStreamOpenSLES.cpp b/src/opensles/AudioInputStreamOpenSLES.cpp
index 50fd715..1606da3 100644
--- a/src/opensles/AudioInputStreamOpenSLES.cpp
+++ b/src/opensles/AudioInputStreamOpenSLES.cpp
@@ -282,12 +282,11 @@
     return result;
 }
 
-int64_t AudioInputStreamOpenSLES::getFramesWritten() {
+void AudioInputStreamOpenSLES::updateFramesWritten() {
     if (usingFIFO()) {
-        return AudioStreamBuffered::getFramesWritten();
+        AudioStreamBuffered::updateFramesWritten();
     } else {
         mFramesWritten = getFramesProcessedByServer();
-        return mFramesWritten;
     }
 }
 
diff --git a/src/opensles/AudioInputStreamOpenSLES.h b/src/opensles/AudioInputStreamOpenSLES.h
index 7837a30..bf88ad9 100644
--- a/src/opensles/AudioInputStreamOpenSLES.h
+++ b/src/opensles/AudioInputStreamOpenSLES.h
@@ -45,12 +45,12 @@
     Result requestFlush() override;
     Result requestStop() override;
 
-    int64_t getFramesWritten() override;
-
 protected:
 
     Result updateServiceFrameCounter() override;
 
+    void updateFramesWritten() override;
+
 private:
 
     SLuint32 channelCountToChannelMask(int chanCount);
diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp
index 7c33632..9a54760 100644
--- a/src/opensles/AudioOutputStreamOpenSLES.cpp
+++ b/src/opensles/AudioOutputStreamOpenSLES.cpp
@@ -318,12 +318,11 @@
     mPositionMillis.set(millisWritten);
 }
 
-int64_t AudioOutputStreamOpenSLES::getFramesRead() {
+void AudioOutputStreamOpenSLES::updateFramesRead() {
     if (usingFIFO()) {
-        return AudioStreamBuffered::getFramesRead();
+        AudioStreamBuffered::updateFramesRead();
     } else {
         mFramesRead = getFramesProcessedByServer();
-        return mFramesRead;
     }
 }
 
diff --git a/src/opensles/AudioOutputStreamOpenSLES.h b/src/opensles/AudioOutputStreamOpenSLES.h
index f5735b4..ea0ba8c 100644
--- a/src/opensles/AudioOutputStreamOpenSLES.h
+++ b/src/opensles/AudioOutputStreamOpenSLES.h
@@ -44,14 +44,14 @@
     Result requestFlush() override;
     Result requestStop() override;
 
-    int64_t getFramesRead() override;
-
 protected:
 
     void setFramesRead(int64_t framesRead);
 
     Result updateServiceFrameCounter() override;
 
+    void updateFramesRead() override;
+
 private:
 
     SLuint32 channelCountToChannelMask(int chanCount);
diff --git a/src/opensles/AudioStreamBuffered.cpp b/src/opensles/AudioStreamBuffered.cpp
index 656003e..9fbf457 100644
--- a/src/opensles/AudioStreamBuffered.cpp
+++ b/src/opensles/AudioStreamBuffered.cpp
@@ -43,22 +43,20 @@
             mBufferCapacityInFrames = capacity;
         }
         // TODO consider using std::make_unique if we require c++14
-        mFifoBuffer.reset( new FifoBuffer(getBytesPerFrame(), capacity));
+        mFifoBuffer.reset(new FifoBuffer(getBytesPerFrame(), capacity));
     }
 }
 
-int64_t AudioStreamBuffered::getFramesWritten() {
+void AudioStreamBuffered::updateFramesWritten() {
     if (mFifoBuffer) {
         mFramesWritten = static_cast<int64_t>(mFifoBuffer->getWriteCounter());
-    }
-    return mFramesWritten;
+    } // or else it will get updated by processBufferCallback()
 }
 
-int64_t AudioStreamBuffered::getFramesRead() {
+void AudioStreamBuffered::updateFramesRead() {
     if (mFifoBuffer) {
         mFramesRead = static_cast<int64_t>(mFifoBuffer->getReadCounter());
-    }
-    return mFramesRead;
+    } // or else it will get updated by processBufferCallback()
 }
 
 // This is called by the OpenSL ES callback to read or write the back end of the FIFO.
diff --git a/src/opensles/AudioStreamBuffered.h b/src/opensles/AudioStreamBuffered.h
index 9eb3f8f..634ddf7 100644
--- a/src/opensles/AudioStreamBuffered.h
+++ b/src/opensles/AudioStreamBuffered.h
@@ -57,10 +57,6 @@
 
     bool isXRunCountSupported() const override;
 
-    int64_t getFramesWritten() override;
-
-    int64_t getFramesRead() override;
-
 protected:
 
     DataCallbackResult onDefaultCallback(void *audioData, int numFrames) override;
@@ -70,6 +66,9 @@
 
     virtual Result updateServiceFrameCounter() { return Result::OK; };
 
+    void updateFramesRead() override;
+    void updateFramesWritten() override;
+
 private:
 
     int64_t predictNextCallbackTime();
@@ -83,7 +82,7 @@
         mXRunCount++;
     }
 
-    std::unique_ptr<FifoBuffer>                  mFifoBuffer{};
+    std::unique_ptr<FifoBuffer>   mFifoBuffer{};
 
     int64_t mBackgroundRanAtNanoseconds = 0;
     int32_t mLastBackgroundSize = 0;
diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp
index cef4d5d..d6f40c5 100644
--- a/src/opensles/AudioStreamOpenSLES.cpp
+++ b/src/opensles/AudioStreamOpenSLES.cpp
@@ -216,9 +216,7 @@
     if (mState == StreamState::Closed){
         return Result::ErrorClosed;
     } else {
-        // Update frame counter variables so they can be read after close.
-        getFramesWritten();
-        getFramesRead();
+        AudioStreamBuffered::close();
 
         onBeforeDestroy();
 
diff --git a/src/opensles/AudioStreamOpenSLES.h b/src/opensles/AudioStreamOpenSLES.h
index 0d2b838..839e11a 100644
--- a/src/opensles/AudioStreamOpenSLES.h
+++ b/src/opensles/AudioStreamOpenSLES.h
@@ -114,10 +114,9 @@
     uint8_t              *mCallbackBuffer = nullptr;
     int32_t               mBytesPerCallback = oboe::kUnspecified;
     int32_t               mFramesPerBurst = 0;
-    int32_t               mBurstsPerBuffer = 2; // Double buffered
     StreamState           mState = StreamState::Uninitialized;
 
-    MonotonicCounter  mPositionMillis; // for tracking OpenSL ES service position
+    MonotonicCounter      mPositionMillis; // for tracking OpenSL ES service position
 };
 
 } // namespace oboe