Revert "Remove IDataSource dependency from DataSource."

This reverts commit 514674257ef6954a7479ac93a26a07061f54462d.

The original change Iaba6d9be is no longer needed since we
separated out DataSourceBase from DataSource. Now, DataSource
may have a method relying on a class from libmedia, IDataSource.

Test: checked the correct wrapping path with 'dumpsys media.extractor'
Bug: 72869975

Change-Id: Ib0d5ca863fa70a4a96f97b3377c209e1f288f443
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libmediaextractor/include/media/DataSource.h
index a066183..1ae2e21 100644
--- a/media/libmediaextractor/include/media/DataSource.h
+++ b/media/libmediaextractor/include/media/DataSource.h
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/DataSourceBase.h>
+#include <media/IDataSource.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -35,6 +36,11 @@
 public:
     DataSource() {}
 
+    // returns a pointer to IDataSource if it is wrapped.
+    virtual sp<IDataSource> getIDataSource() const {
+        return nullptr;
+    }
+
 protected:
     virtual ~DataSource() {}
 
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
index 4700660..0dd5d6f 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
@@ -35,6 +35,7 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/DataSourceFactory.h>
+#include <media/stagefright/FileSource.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaClock.h>
@@ -161,30 +162,15 @@
 
 status_t NuPlayer2::GenericSource2::initFromDataSource() {
     sp<IMediaExtractor> extractor;
-    CHECK(mDataSource != NULL || mFd != -1);
+    CHECK(mDataSource != NULL);
     sp<DataSource> dataSource = mDataSource;
-    const int fd = mFd;
-    const int64_t offset = mOffset;
-    const int64_t length = mLength;
 
     mLock.unlock();
     // This might take long time if data source is not reliable.
-    if (dataSource != nullptr) {
-        extractor = MediaExtractorFactory::Create(dataSource, NULL /* mime */);
-    } else {
-        extractor = MediaExtractorFactory::CreateFromFd(
-                fd, offset, length, NULL /* mime */, &dataSource);
-    }
-
-    if (dataSource == nullptr) {
-        ALOGE("initFromDataSource, failed to create data source!");
-        mLock.lock();
-        return UNKNOWN_ERROR;
-    }
+    extractor = MediaExtractorFactory::Create(dataSource, NULL);
 
     if (extractor == NULL) {
         ALOGE("initFromDataSource, cannot create extractor!");
-        mLock.lock();
         return UNKNOWN_ERROR;
     }
 
@@ -193,13 +179,10 @@
     size_t numtracks = extractor->countTracks();
     if (numtracks == 0) {
         ALOGE("initFromDataSource, source has no track!");
-        mLock.lock();
         return UNKNOWN_ERROR;
     }
 
     mLock.lock();
-    mFd = -1;
-    mDataSource = dataSource;
     mFileMeta = fileMeta;
     if (mFileMeta != NULL) {
         int64_t duration;
@@ -408,16 +391,51 @@
             if (!mDisconnected) {
                 mDataSource = dataSource;
             }
+        } else {
+            if (property_get_bool("media.stagefright.extractremote", true) &&
+                    !FileSource::requiresDrm(mFd, mOffset, mLength, nullptr /* mime */)) {
+                sp<IBinder> binder =
+                        defaultServiceManager()->getService(String16("media.extractor"));
+                if (binder != nullptr) {
+                    ALOGD("FileSource remote");
+                    sp<IMediaExtractorService> mediaExService(
+                            interface_cast<IMediaExtractorService>(binder));
+                    sp<IDataSource> source =
+                            mediaExService->makeIDataSource(mFd, mOffset, mLength);
+                    ALOGV("IDataSource(FileSource): %p %d %lld %lld",
+                            source.get(), mFd, (long long)mOffset, (long long)mLength);
+                    if (source.get() != nullptr) {
+                        mDataSource = CreateDataSourceFromIDataSource(source);
+                        if (mDataSource != nullptr) {
+                            // Close the local file descriptor as it is not needed anymore.
+                            close(mFd);
+                            mFd = -1;
+                        }
+                    } else {
+                        ALOGW("extractor service cannot make data source");
+                    }
+                } else {
+                    ALOGW("extractor service not running");
+                }
+            }
+            if (mDataSource == nullptr) {
+                ALOGD("FileSource local");
+                mDataSource = new FileSource(mFd, mOffset, mLength);
+            }
+            // TODO: close should always be done on mFd, see the lines following
+            // CreateDataSourceFromIDataSource above,
+            // and the FileSource constructor should dup the mFd argument as needed.
+            mFd = -1;
         }
 
-        if (mFd == -1 && mDataSource == NULL) {
+        if (mDataSource == NULL) {
             ALOGE("Failed to create data source!");
             notifyPreparedAndCleanup(UNKNOWN_ERROR);
             return;
         }
     }
 
-    if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
+    if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
         mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
     }
 
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 511f46f..0cf5b9d 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -27,6 +27,7 @@
 #include <media/MediaBufferHolder.h>
 #include <media/MediaExtractor.h>
 #include <media/MediaSource.h>
