Consolidate libaudioclient buffers p1

Prepare for libaudioclient buffer refactor by updating
clients of libaudioclient to use new buffer interface.

libaudioclient
- Wrap existing buffers with new interface
- Modify internal calls to be compatible with wrap

AAudio
- Update to use new buffer interface
- Update record to use callback

TrackPlayerBase
- Used for SLES (in different repo). Update to use sp<>

ToneGenerator/MediaPlayerService/AudioPlayer
- Update to use new buffer interface

StageFright
- Update to new callback interface
- Update to use new buffer interface

Bug: 216175830 - shared buffer
Bug: 199156212 - callback interface
Test: atest AudioTrackTest AudioRecordTest
atest AudioTrackOffloadTest
OboeTester non-exclusive, non-MMAP, power-saving for both
AAudio and SLES, input and output
No-Typo-Check: Existing class members

Change-Id: Ib1241f2e530bc509b2d4dde956ec5188f2287994
diff --git a/cmds/stagefright/AudioPlayer.cpp b/cmds/stagefright/AudioPlayer.cpp
index a63bde6..6cddf47 100644
--- a/cmds/stagefright/AudioPlayer.cpp
+++ b/cmds/stagefright/AudioPlayer.cpp
@@ -453,7 +453,7 @@
 }
 
 size_t AudioPlayer::onMoreData(const AudioTrack::Buffer& buffer) {
-    return fillBuffer(buffer.raw, buffer.size);
+    return fillBuffer(buffer.data(), buffer.size());
 }
 
 void AudioPlayer::onStreamEnd() {
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index 38f3c24..dd11169 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -76,6 +76,7 @@
     // This takes advantage of them killing the stream when they see a size out of range.
     // That is an undocumented behavior.
     // TODO add to API in AudioRecord and AudioTrack
+    // TODO(b/216175830) cleanup size re-computation
     const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
     aaudio_data_callback_result_t callbackResult;
     (void) checkForDisconnectRequest(true);
@@ -83,7 +84,7 @@
     // Note that this code assumes an AudioTrack::Buffer is the same as
     // AudioRecord::Buffer
     // TODO define our own AudioBuffer and pass it from the subclasses.
-    size_t written = buffer.size;
+    size_t written = buffer.size();
     if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
         ALOGW("%s() data, stream disconnected", __func__);
         // This will kill the stream and prevent it from being restarted.
@@ -96,23 +97,23 @@
         // caused by Legacy callbacks running after the track is "stopped".
         written = 0;
     } else {
-        if (buffer.frameCount == 0) {
+        if (buffer.getFrameCount() == 0) {
             ALOGW("%s() data, frameCount is zero", __func__);
             return written;
         }
 
         // If the caller specified an exact size then use a block size adapter.
         if (mBlockAdapter != nullptr) {
-            int32_t byteCount = buffer.frameCount * getBytesPerDeviceFrame();
+            int32_t byteCount = buffer.getFrameCount() * getBytesPerDeviceFrame();
             callbackResult = mBlockAdapter->processVariableBlock(
-                    static_cast<uint8_t*>(buffer.raw), byteCount);
+                    buffer.data(), byteCount);
         } else {
             // Call using the AAudio callback interface.
-            callbackResult = callDataCallbackFrames(static_cast<uint8_t *>(buffer.raw),
-                                                    buffer.frameCount);
+            callbackResult = callDataCallbackFrames(buffer.data(),
+                                                    buffer.getFrameCount());
         }
         if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
-            written = buffer.frameCount * getBytesPerDeviceFrame();
+            written = buffer.getFrameCount() * getBytesPerDeviceFrame();
         } else {
             if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
                 ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
@@ -134,6 +135,70 @@
     return written;
 }
 
