MediaPlayer2: use ANativeWindow to replace Surface and IGraphicBufferProducer

Test: MediaPlayer2 plays video files
Bug: 63934228
Change-Id: Id655aa19125cfc5554dbf36c223d0a27318ebb24
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index d18f611..0b4fd25 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -246,6 +246,7 @@
         "IStreamSource.cpp",
         "MediaUtils.cpp",
         "Metadata.cpp",
+        "NdkWrapper.cpp",
     ],
 
     shared_libs: [
@@ -254,6 +255,8 @@
         "libgui",
         "liblog",
         "libmediaextractor",
+        "libmediandk",
+        "libnativewindow",
         "libstagefright_foundation",
         "libui",
         "libutils",
@@ -261,6 +264,7 @@
 
     export_shared_lib_headers: [
         "libbinder",
+        "libmediandk",
     ],
 
     header_libs: [
@@ -328,6 +332,7 @@
         "libmediandk",
         "libmediautils",
         "libmemunreachable",
+        "libnativewindow",
         "libpowermanager",
         "libstagefright_httplive",
         "libstagefright_player2",
diff --git a/media/libmedia/MediaPlayer2Manager.cpp b/media/libmedia/MediaPlayer2Manager.cpp
index 637214e..c6ad99e 100644
--- a/media/libmedia/MediaPlayer2Manager.cpp
+++ b/media/libmedia/MediaPlayer2Manager.cpp
@@ -38,7 +38,6 @@
 #include <binder/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
-#include <gui/Surface.h>
 #include <utils/Errors.h>  // for status_t
 #include <utils/String8.h>
 #include <utils/SystemClock.h>
@@ -52,6 +51,8 @@
 #include <media/Metadata.h>
 #include <media/AudioTrack.h>
 #include <media/MemoryLeakTrackUtil.h>
+#include <media/NdkWrapper.h>
+
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaErrors.h>
@@ -737,9 +738,9 @@
 }
 
 void MediaPlayer2Manager::Client::disconnectNativeWindow_l() {
-    if (mConnectedWindow != NULL) {
+    if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
         status_t err = nativeWindowDisconnect(
-                mConnectedWindow.get(), "disconnectNativeWindow");
+                mConnectedWindow->getANativeWindow(), "disconnectNativeWindow");
 
         if (err != OK) {
             ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
@@ -750,21 +751,20 @@
 }
 
 status_t MediaPlayer2Manager::Client::setVideoSurfaceTexture(
-        const sp<IGraphicBufferProducer>& bufferProducer)
+        const sp<ANativeWindowWrapper>& nww)
 {
-    ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get());
+    ALOGV("[%d] setVideoSurfaceTexture(%p)",
+          mConnId,
+          (nww == NULL ? NULL : nww->getANativeWindow()));
     sp<MediaPlayer2Base> p = getPlayer();
     if (p == 0) return UNKNOWN_ERROR;
 
-    sp<IBinder> binder(IInterface::asBinder(bufferProducer));
-    if (mConnectedWindowBinder == binder) {
-        return OK;
-    }
-
-    sp<ANativeWindow> anw;
-    if (bufferProducer != NULL) {
-        anw = new Surface(bufferProducer, true /* controlledByApp */);
-        status_t err = nativeWindowConnect(anw.get(), "setVideoSurfaceTexture");
+    if (nww != NULL && nww->getANativeWindow() != NULL) {
+        if (mConnectedWindow != NULL
+            && mConnectedWindow->getANativeWindow() == nww->getANativeWindow()) {
+            return OK;
+        }
+        status_t err = nativeWindowConnect(nww->getANativeWindow(), "setVideoSurfaceTexture");
 
         if (err != OK) {
             ALOGE("setVideoSurfaceTexture failed: %d", err);
@@ -783,19 +783,18 @@
     // Note that we must set the player's new GraphicBufferProducer before
     // disconnecting the old one.  Otherwise queue/dequeue calls could be made
     // on the disconnected ANW, which may result in errors.
-    status_t err = p->setVideoSurfaceTexture(bufferProducer);
+    status_t err = p->setVideoSurfaceTexture(nww);
 
     mLock.lock();
     disconnectNativeWindow_l();
 
     if (err == OK) {
-        mConnectedWindow = anw;
-        mConnectedWindowBinder = binder;
+        mConnectedWindow = nww;
         mLock.unlock();
-    } else {
+    } else if (nww != NULL) {
         mLock.unlock();
         status_t err = nativeWindowDisconnect(
-                anw.get(), "disconnectNativeWindow");
+                nww->getANativeWindow(), "disconnectNativeWindow");
 
         if (err != OK) {
             ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
diff --git a/media/libmedia/MediaPlayer2Manager.h b/media/libmedia/MediaPlayer2Manager.h
index 8f0c491..d3ee044 100644
--- a/media/libmedia/MediaPlayer2Manager.h
+++ b/media/libmedia/MediaPlayer2Manager.h
@@ -35,6 +35,7 @@
 
 namespace android {
 
+struct ANativeWindowWrapper;
 struct AudioPlaybackRate;
 class AudioTrack;
 struct AVSyncSettings;
@@ -244,7 +245,7 @@
         // MediaPlayer2Engine interface
         virtual void            disconnect();
         virtual status_t        setVideoSurfaceTexture(
-                                        const sp<IGraphicBufferProducer>& bufferProducer);
+                const sp<ANativeWindowWrapper>& nww) override;
         virtual status_t        setBufferingSettings(const BufferingSettings& buffering) override;
         virtual status_t        getBufferingSettings(
                                         BufferingSettings* buffering /* nonnull */) override;
@@ -286,7 +287,7 @@
                                         const sp<media::VolumeShaper::Operation>& operation) override;
         virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;
 
-        sp<MediaPlayer2Base>     createPlayer(player2_type playerType);
+        sp<MediaPlayer2Base>    createPlayer(player2_type playerType);
 
         virtual status_t        setDataSource(
                         const sp<MediaHTTPService> &httpService,
@@ -299,7 +300,7 @@
         virtual status_t        setDataSource(const sp<IDataSource> &source);
 
 
-        sp<MediaPlayer2Base>     setDataSource_pre(player2_type playerType);
+        sp<MediaPlayer2Base>    setDataSource_pre(player2_type playerType);
         status_t                setDataSource_post(const sp<MediaPlayer2Base>& p,
                                                    status_t status);
 
@@ -375,8 +376,7 @@
                     audio_session_t              mAudioSessionId;
                     audio_attributes_t *         mAudioAttributes;
                     uid_t                        mUid;
-                    sp<ANativeWindow>            mConnectedWindow;
-                    sp<IBinder>                  mConnectedWindowBinder;
+                    sp<ANativeWindowWrapper>     mConnectedWindow;
                     struct sockaddr_in           mRetransmitEndpoint;
                     bool                         mRetransmitEndpointValid;
                     sp<Client>                   mNextClient;
diff --git a/media/libmedia/nuplayer2/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
similarity index 96%
rename from media/libmedia/nuplayer2/NdkWrapper.cpp
rename to media/libmedia/NdkWrapper.cpp
index 6698826..942393d 100644
--- a/media/libmedia/nuplayer2/NdkWrapper.cpp
+++ b/media/libmedia/NdkWrapper.cpp
@@ -17,9 +17,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "NdkWrapper"
 
-#include "NdkWrapper.h"
+#include <media/NdkWrapper.h>
 
-#include <gui/Surface.h>
+#include <android/native_window.h>
 #include <log/log.h>
 #include <media/NdkMediaCodec.h>
 #include <media/NdkMediaCrypto.h>
@@ -473,6 +473,31 @@
 }
 
 
+//////////// ANativeWindowWrapper
+ANativeWindowWrapper::ANativeWindowWrapper(ANativeWindow *aNativeWindow)
+    : mANativeWindow(aNativeWindow) {
+    if (aNativeWindow != NULL) {
+        ANativeWindow_acquire(aNativeWindow);
+    }
+}
+
+ANativeWindowWrapper::~ANativeWindowWrapper() {
+    release();
+}
+
+status_t ANativeWindowWrapper::release() {
+    if (mANativeWindow != NULL) {
+        ANativeWindow_release(mANativeWindow);
+        mANativeWindow = NULL;
+    }
+    return OK;
+}
+
+ANativeWindow *ANativeWindowWrapper::getANativeWindow() const {
+    return mANativeWindow;
+}
+
+
 //////////// AMediaDrmWrapper
 AMediaDrmWrapper::AMediaDrmWrapper(const uint8_t uuid[16]) {
     mAMediaDrm = AMediaDrm_createByUUID(uuid);
@@ -838,7 +863,7 @@
 
 status_t AMediaCodecWrapper::configure(
     const sp<AMediaFormatWrapper> &format,
-    const sp<Surface> &surface,
+    const sp<ANativeWindowWrapper> &nww,
     const sp<AMediaCryptoWrapper> &crypto,
     uint32_t flags) {
     if (mAMediaCodec == NULL) {
@@ -848,7 +873,7 @@
     media_status_t err = AMediaCodec_configure(
             mAMediaCodec,
             format->getAMediaFormat(),
-            surface.get(),
+            (nww == NULL ? NULL : nww->getANativeWindow()),
             crypto == NULL ? NULL : crypto->getAMediaCrypto(),
             flags);
 
@@ -969,12 +994,13 @@
         AMediaCodec_releaseOutputBuffer(mAMediaCodec, idx, render));
 }
 
-status_t AMediaCodecWrapper::setOutputSurface(const sp<Surface> &surface) {
+status_t AMediaCodecWrapper::setOutputSurface(const sp<ANativeWindowWrapper> &nww) {
     if (mAMediaCodec == NULL) {
         return DEAD_OBJECT;
     }
     return translateErrorCode(
-        AMediaCodec_setOutputSurface(mAMediaCodec, surface.get()));
+        AMediaCodec_setOutputSurface(mAMediaCodec,
+                                     (nww == NULL ? NULL : nww->getANativeWindow())));
 }
 
 status_t AMediaCodecWrapper::releaseOutputBufferAtTime(size_t idx, int64_t timestampNs) {
diff --git a/media/libmedia/TestPlayerStub.h b/media/libmedia/TestPlayerStub.h
index 1530ae1..27c8bf4 100644
--- a/media/libmedia/TestPlayerStub.h
+++ b/media/libmedia/TestPlayerStub.h
@@ -78,7 +78,7 @@
 
     // All the methods below wrap the mPlayer instance.
     virtual status_t setVideoSurfaceTexture(
-            const android::sp<android::IGraphicBufferProducer>& st)  {
+            const android::sp<android::ANativeWindowWrapper>& st)  {
         return mPlayer->setVideoSurfaceTexture(st);
     }
     virtual status_t prepare() {return mPlayer->prepare();}
diff --git a/media/libmedia/include/media/MediaPlayer2Engine.h b/media/libmedia/include/media/MediaPlayer2Engine.h
index 11d087b..0b43923 100644
--- a/media/libmedia/include/media/MediaPlayer2Engine.h
+++ b/media/libmedia/include/media/MediaPlayer2Engine.h
@@ -31,11 +31,10 @@
 
 namespace android {
 
+struct ANativeWindowWrapper;
 class Parcel;
-class Surface;
 class IDataSource;
 struct IStreamSource;
-class IGraphicBufferProducer;
 struct MediaHTTPService;
 struct AudioPlaybackRate;
 struct AVSyncSettings;
@@ -56,8 +55,7 @@
     virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
     virtual status_t        setDataSource(const sp<IStreamSource>& source) = 0;
     virtual status_t        setDataSource(const sp<IDataSource>& source) = 0;
-    virtual status_t        setVideoSurfaceTexture(
-                                    const sp<IGraphicBufferProducer>& bufferProducer) = 0;
+    virtual status_t        setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
     virtual status_t        getBufferingSettings(
                                     BufferingSettings* buffering /* nonnull */) = 0;
     virtual status_t        setBufferingSettings(const BufferingSettings& buffering) = 0;
diff --git a/media/libmedia/include/media/MediaPlayer2Interface.h b/media/libmedia/include/media/MediaPlayer2Interface.h
index 7c8e3e6..931a110 100644
--- a/media/libmedia/include/media/MediaPlayer2Interface.h
+++ b/media/libmedia/include/media/MediaPlayer2Interface.h
@@ -43,8 +43,7 @@
 class DataSource;
 struct MediaHTTPService;
 class Parcel;
-class Surface;
-class IGraphicBufferProducer;
+struct ANativeWindowWrapper;
 
 template<typename T> class SortedVector;
 
@@ -183,9 +182,8 @@
         return INVALID_OPERATION;
     }
 
-    // pass the buffered IGraphicBufferProducer to the media player service
-    virtual status_t    setVideoSurfaceTexture(
-                                const sp<IGraphicBufferProducer>& bufferProducer) = 0;
+    // pass the buffered native window to the media player service
+    virtual status_t    setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
 
     virtual status_t    getBufferingSettings(
                                 BufferingSettings* buffering /* nonnull */) {
diff --git a/media/libmedia/nuplayer2/NdkWrapper.h b/media/libmedia/include/media/NdkWrapper.h
similarity index 93%
rename from media/libmedia/nuplayer2/NdkWrapper.h
rename to media/libmedia/include/media/NdkWrapper.h
index a097d5a..00e0fd4 100644
--- a/media/libmedia/nuplayer2/NdkWrapper.h
+++ b/media/libmedia/include/media/NdkWrapper.h
@@ -33,13 +33,13 @@
 struct AMediaDrm;
 struct AMediaFormat;
 struct AMediaExtractor;
+struct ANativeWindow;
 struct PsshInfo;
 
 namespace android {
 
 struct AMessage;
 class MetaData;
-class Surface;
 
 struct AMediaFormatWrapper : public RefBase {
     static sp<AMediaFormatWrapper> Create(const sp<AMessage> &message);
@@ -84,6 +84,23 @@
     DISALLOW_EVIL_CONSTRUCTORS(AMediaFormatWrapper);
 };
 
+struct ANativeWindowWrapper : public RefBase {
+    ANativeWindowWrapper(ANativeWindow *aNativeWindow);
+
+    // the returned ANativeWindow is still owned by this wrapper.
+    ANativeWindow *getANativeWindow() const;
+
+    status_t release();
+
+protected:
+    virtual ~ANativeWindowWrapper();
+
+private:
+    ANativeWindow *mANativeWindow;
+
+    DISALLOW_EVIL_CONSTRUCTORS(ANativeWindowWrapper);
+};
+
 struct AMediaDrmWrapper : public RefBase {
     AMediaDrmWrapper(const uint8_t uuid[16]);
     AMediaDrmWrapper(AMediaDrm *aMediaDrm);
@@ -205,7 +222,7 @@
 
     status_t configure(
             const sp<AMediaFormatWrapper> &format,
-            const sp<Surface> &surface,
+            const sp<ANativeWindowWrapper> &nww,
             const sp<AMediaCryptoWrapper> &crypto,
             uint32_t flags);
 
@@ -239,7 +256,7 @@
 
     status_t releaseOutputBuffer(size_t idx, bool render);
 
-    status_t setOutputSurface(const sp<Surface> &surface);
+    status_t setOutputSurface(const sp<ANativeWindowWrapper> &nww);
 
     status_t releaseOutputBufferAtTime(size_t idx, int64_t timestampNs);
 
diff --git a/media/libmedia/include/media/mediaplayer2.h b/media/libmedia/include/media/mediaplayer2.h
index 2358a48..8327043 100644
--- a/media/libmedia/include/media/mediaplayer2.h
+++ b/media/libmedia/include/media/mediaplayer2.h
@@ -31,13 +31,10 @@
 #include <utils/String8.h>
 #include <utils/ThreadDefs.h>
 
-struct ANativeWindow;
-
 namespace android {
 
 struct AVSyncSettings;
-class IGraphicBufferProducer;
-class Surface;
+struct ANativeWindowWrapper;
 
 enum media2_event_type {
     MEDIA2_NOP               = 0, // interface test message
@@ -212,8 +209,7 @@
 
             status_t        setDataSource(int fd, int64_t offset, int64_t length);
             status_t        setDataSource(const sp<IDataSource> &source);
-            status_t        setVideoSurfaceTexture(
-                                    const sp<IGraphicBufferProducer>& bufferProducer);
+            status_t        setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww);
             status_t        setListener(const sp<MediaPlayer2Listener>& listener);
             status_t        getBufferingSettings(BufferingSettings* buffering /* nonnull */);
             status_t        setBufferingSettings(const BufferingSettings& buffering);
diff --git a/media/libmedia/mediaplayer2.cpp b/media/libmedia/mediaplayer2.cpp
index 40d38fa..5a52abf 100644
--- a/media/libmedia/mediaplayer2.cpp
+++ b/media/libmedia/mediaplayer2.cpp
@@ -29,14 +29,13 @@
 #include <binder/IServiceManager.h>
 #include <binder/IPCThreadState.h>
 
-#include <gui/Surface.h>
-
 #include <media/mediaplayer2.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
 #include <media/AVSyncSettings.h>
 #include <media/IDataSource.h>
 #include <media/MediaAnalyticsItem.h>
+#include <media/NdkWrapper.h>
 
 #include <binder/MemoryBase.h>
 
@@ -231,13 +230,12 @@
     return mPlayer->getMetadata(update_only, apply_filter, metadata);
 }
 
-status_t MediaPlayer2::setVideoSurfaceTexture(
-        const sp<IGraphicBufferProducer>& bufferProducer)
+status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww)
 {
     ALOGV("setVideoSurfaceTexture");
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) return NO_INIT;
-    return mPlayer->setVideoSurfaceTexture(bufferProducer);
+    return mPlayer->setVideoSurfaceTexture(nww);
 }
 
 status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */)
diff --git a/media/libmedia/nuplayer2/Android.bp b/media/libmedia/nuplayer2/Android.bp
index 2a1fc59..d609ba0 100644
--- a/media/libmedia/nuplayer2/Android.bp
+++ b/media/libmedia/nuplayer2/Android.bp
@@ -4,7 +4,6 @@
         "JWakeLock.cpp",
         "GenericSource.cpp",
         "HTTPLiveSource.cpp",
-        "NdkWrapper.cpp",
         "NuPlayer2.cpp",
         "NuPlayer2CCDecoder.cpp",
         "NuPlayer2Decoder.cpp",
@@ -23,6 +22,7 @@
     ],
 
     include_dirs: [
+        "frameworks/av/media/libmedia/include",
         "frameworks/av/media/libstagefright",
         "frameworks/av/media/libstagefright/httplive",
         "frameworks/av/media/libstagefright/include",
diff --git a/media/libmedia/nuplayer2/GenericSource.cpp b/media/libmedia/nuplayer2/GenericSource.cpp
index 8142767..f8bc4f1 100644
--- a/media/libmedia/nuplayer2/GenericSource.cpp
+++ b/media/libmedia/nuplayer2/GenericSource.cpp
@@ -18,7 +18,6 @@
 #define LOG_TAG "GenericSource"
 
 #include "GenericSource.h"
-#include "NdkWrapper.h"
 #include "NuPlayer2Drm.h"
 
 #include "AnotherPacketSource.h"
@@ -29,6 +28,7 @@
 #include <media/MediaHTTPService.h>
 #include <media/MediaExtractor.h>
 #include <media/MediaSource.h>
+#include <media/NdkWrapper.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
diff --git a/media/libmedia/nuplayer2/NuPlayer2.cpp b/media/libmedia/nuplayer2/NuPlayer2.cpp
index aa0c8d1..2745219 100644
--- a/media/libmedia/nuplayer2/NuPlayer2.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2.cpp
@@ -24,7 +24,6 @@
 #include "NuPlayer2.h"
 
 #include "HTTPLiveSource.h"
-#include "NdkWrapper.h"
 #include "NuPlayer2CCDecoder.h"
 #include "NuPlayer2Decoder.h"
 #include "NuPlayer2DecoderBase.h"
@@ -45,6 +44,7 @@
 #include <media/AudioResamplerPublic.h>
 #include <media/AVSyncSettings.h>
 #include <media/MediaCodecBuffer.h>
+#include <media/NdkWrapper.h>
 
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -57,13 +57,11 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/Surface.h>
-
-
 #include "ESDS.h"
 #include <media/stagefright/Utils.h>
 
+#include <system/window.h>
+
 namespace android {
 
 static status_t sendMetaDataToHal(sp<MediaPlayer2Base::AudioSink>& sink,
@@ -143,16 +141,16 @@
 };
 
 struct NuPlayer2::SetSurfaceAction : public Action {
-    explicit SetSurfaceAction(const sp<Surface> &surface)
-        : mSurface(surface) {
+    explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
+        : mNativeWindow(nww) {
     }
 
     virtual void execute(NuPlayer2 *player) {
-        player->performSetSurface(mSurface);
+        player->performSetSurface(mNativeWindow);
     }
 
 private:
-    sp<Surface> mSurface;
+    sp<ANativeWindowWrapper> mNativeWindow;
 
     DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
 };
@@ -407,14 +405,13 @@
     (new AMessage(kWhatPrepare, this))->post();
 }
 
-void NuPlayer2::setVideoSurfaceTextureAsync(
-        const sp<IGraphicBufferProducer> &bufferProducer) {
+void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
     sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
 
-    if (bufferProducer == NULL) {
+    if (nww == NULL || nww->getANativeWindow() == NULL) {
         msg->setObject("surface", NULL);
     } else {
-        msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */));
+        msg->setObject("surface", nww);
     }
 
     msg->post();
@@ -792,10 +789,10 @@
 
             sp<RefBase> obj;
             CHECK(msg->findObject("surface", &obj));
-            sp<Surface> surface = static_cast<Surface *>(obj.get());
+            sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
 
             ALOGD("onSetVideoSurface(%p, %s video decoder)",
-                    surface.get(),
+                    (nww == NULL ? NULL : nww->getANativeWindow()),
                     (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
                             && mVideoDecoder != NULL) ? "have" : "no");
 
@@ -803,9 +800,9 @@
             // be in preparing state and it could take long time.
             // When mStarted is true, mSource must have been set.
             if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
-                    // NOTE: mVideoDecoder's mSurface is always non-null
-                    || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
-                performSetSurface(surface);
+                    // NOTE: mVideoDecoder's mNativeWindow is always non-null
+                    || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
+                performSetSurface(nww);
                 break;
             }
 
@@ -814,7 +811,7 @@
                             (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
                                            FLUSH_CMD_SHUTDOWN /* video */));
 
-            mDeferredActions.push_back(new SetSurfaceAction(surface));
+            mDeferredActions.push_back(new SetSurfaceAction(nww));
 
             if (obj != NULL) {
                 if (mStarted) {
@@ -1033,7 +1030,7 @@
 
             // initialize video before audio because successful initialization of
             // video may change deep buffer mode of audio.
-            if (mSurface != NULL) {
+            if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
                 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
                     rescan = true;
                 }
@@ -1219,7 +1216,8 @@
                 if (mSource != nullptr) {
                     if (audio) {
                         if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
-                                || mSurface == NULL || mVideoDecoder == NULL) {
+                                || mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
+                                || mVideoDecoder == NULL) {
                             // When both audio and video have error, or this stream has only audio
                             // which has error, notify client of error.
                             notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
@@ -1505,7 +1503,7 @@
 
     // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
     // data on instantiation.
-    if (mSurface != NULL) {
+    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
         err = instantiateDecoder(false, &mVideoDecoder);
         if (err != OK) {
             return err;
@@ -1934,7 +1932,7 @@
         notify->setInt32("generation", mVideoDecoderGeneration);
 
         *decoder = new Decoder(
-                notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
+                notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
         mVideoDecoderError = false;
 
         // enable FRC if high-quality AV sync is requested, even if not
@@ -2141,8 +2139,9 @@
 
 status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
     mVideoScalingMode = mode;
-    if (mSurface != NULL) {
-        status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
+    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
+        status_t ret = native_window_set_scaling_mode(
+                mNativeWindow->getANativeWindow(), mVideoScalingMode);
         if (ret != OK) {
             ALOGE("Failed to set scaling mode (%d): %s",
                 -ret, strerror(-ret));
@@ -2375,10 +2374,10 @@
     }
 }
 
-void NuPlayer2::performSetSurface(const sp<Surface> &surface) {
+void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
     ALOGV("performSetSurface");
 
-    mSurface = surface;
+    mNativeWindow = nww;
 
     // XXX - ignore error from setVideoScalingMode for now
     setVideoScalingMode(mVideoScalingMode);
diff --git a/media/libmedia/nuplayer2/NuPlayer2.h b/media/libmedia/nuplayer2/NuPlayer2.h
index 6dc6442..638b259 100644
--- a/media/libmedia/nuplayer2/NuPlayer2.h
+++ b/media/libmedia/nuplayer2/NuPlayer2.h
@@ -27,6 +27,7 @@
 struct ABuffer;
 struct AMediaCryptoWrapper;
 struct AMessage;
+struct ANativeWindowWrapper;
 struct AudioPlaybackRate;
 struct AVSyncSettings;
 class IDataSource;
@@ -58,8 +59,7 @@
 
     void prepareAsync();
 
-    void setVideoSurfaceTextureAsync(
-            const sp<IGraphicBufferProducer> &bufferProducer);
+    void setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww);
 
     void setAudioSink(const sp<MediaPlayer2Base::AudioSink> &sink);
     status_t setPlaybackSettings(const AudioPlaybackRate &rate);
@@ -167,7 +167,7 @@
     Mutex mSourceLock;  // guard |mSource|.
     sp<Source> mSource;
     uint32_t mSourceFlags;
-    sp<Surface> mSurface;
+    sp<ANativeWindowWrapper> mNativeWindow;
     sp<MediaPlayer2Base::AudioSink> mAudioSink;
     sp<DecoderBase> mVideoDecoder;
     bool mOffloadAudio;
@@ -320,7 +320,7 @@
     void performDecoderFlush(FlushCommand audio, FlushCommand video);
     void performReset();
     void performScanSources();
-    void performSetSurface(const sp<Surface> &wrapper);
+    void performSetSurface(const sp<ANativeWindowWrapper> &nw);
     void performResumeDecoders(bool needNotify);
 
     void onSourceNotify(const sp<AMessage> &msg);
diff --git a/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp b/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp
index d78a8e8..25d41f3 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp
@@ -21,7 +21,6 @@
 
 #include <algorithm>
 
-#include "NdkWrapper.h"
 #include "NuPlayer2CCDecoder.h"
 #include "NuPlayer2Decoder.h"
 #include "NuPlayer2Drm.h"
@@ -31,6 +30,7 @@
 #include <cutils/properties.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/NdkMediaCodec.h>
+#include <media/NdkWrapper.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -39,7 +39,6 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/SurfaceUtils.h>
-#include <gui/Surface.h>
 
 #include "ATSParser.h"
 
@@ -61,10 +60,10 @@
         pid_t pid,
         uid_t uid,
         const sp<Renderer> &renderer,
-        const sp<Surface> &surface,
+        const sp<ANativeWindowWrapper> &nww,
         const sp<CCDecoder> &ccDecoder)
     : DecoderBase(notify),
-      mSurface(surface),
+      mNativeWindow(nww),
       mSource(source),
       mRenderer(renderer),
       mCCDecoder(ccDecoder),
@@ -109,14 +108,15 @@
     return mStats;
 }
 
-status_t NuPlayer2::Decoder::setVideoSurface(const sp<Surface> &surface) {
-    if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
+status_t NuPlayer2::Decoder::setVideoSurface(const sp<ANativeWindowWrapper> &nww) {
+    if (nww == NULL || nww->getANativeWindow() == NULL
+        || ADebug::isExperimentEnabled("legacy-setsurface")) {
         return BAD_VALUE;
     }
 
     sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
 
-    msg->setObject("surface", surface);
+    msg->setObject("surface", nww);
     sp<AMessage> response;
     status_t err = msg->postAndAwaitResponse(&response);
     if (err == OK && response != NULL) {
@@ -226,30 +226,37 @@
 
             sp<RefBase> obj;
             CHECK(msg->findObject("surface", &obj));
-            sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
+            sp<ANativeWindowWrapper> nww =
+                static_cast<ANativeWindowWrapper *>(obj.get()); // non-null
+            if (nww == NULL || nww->getANativeWindow() == NULL) {
+                break;
+            }
             int32_t err = INVALID_OPERATION;
-            // NOTE: in practice mSurface is always non-null, but checking here for completeness
-            if (mCodec != NULL && mSurface != NULL) {
+            // NOTE: in practice mNativeWindow is always non-null,
+            // but checking here for completeness
+            if (mCodec != NULL
+                && mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
                 // TODO: once AwesomePlayer is removed, remove this automatic connecting
                 // to the surface by MediaPlayerService.
                 //
-                // at this point MediaPlayerService::client has already connected to the
+                // at this point MediaPlayer2Manager::client has already connected to the
                 // surface, which MediaCodec does not expect
-                err = nativeWindowDisconnect(surface.get(), "kWhatSetVideoSurface(surface)");
+                err = nativeWindowDisconnect(nww->getANativeWindow(), "kWhatSetVideoSurface(nww)");
                 if (err == OK) {
-                    err = mCodec->setOutputSurface(surface);
+                    err = mCodec->setOutputSurface(nww);
                     ALOGI_IF(err, "codec setOutputSurface returned: %d", err);
                     if (err == OK) {
                         // reconnect to the old surface as MPS::Client will expect to
                         // be able to disconnect from it.
-                        (void)nativeWindowConnect(mSurface.get(), "kWhatSetVideoSurface(mSurface)");
-                        mSurface = surface;
+                        (void)nativeWindowConnect(mNativeWindow->getANativeWindow(),
+                                                  "kWhatSetVideoSurface(mNativeWindow)");
+                        mNativeWindow = nww;
                     }
                 }
                 if (err != OK) {
                     // reconnect to the new surface on error as MPS::Client will expect to
                     // be able to disconnect from it.
-                    (void)nativeWindowConnect(surface.get(), "kWhatSetVideoSurface(err)");
+                    (void)nativeWindowConnect(nww->getANativeWindow(), "kWhatSetVideoSurface(err)");
                 }
             }
 
@@ -289,7 +296,8 @@
 
     mComponentName = mime;
     mComponentName.append(" decoder");
-    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
+    ALOGV("[%s] onConfigure (nww=%p)", mComponentName.c_str(),
+          (mNativeWindow == NULL ? NULL : mNativeWindow->getANativeWindow()));
 
     mCodec = AMediaCodecWrapper::CreateDecoderByType(mime);
     int32_t secure = 0;
@@ -316,9 +324,9 @@
     mCodec->getName(&mComponentName);
 
     status_t err;
-    if (mSurface != NULL) {
+    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
         // disconnect from surface as MediaCodec will reconnect
-        err = nativeWindowDisconnect(mSurface.get(), "onConfigure");
+        err = nativeWindowDisconnect(mNativeWindow->getANativeWindow(), "onConfigure");
         // We treat this as a warning, as this is a preparatory step.
         // Codec will try to connect to the surface, which is where
         // any error signaling will occur.
@@ -337,7 +345,7 @@
 
     err = mCodec->configure(
             AMediaFormatWrapper::Create(format),
-            mSurface,
+            mNativeWindow,
             crypto,
             0 /* flags */);
 
@@ -530,9 +538,9 @@
         mCodec = NULL;
         ++mBufferGeneration;
 
-        if (mSurface != NULL) {
+        if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
             // reconnect to surface as MediaCodec disconnected from it
-            status_t error = nativeWindowConnect(mSurface.get(), "onShutdown");
+            status_t error = nativeWindowConnect(mNativeWindow->getANativeWindow(), "onShutdown");
             ALOGW_IF(error != NO_ERROR,
                     "[%s] failed to connect to native window, error=%d",
                     mComponentName.c_str(), error);
diff --git a/media/libmedia/nuplayer2/NuPlayer2Decoder.h b/media/libmedia/nuplayer2/NuPlayer2Decoder.h
index 58f70e7..fdfb10e 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Decoder.h
+++ b/media/libmedia/nuplayer2/NuPlayer2Decoder.h
@@ -34,13 +34,13 @@
             pid_t pid,
             uid_t uid,
             const sp<Renderer> &renderer = NULL,
-            const sp<Surface> &surface = NULL,
+            const sp<ANativeWindowWrapper> &nww = NULL,
             const sp<CCDecoder> &ccDecoder = NULL);
 
     virtual sp<AMessage> getStats() const;
 
     // sets the output surface of video decoders.
-    virtual status_t setVideoSurface(const sp<Surface> &surface);
+    virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &nww);
 
     virtual status_t releaseCrypto();
 
@@ -70,7 +70,7 @@
         kMaxNumVideoTemporalLayers = 32,
     };
 
-    sp<Surface> mSurface;
+    sp<ANativeWindowWrapper> mNativeWindow;
 
     sp<Source> mSource;
     sp<Renderer> mRenderer;
diff --git a/media/libmedia/nuplayer2/NuPlayer2DecoderBase.h b/media/libmedia/nuplayer2/NuPlayer2DecoderBase.h
index 2819dae..1e57f0d 100644
--- a/media/libmedia/nuplayer2/NuPlayer2DecoderBase.h
+++ b/media/libmedia/nuplayer2/NuPlayer2DecoderBase.h
@@ -25,10 +25,10 @@
 namespace android {
 
 struct ABuffer;
+struct ANativeWindowWrapper;
 struct MediaCodec;
 class MediaBuffer;
 class MediaCodecBuffer;
-class Surface;
 
 struct NuPlayer2::DecoderBase : public AHandler {
     explicit DecoderBase(const sp<AMessage> &notify);
@@ -41,7 +41,7 @@
     void pause();
 
     void setRenderer(const sp<Renderer> &renderer);
-    virtual status_t setVideoSurface(const sp<Surface> &) { return INVALID_OPERATION; }
+    virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &) { return INVALID_OPERATION; }
 
     void signalFlush();
     void signalResume(bool notifyComplete);
diff --git a/media/libmedia/nuplayer2/NuPlayer2Driver.cpp b/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
index dd0da8a..c4e42e7 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
@@ -219,8 +219,7 @@
     return mAsyncResult;
 }
 
-status_t NuPlayer2Driver::setVideoSurfaceTexture(
-        const sp<IGraphicBufferProducer> &bufferProducer) {
+status_t NuPlayer2Driver::setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) {
     ALOGV("setVideoSurfaceTexture(%p)", this);
     Mutex::Autolock autoLock(mLock);
 
@@ -239,7 +238,7 @@
 
     mSetSurfaceInProgress = true;
 
-    mPlayer->setVideoSurfaceTextureAsync(bufferProducer);
+    mPlayer->setVideoSurfaceTextureAsync(nww);
 
     while (mSetSurfaceInProgress) {
         mCondition.wait(mLock);
diff --git a/media/libmedia/nuplayer2/NuPlayer2Driver.h b/media/libmedia/nuplayer2/NuPlayer2Driver.h
index 0028d05..4451349 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Driver.h
+++ b/media/libmedia/nuplayer2/NuPlayer2Driver.h
@@ -43,8 +43,7 @@
 
     virtual status_t setDataSource(const sp<DataSource>& dataSource);
 
-    virtual status_t setVideoSurfaceTexture(
-            const sp<IGraphicBufferProducer> &bufferProducer);
+    virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww);
 
     virtual status_t getBufferingSettings(
             BufferingSettings* buffering /* nonnull */) override;
diff --git a/media/libmedia/nuplayer2/NuPlayer2Drm.cpp b/media/libmedia/nuplayer2/NuPlayer2Drm.cpp
index 5a4502a..4751849 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Drm.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2Drm.cpp
@@ -19,7 +19,7 @@
 
 #include "NuPlayer2Drm.h"
 
-#include "NdkWrapper.h"
+#include <media/NdkWrapper.h>
 #include <utils/Log.h>