+#include <media/IMediaExtractorService.h>
 #include <media/IMediaHTTPService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -161,30 +162,15 @@
 
 status_t NuPlayer::GenericSource::initFromDataSource() {
     sp<IMediaExtractor> extractor;
-    CHECK(mDataSource != NULL || mFd != -1);
+    CHECK(mDataSource != NULL);
     sp<DataSource> dataSource = mDataSource;
-    const int fd = mFd;
-    const int64_t offset = mOffset;
-    const int64_t length = mLength;
 
     mLock.unlock();
     // This might take long time if data source is not reliable.
-    if (dataSource != nullptr) {
-        extractor = MediaExtractorFactory::Create(dataSource, NULL /* mime */);
-    } else {
-        extractor = MediaExtractorFactory::CreateFromFd(
-                fd, offset, length, NULL /* mime */, &dataSource);
-    }
-
-    if (dataSource == nullptr) {
-        ALOGE("initFromDataSource, failed to create data source!");
-        mLock.lock();
-        return UNKNOWN_ERROR;
-    }
+    extractor = MediaExtractorFactory::Create(dataSource, NULL);
 
     if (extractor == NULL) {
         ALOGE("initFromDataSource, cannot create extractor!");
-        mLock.lock();
         return UNKNOWN_ERROR;
     }
 
@@ -193,13 +179,10 @@
     size_t numtracks = extractor->countTracks();
     if (numtracks == 0) {
         ALOGE("initFromDataSource, source has no track!");
-        mLock.lock();
         return UNKNOWN_ERROR;
     }
 
     mLock.lock();
-    mFd = -1;
-    mDataSource = dataSource;
     mFileMeta = fileMeta;
     if (mFileMeta != NULL) {
         int64_t duration;
@@ -403,15 +386,51 @@
             if (!mDisconnected) {
                 mDataSource = dataSource;
             }
+        } else {
+            if (property_get_bool("media.stagefright.extractremote", true) &&
+                    !FileSource::requiresDrm(mFd, mOffset, mLength, nullptr /* mime */)) {
+                sp<IBinder> binder =
+                        defaultServiceManager()->getService(String16("media.extractor"));
+                if (binder != nullptr) {
+                    ALOGD("FileSource remote");
+                    sp<IMediaExtractorService> mediaExService(
+                            interface_cast<IMediaExtractorService>(binder));
+                    sp<IDataSource> source =
+                            mediaExService->makeIDataSource(mFd, mOffset, mLength);
+                    ALOGV("IDataSource(FileSource): %p %d %lld %lld",
+                            source.get(), mFd, (long long)mOffset, (long long)mLength);
+                    if (source.get() != nullptr) {
+                        mDataSource = CreateDataSourceFromIDataSource(source);
+                        if (mDataSource != nullptr) {
+                            // Close the local file descriptor as it is not needed anymore.
+                            close(mFd);
+                            mFd = -1;
+                        }
+                    } else {
+                        ALOGW("extractor service cannot make data source");
+                    }
+                } else {
+                    ALOGW("extractor service not running");
+                }
+            }
+            if (mDataSource == nullptr) {
+                ALOGD("FileSource local");
+                mDataSource = new FileSource(mFd, mOffset, mLength);
+            }
+            // TODO: close should always be done on mFd, see the lines following
+            // CreateDataSourceFromIDataSource above,
+            // and the FileSource constructor should dup the mFd argument as needed.
+            mFd = -1;
         }
-        if (mFd == -1 && mDataSource == NULL) {
+
+        if (mDataSource == NULL) {
             ALOGE("Failed to create data source!");
             notifyPreparedAndCleanup(UNKNOWN_ERROR);
             return;
         }
     }
 
-    if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
+    if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
         mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
     }
 
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index 71b737b..92e6eb9 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -117,6 +117,10 @@
     return mIDataSource->DrmInitialization(mime);
 }
 