+// TODO (b/216175830) this method is duplicated in order to ease refactoring which will
+// reconsolidate.
+size_t AudioStreamLegacy::onMoreData(const android::AudioRecord::Buffer& buffer) {
+    // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
+    // This takes advantage of them killing the stream when they see a size out of range.
+    // That is an undocumented behavior.
+    // TODO add to API in AudioRecord and AudioTrack
+    const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
+    aaudio_data_callback_result_t callbackResult;
+    (void) checkForDisconnectRequest(true);
+
+    // Note that this code assumes an AudioTrack::Buffer is the same as
+    // AudioRecord::Buffer
+    // TODO define our own AudioBuffer and pass it from the subclasses.
+    size_t written = buffer.size();
+    if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+        ALOGW("%s() data, stream disconnected", __func__);
+        // This will kill the stream and prevent it from being restarted.
+        // That is OK because the stream is disconnected.
+        written = SIZE_STOP_CALLBACKS;
+    } else if (!mCallbackEnabled.load()) {
+        ALOGW("%s() no data because callback disabled, set size=0", __func__);
+        // Do NOT use SIZE_STOP_CALLBACKS here because that will kill the stream and
+        // prevent it from being restarted. This can occur because of a race condition
+        // caused by Legacy callbacks running after the track is "stopped".
+        written = 0;
+    } else {
+        if (buffer.getFrameCount() == 0) {
+            ALOGW("%s() data, frameCount is zero", __func__);
+            return written;
+        }
+
+        // If the caller specified an exact size then use a block size adapter.
+        if (mBlockAdapter != nullptr) {
+            int32_t byteCount = buffer.getFrameCount() * getBytesPerDeviceFrame();
+            callbackResult = mBlockAdapter->processVariableBlock(
+                    buffer.data(), byteCount);
+        } else {
+            // Call using the AAudio callback interface.
+            callbackResult = callDataCallbackFrames(buffer.data(),
+                                                    buffer.getFrameCount());
+        }
+        if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
+            written = buffer.getFrameCount() * getBytesPerDeviceFrame();
+        } else {
+            if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
+                ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+            } else {
+                ALOGW("%s() callback returned invalid result = %d",
+                      __func__, callbackResult);
+            }
+            written = 0;
+            systemStopInternal();
+            // Disable the callback just in case the system keeps trying to call us.
+            mCallbackEnabled.store(false);
+        }
+
+        if (updateStateMachine() != AAUDIO_OK) {
+            forceDisconnect();
+            mCallbackEnabled.store(false);
+        }
+    }
+    return written;
+}
 
 aaudio_result_t AudioStreamLegacy::checkForDisconnectRequest(bool errorCallbackEnabled) {
     if (mRequestDisconnect.isRequested()) {
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.h b/media/libaaudio/src/legacy/AudioStreamLegacy.h
index c54d7e2..53f6e06 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.h
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.h
@@ -17,9 +17,10 @@
 #ifndef LEGACY_AUDIO_STREAM_LEGACY_H
 #define LEGACY_AUDIO_STREAM_LEGACY_H
 
+#include <media/AudioRecord.h>
+#include <media/AudioSystem.h>
 #include <media/AudioTimestamp.h>
 #include <media/AudioTrack.h>
-#include <media/AudioSystem.h>
 
 #include <aaudio/AAudio.h>
 
@@ -57,7 +58,8 @@
 
 class AudioStreamLegacy : public AudioStream,
                           public FixedBlockProcessor,
-                          protected android::AudioTrack::IAudioTrackCallback {
+                          protected android::AudioTrack::IAudioTrackCallback,
+                          protected android::AudioRecord::IAudioRecordCallback {
 public:
     AudioStreamLegacy();
 
@@ -82,7 +84,11 @@
 
 protected:
     size_t onMoreData(const android::AudioTrack::Buffer& buffer) override;
+    // TODO (b/216175830) this method is duplicated in order to ease refactoring which will
+    // reconsolidate.
+    size_t onMoreData(const android::AudioRecord::Buffer& buffer) override;
     void onNewIAudioTrack() override;
+    void onNewIAudioRecord() override { onNewIAudioTrack(); }
     aaudio_result_t getBestTimestamp(clockid_t clockId,
                                      int64_t *framePosition,
                                      int64_t *timeNanoseconds,
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index df7d4cf..988d097 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -37,10 +37,6 @@
 using namespace android;
 using namespace aaudio;
 
-static void sCallbackWrapper(int event, void* userData, void* info) {
-    static_cast<AudioStreamRecord*>(userData)->processCallback(event, info);
-}
-
 AudioStreamRecord::AudioStreamRecord()
     : AudioStreamLegacy()
     , mFixedBlockWriter(*this)
@@ -128,13 +124,11 @@
     uint32_t notificationFrames = 0;
 
     // Setup the callback if there is one.
-    AudioRecord::legacy_callback_t callback = nullptr;
-    void *callbackData = nullptr;
+    sp<AudioRecord::IAudioRecordCallback> callback;
     AudioRecord::transfer_type streamTransferType = AudioRecord::transfer_type::TRANSFER_SYNC;
     if (builder.getDataCallbackProc() != nullptr) {
         streamTransferType = AudioRecord::transfer_type::TRANSFER_CALLBACK;
-        callback = sCallbackWrapper;
-        callbackData = this;
+        callback = sp<AudioRecord::IAudioRecordCallback>::fromExisting(this);
     }
     mCallbackBufferSize = builder.getFramesPerDataCallback();
 
@@ -181,7 +175,6 @@
                 channelMask,
                 frameCount,
                 callback,
-                callbackData,
                 notificationFrames,
                 false /*threadCanCallJava*/,
                 sessionId,
@@ -354,24 +347,6 @@
     }
 }
 
-void AudioStreamRecord::processCallback(int event, void *info) {
-    switch (event) {
-        case AudioRecord::EVENT_MORE_DATA:
-        {
-            AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
-            audioBuffer->size = onMoreData(*audioBuffer);
-            break;
-        }
-            // Stream got rerouted so we disconnect.
-        case AudioRecord::EVENT_NEW_IAUDIORECORD:
-            onNewIAudioTrack();
-            break;
-        default:
-            break;
-    }
-    return;
-}
-
 aaudio_result_t AudioStreamRecord::requestStart_l()
 {
     if (mAudioRecord.get() == nullptr) {
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index ebd488a..0c37fb5 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -266,7 +266,7 @@
     size_t onMoreData(const AudioRecord::Buffer& buffer) override {
         AudioRecord::Buffer copy = buffer;
         mCallback(AudioRecord::EVENT_MORE_DATA, mData, &copy);
-        return copy.size;
+        return copy.size();
     }
 
     void onOverrun() override { mCallback(AudioRecord::EVENT_OVERRUN, mData, nullptr); }
@@ -1131,7 +1131,7 @@
     }
     if (mTransfer != TRANSFER_OBTAIN) {
         audioBuffer->frameCount = 0;
-        audioBuffer->size = 0;
+        audioBuffer->mSize = 0;
         audioBuffer->raw = NULL;
         if (nonContig != NULL) {
             *nonContig = 0;
@@ -1214,7 +1214,7 @@
     } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
 
     audioBuffer->frameCount = buffer.mFrameCount;
-    audioBuffer->size = buffer.mFrameCount * mServerFrameSize;
+    audioBuffer->mSize = buffer.mFrameCount * mServerFrameSize;
     audioBuffer->raw = buffer.mRaw;
     audioBuffer->sequence = oldSequence;
     if (nonContig != NULL) {
@@ -1291,7 +1291,7 @@
 
         size_t bytesRead = audioBuffer.frameCount * mFrameSize;
         memcpy_by_audio_format(buffer, mFormat, audioBuffer.raw, mServerConfig.format,
-                               audioBuffer.size / mServerSampleSize);
+                               audioBuffer.mSize / mServerSampleSize);
         buffer = ((char *) buffer) + bytesRead;
         userSize -= bytesRead;
         read += bytesRead;
@@ -1497,15 +1497,15 @@
         if (mServerConfig.format != mFormat) {
             buffer = &mFormatConversionBuffer;
             buffer->frameCount = audioBuffer.frameCount;
-            buffer->size = buffer->frameCount * mFrameSize;
+            buffer->mSize = buffer->frameCount * mFrameSize;
             buffer->sequence = audioBuffer.sequence;
             memcpy_by_audio_format(buffer->raw, mFormat, audioBuffer.raw,
-                                   mServerConfig.format, audioBuffer.size / mServerSampleSize);
+                                   mServerConfig.format, audioBuffer.size() / mServerSampleSize);
         }
 
-        const size_t reqSize = buffer->size;
+        const size_t reqSize = buffer->size();
         const size_t readSize = callback->onMoreData(*buffer);
-        buffer->size = readSize;
+        buffer->mSize = readSize;
 
         // Validate on returned size
         if (ssize_t(readSize) < 0 || readSize > reqSize) {
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index bdf3147..919d6d2 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -293,7 +293,7 @@
         size_t onMoreData(const AudioTrack::Buffer & buffer) override {
           AudioTrack::Buffer copy = buffer;
           mCallback(AudioTrack::EVENT_MORE_DATA, mData, static_cast<void*>(&copy));
-          return copy.size;
+          return copy.size();
         }
         void onUnderrun() override {
             mCallback(AudioTrack::EVENT_UNDERRUN, mData, nullptr);
@@ -319,7 +319,7 @@
         size_t onCanWriteMoreData(const AudioTrack::Buffer & buffer) override {
           AudioTrack::Buffer copy = buffer;
           mCallback(AudioTrack::EVENT_CAN_WRITE_MORE_DATA, mData, static_cast<void*>(&copy));
-          return copy.size;
+          return copy.size();
         }
     };
 }
@@ -2194,7 +2194,7 @@
     }
     if (mTransfer != TRANSFER_OBTAIN) {
         audioBuffer->frameCount = 0;
-        audioBuffer->size = 0;
+        audioBuffer->mSize = 0;
         audioBuffer->raw = NULL;
         if (nonContig != NULL) {
             *nonContig = 0;
@@ -2286,7 +2286,7 @@
     } while (((status == DEAD_OBJECT) || (status == NOT_ENOUGH_DATA)) && (tryCounter-- > 0));
 
     audioBuffer->frameCount = buffer.mFrameCount;
-    audioBuffer->size = buffer.mFrameCount * mFrameSize;
+    audioBuffer->mSize = buffer.mFrameCount * mFrameSize;
     audioBuffer->raw = buffer.mRaw;
     audioBuffer->sequence = oldSequence;
     if (nonContig != NULL) {
@@ -2302,7 +2302,7 @@
         return;
     }
 
-    size_t stepCount = audioBuffer->size / mFrameSize;
+    size_t stepCount = audioBuffer->mSize / mFrameSize;
     if (stepCount == 0) {
         return;
     }
@@ -2382,8 +2382,8 @@
             return ssize_t(err);
         }
 
-        size_t toWrite = audioBuffer.size;
-        memcpy(audioBuffer.i8, buffer, toWrite);
+        size_t toWrite = audioBuffer.size();
+        memcpy(audioBuffer.raw, buffer, toWrite);
         buffer = ((const char *) buffer) + toWrite;
         userSize -= toWrite;
         written += toWrite;
@@ -2740,11 +2740,11 @@
             }
         }
 
-        size_t reqSize = audioBuffer.size;
+        size_t reqSize = audioBuffer.size();
         if (mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK) {
             // when notifying client it can write more data, pass the total size that can be
             // written in the next write() call, since it's not passed through the callback
-            audioBuffer.size += nonContig;
+            audioBuffer.mSize += nonContig;
         }
         const size_t writtenSize = (mTransfer == TRANSFER_CALLBACK)
                                       ? callback->onMoreData(audioBuffer)
@@ -2809,7 +2809,7 @@
         }
 
         // releaseBuffer reads from audioBuffer.size
