1 /*
2  * Copyright 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef REMOTE_DATA_SOURCE_H_
18 #define REMOTE_DATA_SOURCE_H_
19 
20 #include <android/IDataSource.h>
21 #include <binder/IMemory.h>
22 #include <binder/MemoryDealer.h>
23 #include <media/DataSource.h>
24 
25 namespace android {
26 
27 // Originally in MediaExtractor.cpp
28 class RemoteDataSource : public BnDataSource {
29 public:
wrap(const sp<DataSource> & source)30     static sp<IDataSource> wrap(const sp<DataSource> &source) {
31         if (source.get() == nullptr) {
32             return nullptr;
33         }
34         if (source->getIDataSource().get() != nullptr) {
35             return source->getIDataSource();
36         }
37         return new RemoteDataSource(source);
38     }
39 
~RemoteDataSource()40     virtual ~RemoteDataSource() {
41         close();
42     }
getIMemory()43     virtual sp<IMemory> getIMemory() {
44         Mutex::Autolock lock(mLock);
45         if (mMemory.get() == nullptr) {
46             ALOGE("getIMemory() failed, mMemory is nullptr");
47             return nullptr;
48         }
49         return mMemory;
50     }
readAt(off64_t offset,size_t size)51     virtual ssize_t readAt(off64_t offset, size_t size) {
52         ALOGV("readAt(%lld, %zu)", (long long)offset, size);
53         if (size > kBufferSize) {
54             size = kBufferSize;
55         }
56 
57         Mutex::Autolock lock(mLock);
58         if (mSource.get() == nullptr) {
59             ALOGE("readAt() failed, mSource is nullptr");
60             return 0;
61         }
62         return mSource->readAt(offset, mMemory->unsecurePointer(), size);
63     }
getSize(off64_t * size)64     virtual status_t getSize(off64_t *size) {
65         Mutex::Autolock lock(mLock);
66         if (mSource.get() == nullptr) {
67             ALOGE("getSize() failed, mSource is nullptr");
68             return INVALID_OPERATION;
69         }
70         return mSource->getSize(size);
71     }
close()72     virtual void close() {
73         // Protect strong pointer assignments. This also can be called from the binder
74         // clean-up procedure which is running on a separate thread.
75         Mutex::Autolock lock(mLock);
76         mSource = nullptr;
77         mMemory = nullptr;
78     }
getFlags()79     virtual uint32_t getFlags() {
80         Mutex::Autolock lock(mLock);
81         if (mSource.get() == nullptr) {
82             ALOGE("getSize() failed, mSource is nullptr");
83             return 0;
84         }
85         return mSource->flags();
86     }
toString()87     virtual String8 toString()  {
88         return mName;
89     }
90 
91 private:
92     enum {
93         kBufferSize = 64 * 1024,
94     };
95 
96     sp<IMemory> mMemory;
97     sp<DataSource> mSource;
98     String8 mName;
99     Mutex mLock;
100 
RemoteDataSource(const sp<DataSource> & source)101     explicit RemoteDataSource(const sp<DataSource> &source) {
102         Mutex::Autolock lock(mLock);
103         mSource = source;
104         sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource");
105         mMemory = memoryDealer->allocate(kBufferSize);
106         if (mMemory.get() == nullptr) {
107             ALOGE("Failed to allocate memory!");
108         }
109         mName = String8::format("RemoteDataSource(%s)", mSource->toString().c_str());
110     }
111 
112     DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
113 };
114 
115 }  // namespace android
116 
117 #endif  // REMOTE_DATA_SOURCE_H_
118