+sp<IDataSource> CallbackDataSource::getIDataSource() const {
+    return mIDataSource;
+}
+
 TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
     : mSource(source), mCachedOffset(0), mCachedSize(0) {
     mName = String8::format("TinyCacheSource(%s)", mSource->toString().string());
@@ -194,4 +198,8 @@
     return mSource->DrmInitialization(mime);
 }
 
+sp<IDataSource> TinyCacheSource::getIDataSource() const {
+    return mSource->getIDataSource();
+}
+
 } // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 543c274..f6c61a0 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -23,7 +23,6 @@
 #include <media/MediaAnalyticsItem.h>
 #include <media/MediaExtractor.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/IMediaExtractor.h>
@@ -40,7 +39,7 @@
 // static
 sp<IMediaExtractor> MediaExtractorFactory::Create(
         const sp<DataSource> &source, const char *mime) {
-    ALOGV("MediaExtractorFactory::%s %s", __func__, mime);
+    ALOGV("MediaExtractorFactory::Create %s", mime);
 
     if (!property_get_bool("media.stagefright.extractremote", true)) {
         // local extractor
@@ -64,44 +63,6 @@
     return NULL;
 }
 
-// static
-sp<IMediaExtractor> MediaExtractorFactory::CreateFromFd(
-        int fd, int64_t offset, int64_t length, const char *mime, sp<DataSource> *out) {
-    ALOGV("MediaExtractorFactory::%s %s", __func__, mime);
-
-    if (property_get_bool("media.stagefright.extractremote", true)) {
-        // remote extractor
-        ALOGV("get service manager");
-        sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));
-
-        if (binder != 0) {
-            sp<IMediaExtractorService> mediaExService(
-                    interface_cast<IMediaExtractorService>(binder));
-            if (!FileSource::requiresDrm(fd, offset, length, nullptr /* mime */)) {
-                ALOGD("FileSource remote");
-                sp<IDataSource> remoteSource =
-                    mediaExService->makeIDataSource(fd, offset, length);
-                ALOGV("IDataSource(FileSource): %p %d %lld %lld",
-                        remoteSource.get(), fd, (long long)offset, (long long)length);
-                if (remoteSource.get() != nullptr) {
-                    // replace the caller's local source with remote source.
-                    *out = CreateDataSourceFromIDataSource(remoteSource);
-                    return mediaExService->makeExtractor(remoteSource, mime);
-                } else {
-                    ALOGW("extractor service cannot make file source."
-                            " falling back to local file source.");
-                }
-            }
-            // Falls back.
-        } else {
-            ALOGE("extractor service not running");
-            return nullptr;
-        }
-    }
-    *out = new FileSource(fd, offset, length);
-    return Create(*out, mime);
-}
-
 sp<IMediaExtractor> MediaExtractorFactory::CreateFromService(
         const sp<DataSource> &source, const char *mime) {
 
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
index 32556d6..9f413cd 100644
--- a/media/libstagefright/include/CallbackDataSource.h
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -42,6 +42,7 @@
         return mName;
     }
     virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL);
+    virtual sp<IDataSource> getIDataSource() const;
 
 private:
     sp<IDataSource> mIDataSource;
@@ -70,6 +71,7 @@
         return mName;
     }
     virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL);
+    virtual sp<IDataSource> getIDataSource() const;
 
 private:
     // 2kb comes from experimenting with the time-to-first-frame from a MediaPlayer
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index 90c66eb..fb9f5bd 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -33,12 +33,6 @@
 public:
     static sp<IMediaExtractor> Create(
             const sp<DataSource> &source, const char *mime = NULL);
-    // Creates media extractor from the given file descriptor. To avoid binder calls for
-    // reading file data, this tries to create remote file source in extractor service.
-    // If that fails, this falls back to local file source. The data source used for extractor
-    // will be alsp returned with |out|.
-    static sp<IMediaExtractor> CreateFromFd(
-            int fd, int64_t offset, int64_t length, const char *mime, sp<DataSource> *out);
     static sp<IMediaExtractor> CreateFromService(
             const sp<DataSource> &source, const char *mime = NULL);
     static void LoadPlugins(const ::std::string& apkPath);
diff --git a/media/libstagefright/include/media/stagefright/RemoteDataSource.h b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
index 4ddc5e3..e191e6a 100644
--- a/media/libstagefright/include/media/stagefright/RemoteDataSource.h
+++ b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
@@ -31,6 +31,9 @@
         if (source.get() == nullptr) {
             return nullptr;
         }
+        if (source->getIDataSource().get() != nullptr) {
+            return source->getIDataSource();
+        }
         return new RemoteDataSource(source);
     }