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 <binder/IMemory.h> 21#include <binder/MemoryDealer.h> 22#include <media/DataSource.h> 23#include <media/IDataSource.h> 24 25namespace android { 26 27// Originally in MediaExtractor.cpp 28class RemoteDataSource : public BnDataSource { 29public: 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 40 virtual ~RemoteDataSource() { 41 close(); 42 } 43 virtual sp<IMemory> getIMemory() { 44 return mMemory; 45 } 46 virtual ssize_t readAt(off64_t offset, size_t size) { 47 ALOGV("readAt(%lld, %zu)", (long long)offset, size); 48 if (size > kBufferSize) { 49 size = kBufferSize; 50 } 51 return mSource->readAt(offset, mMemory->pointer(), size); 52 } 53 virtual status_t getSize(off64_t *size) { 54 return mSource->getSize(size); 55 } 56 virtual void close() { 57 // Protect strong pointer assignments. This also can be called from the binder 58 // clean-up procedure which is running on a separate thread. 59 Mutex::Autolock lock(mCloseLock); 60 mSource = nullptr; 61 mMemory = nullptr; 62 } 63 virtual uint32_t getFlags() { 64 return mSource->flags(); 65 } 66 virtual String8 toString() { 67 return mName; 68 } 69 virtual sp<DecryptHandle> DrmInitialization(const char *mime) { 70 return mSource->DrmInitialization(mime); 71 } 72 73private: 74 enum { 75 kBufferSize = 64 * 1024, 76 }; 77 78 sp<IMemory> mMemory; 79 sp<DataSource> mSource; 80 String8 mName; 81 Mutex mCloseLock; 82 83 explicit RemoteDataSource(const sp<DataSource> &source) { 84 mSource = source; 85 sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource"); 86 mMemory = memoryDealer->allocate(kBufferSize); 87 if (mMemory.get() == nullptr) { 88 ALOGE("Failed to allocate memory!"); 89 } 90 mName = String8::format("RemoteDataSource(%s)", mSource->toString().string()); 91 } 92 93 DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource); 94}; 95 96} // namespace android 97 98#endif // REMOTE_DATA_SOURCE_H_ 99