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