-        audioBuffer.size = writtenSize;
+        audioBuffer.mSize = writtenSize;
 
         size_t releasedFrames = writtenSize / mFrameSize;
         audioBuffer.frameCount = releasedFrames;
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index cd3eacb..9b43f3c 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -1329,7 +1329,7 @@
 //
 //    Input:
 //        buffer  An buffer object containing a pointer which we will fill with
-//                buffer.size bytes.
+//                buffer.size() bytes.
 //
 //    Output:
 //        The number of bytes we successfully wrote.
@@ -1337,16 +1337,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 size_t ToneGenerator::onMoreData(const AudioTrack::Buffer& buffer) {
 
-    int16_t *lpOut = buffer.i16;
-    uint32_t lNumSmp = (buffer.size / sizeof(int16_t) < UINT32_MAX) ?
-            buffer.size / sizeof(int16_t) : UINT32_MAX;
-    if (buffer.size == 0) return 0;
+    int16_t *lpOut = reinterpret_cast<int16_t*>(buffer.data());
+    uint32_t lNumSmp = (buffer.size() / sizeof(int16_t) < UINT32_MAX) ?
+            buffer.size() / sizeof(int16_t) : UINT32_MAX;
+    if (buffer.size() == 0) return 0;
     // We will write to the entire buffer unless we are stopped, then we return
     // 0 at loop end
     size_t bytesWritten = lNumSmp * sizeof(int16_t);
 
     // Clear output buffer: WaveGenerator accumulates into lpOut buffer
-    memset(lpOut, 0, buffer.size);
+    memset(lpOut, 0, buffer.size());
 
     while (lNumSmp) {
         unsigned int lReqSmp = lNumSmp < mProcessSize*2 ? lNumSmp : mProcessSize;
diff --git a/media/libaudioclient/TrackPlayerBase.cpp b/media/libaudioclient/TrackPlayerBase.cpp
index 188f321..4fc1c44 100644
--- a/media/libaudioclient/TrackPlayerBase.cpp
+++ b/media/libaudioclient/TrackPlayerBase.cpp
@@ -33,11 +33,14 @@
     doDestroy();
 }
 
-void TrackPlayerBase::init(AudioTrack* pat, player_type_t playerType, audio_usage_t usage,
-        audio_session_t sessionId) {
+void TrackPlayerBase::init(const sp<AudioTrack>& pat,
+                           const sp<AudioTrack::IAudioTrackCallback>& callback,
+                           player_type_t playerType, audio_usage_t usage,
+                           audio_session_t sessionId) {
     PlayerBase::init(playerType, usage, sessionId);
     mAudioTrack = pat;
     if (mAudioTrack != 0) {
+        mCallbackHandle = callback;
         mSelfAudioDeviceCallback = new SelfAudioDeviceCallback(*this);
         mAudioTrack->addAudioDeviceCallback(mSelfAudioDeviceCallback);
         mAudioTrack->setPlayerIId(mPIId); // set in PlayerBase::init().
diff --git a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
index 4c89249..169a6a7 100644
--- a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
+++ b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
@@ -355,7 +355,7 @@
     audioBuffer.frameCount = static_cast<size_t>(mFdp.ConsumeIntegral<uint32_t>());
     record->obtainBuffer(&audioBuffer, waitCount, &nonContig);
     bool blocking = false;
-    record->read(audioBuffer.raw, audioBuffer.size, blocking);
+    record->read(audioBuffer.data(), audioBuffer.size(), blocking);
     record->getInputFramesLost();
     record->getFlags();
 
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 3cfcbf3..faea716 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -40,7 +40,6 @@
 
 struct audio_track_cblk_t;
 class AudioRecordClientProxy;
-
 // ----------------------------------------------------------------------------
 
 class AudioRecord : public AudioSystem::AudioDeviceCallback
@@ -70,15 +69,21 @@
 
     class Buffer
     {
+      friend AudioRecord;
     public:
-        // FIXME use m prefix
+        size_t size() const { return mSize; }
+        size_t getFrameCount() const { return frameCount; }
+        uint8_t* data() const { return ui8; }
+        // Leaving public for now to assist refactoring. This class will
+        // be replaced.
         size_t      frameCount;     // number of sample frames corresponding to size;
                                     // on input to obtainBuffer() it is the number of frames desired
                                     // on output from obtainBuffer() it is the number of available
                                     //    frames to be read
                                     // on input to releaseBuffer() it is currently ignored
 
-        size_t      size;           // input/output in bytes == frameCount * frameSize
+    private:
+        size_t      mSize;          // input/output in bytes == frameCount * frameSize
                                     // on input to obtainBuffer() it is ignored
                                     // on output from obtainBuffer() it is the number of available
                                     //    bytes to be read, which is frameCount * frameSize
@@ -90,7 +95,7 @@
         union {
             void*       raw;
             int16_t*    i16;        // signed 16-bit
-            int8_t*     i8;         // unsigned 8-bit, offset by 0x80
+            uint8_t*    ui8;        // unsigned 8-bit, offset by 0x80
                                     // input to obtainBuffer(): unused, output: pointer to buffer
         };
 
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 16e10b5..d777124 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -95,34 +95,36 @@
 
     class Buffer
     {
+    friend AudioTrack;
     public:
-        // FIXME use m prefix
+       size_t size() const { return mSize; }
+       size_t getFrameCount() const { return frameCount; }
+       uint8_t * data() const { return ui8; }
+       // Leaving public for now to ease refactoring. This class will be
+       // replaced
         size_t      frameCount;   // number of sample frames corresponding to size;
                                   // on input to obtainBuffer() it is the number of frames desired,
                                   // on output from obtainBuffer() it is the number of available
                                   //    [empty slots for] frames to be filled
                                   // on input to releaseBuffer() it is currently ignored
-
-        size_t      size;         // input/output in bytes == frameCount * frameSize
+    private:
+        size_t      mSize;        // input/output in bytes == frameCount * frameSize
                                   // on input to obtainBuffer() it is ignored
                                   // on output from obtainBuffer() it is the number of available
                                   //    [empty slots for] bytes to be filled,
                                   //    which is frameCount * frameSize
                                   // on input to releaseBuffer() it is the number of bytes to
                                   //    release
-                                  // FIXME This is redundant with respect to frameCount.  Consider
-                                  //    removing size and making frameCount the primary field.
 
         union {
             void*       raw;
             int16_t*    i16;      // signed 16-bit
-            int8_t*     i8;       // unsigned 8-bit, offset by 0x80
+            uint8_t*    ui8;      // unsigned 8-bit, offset by 0x80
         };                        // input to obtainBuffer(): unused, output: pointer to buffer
 
         uint32_t    sequence;       // IAudioTrack instance sequence number, as of obtainBuffer().
                                     // It is set by obtainBuffer() and confirmed by releaseBuffer().
                                     // Not "user-serviceable".
-                                    // TODO Consider sp<IMemory> instead, or in addition to this.
     };
 
     /* As a convenience, if a callback is supplied, a handler thread
diff --git a/media/libaudioclient/include/media/TrackPlayerBase.h b/media/libaudioclient/include/media/TrackPlayerBase.h
index 80124b8..fe88116 100644
--- a/media/libaudioclient/include/media/TrackPlayerBase.h
+++ b/media/libaudioclient/include/media/TrackPlayerBase.h
@@ -28,8 +28,8 @@
     explicit TrackPlayerBase();
     virtual ~TrackPlayerBase();
 
-            void init(AudioTrack* pat, player_type_t playerType, audio_usage_t usage,
-                    audio_session_t sessionId);
+    void init(const sp<AudioTrack>& pat, const sp<AudioTrack::IAudioTrackCallback>& callback,
+              player_type_t playerType, audio_usage_t usage, audio_session_t sessionId);
     virtual void destroy();
 
     //IPlayer implementation
@@ -66,8 +66,8 @@
 
     // volume coming from the player volume API
     float mPlayerVolumeL, mPlayerVolumeR;
-
-   sp<SelfAudioDeviceCallback> mSelfAudioDeviceCallback;
+    sp<AudioTrack::IAudioTrackCallback> mCallbackHandle;
+    sp<SelfAudioDeviceCallback> mSelfAudioDeviceCallback;
 };
 
 } // namespace android
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index c7a7a3a..b512982 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -2658,7 +2658,7 @@
         return 0;
     }
     size_t actualSize = (*me->mCallback)(
-            me.get(), buffer.raw, buffer.size, me->mCallbackCookie,
+            me.get(), buffer.data(), buffer.size(), me->mCallbackCookie,
             CB_EVENT_FILL_BUFFER);
 
     // Log when no data is returned from the callback.
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index b6acdc8..faaae3f 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -36,21 +36,9 @@
 
 using content::AttributionSourceState;
 
-static void AudioRecordCallbackFunction(int event, void *user, void *info) {
-    AudioSource *source = (AudioSource *) user;
-    switch (event) {
-        case AudioRecord::EVENT_MORE_DATA: {
-            source->dataCallback(*((AudioRecord::Buffer *) info));
-            break;
-        }
-        case AudioRecord::EVENT_OVERRUN: {
-            ALOGW("AudioRecord reported overrun!");
-            break;
-        }
-        default:
-            // does nothing
-            break;
-    }
+
+void AudioSource::onOverrun() {
+    ALOGW("AudioRecord reported overrun!");
 }
 
 AudioSource::AudioSource(
@@ -129,8 +117,7 @@
         audio_channel_in_mask_from_count(channelCount),
         attributionSource,
         (size_t) (bufCount * frameCount),
-        AudioRecordCallbackFunction,
-        this,
+        wp<AudioRecord::IAudioRecordCallback>::fromExisting(this),
         frameCount /*notificationFrames*/,
         AUDIO_SESSION_ALLOCATE,
         AudioRecord::TRANSFER_DEFAULT,
@@ -359,7 +346,7 @@
     return;
 }
 
-status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
+size_t AudioSource::onMoreData(const AudioRecord::Buffer& audioBuffer) {
     int64_t timeUs, position, timeNs;
     ExtendedTimestamp ts;
     ExtendedTimestamp::Location location;
@@ -384,21 +371,21 @@
 
     ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
     Mutex::Autolock autoLock(mLock);
+
     if (!mStarted) {
         ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
-        return OK;
+        return audioBuffer.size();
     }
 
-    const size_t bufferSize = audioBuffer.size;
 
     // Drop retrieved and previously lost audio data.
     if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
         (void) mRecord->getInputFramesLost();
-        int64_t receievedFrames = bufferSize / mRecord->frameSize();
+        int64_t receievedFrames = audioBuffer.size() / mRecord->frameSize();
         ALOGV("Drop audio data(%" PRId64 " frames) at %" PRId64 "/%" PRId64 " us",
                 receievedFrames, timeUs, mStartTimeUs);
         mNumFramesSkipped += receievedFrames;
-        return OK;
+        return audioBuffer.size();
     }
 
     if (mStopSystemTimeUs != -1 && timeUs >= mStopSystemTimeUs) {
@@ -406,7 +393,7 @@
                 (long long)timeUs, (long long)mStopSystemTimeUs);
         mNoMoreFramesToRead = true;
         mFrameAvailableCondition.signal();
-        return OK;
+        return audioBuffer.size();
     }
 
     if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
@@ -427,7 +414,7 @@
     }
 
     CHECK_EQ(numLostBytes & 1, 0u);
-    CHECK_EQ(audioBuffer.size & 1, 0u);
+    CHECK_EQ(audioBuffer.size() & 1, 0u);
     if (numLostBytes > 0) {
         // Loss of audio frames should happen rarely; thus the LOGW should
         // not cause a logging spam
@@ -449,17 +436,17 @@
         queueInputBuffer_l(lostAudioBuffer, timeUs);
     }
 
-    if (audioBuffer.size == 0) {
+    if (audioBuffer.size() == 0) {
         ALOGW("Nothing is available from AudioRecord callback buffer");
-        return OK;
+        return audioBuffer.size();
     }
 
-    MediaBuffer *buffer = new MediaBuffer(bufferSize);
+    MediaBuffer *buffer = new MediaBuffer(audioBuffer.size());
     memcpy((uint8_t *) buffer->data(),
-            audioBuffer.i16, audioBuffer.size);
-    buffer->set_range(0, bufferSize);
+            audioBuffer.data(), audioBuffer.size());
+    buffer->set_range(0, audioBuffer.size());
     queueInputBuffer_l(buffer, timeUs);
-    return OK;
+    return audioBuffer.size();
 }
 
 void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
diff --git a/media/libstagefright/include/media/stagefright/AudioSource.h b/media/libstagefright/include/media/stagefright/AudioSource.h
index 43d50f1..5e84977 100644
--- a/media/libstagefright/include/media/stagefright/AudioSource.h
+++ b/media/libstagefright/include/media/stagefright/AudioSource.h
@@ -35,7 +35,9 @@
 
 class AudioRecord;
 
-struct AudioSource : public MediaSource, public MediaBufferObserver {
+struct AudioSource : public MediaSource,
+                     public MediaBufferObserver,
+                     public AudioRecord::IAudioRecordCallback {
     // Note that the "channels" parameter _is_ the number of channels,
     // _not_ a bitmask of audio_channels_t constants.
     AudioSource(
@@ -74,7 +76,6 @@
             MediaBufferBase **buffer, const ReadOptions *options = NULL);
     virtual status_t setStopTimeUs(int64_t stopTimeUs);
 
-    status_t dataCallback(const AudioRecord::Buffer& buffer);
     virtual void signalBufferReturned(MediaBufferBase *buffer);
 
     status_t setInputDevice(audio_port_handle_t deviceId);
@@ -142,6 +143,10 @@
     void waitOutstandingEncodingFrames_l();
     status_t reset();
 
+    // IAudioRecordCallback implementation
+    size_t onMoreData(const AudioRecord::Buffer&) override;
+    void onOverrun() override;
+
     AudioSource(const AudioSource &);
     AudioSource &operator=(const AudioSource &);