FileSource.cpp revision d066bc8faf68b9fcb034ceb203e8d7e8213dc1ce
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 174f82a25c07c3ffc8d44d61797043f9864058afdfMarco Nelissen//#define LOG_NDEBUG 0 184f82a25c07c3ffc8d44d61797043f9864058afdfMarco Nelissen#define LOG_TAG "FileSource" 194f82a25c07c3ffc8d44d61797043f9864058afdfMarco Nelissen#include <utils/Log.h> 204f82a25c07c3ffc8d44d61797043f9864058afdfMarco Nelissen 21f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/FileSource.h> 23c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong#include <sys/types.h> 24c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong#include <unistd.h> 25674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <sys/types.h> 26674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <sys/stat.h> 27674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <fcntl.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberFileSource::FileSource(const char *filename) 32674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(-1), 3303475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber mOffset(0), 34dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mLength(-1), 35dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDecryptHandle(NULL), 36dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmManagerClient(NULL), 37dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufOffset(0), 38dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufSize(0), 39dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf(NULL){ 40674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong 41674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = open(filename, O_LARGEFILE | O_RDONLY); 424ee31e2603b4019e4ae76e027115f80b818527aaAndreas Huber 434ee31e2603b4019e4ae76e027115f80b818527aaAndreas Huber if (mFd >= 0) { 444ee31e2603b4019e4ae76e027115f80b818527aaAndreas Huber mLength = lseek64(mFd, 0, SEEK_END); 45f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber } else { 46f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber ALOGE("Failed to open file '%s'. (%s)", filename, strerror(errno)); 474ee31e2603b4019e4ae76e027115f80b818527aaAndreas Huber } 4803475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber} 4903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 5003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas HuberFileSource::FileSource(int fd, int64_t offset, int64_t length) 51674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(fd), 5203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber mOffset(offset), 53dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mLength(length), 54dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDecryptHandle(NULL), 55dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmManagerClient(NULL), 56dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufOffset(0), 57dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufSize(0), 58dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf(NULL){ 5903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber CHECK(offset >= 0); 6003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber CHECK(length >= 0); 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberFileSource::~FileSource() { 64674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd >= 0) { 65674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 66674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 69dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBuf != NULL) { 70dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete[] mDrmBuf; 71dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf = NULL; 72dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 73889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang 74889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDecryptHandle != NULL) { 75889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang // To release mDecryptHandle 768f64134f749e4f7861a08a3063450fc714c4651dGloria Wang CHECK(mDrmManagerClient); 77889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDrmManagerClient->closeDecryptSession(mDecryptHandle); 78889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDecryptHandle = NULL; 79889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang } 80889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang 81889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDrmManagerClient != NULL) { 82889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang delete mDrmManagerClient; 83889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDrmManagerClient = NULL; 84889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang } 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huberstatus_t FileSource::initCheck() const { 88674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong return mFd >= 0 ? OK : NO_INIT; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t FileSource::readAt(off64_t offset, void *data, size_t size) { 92674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd < 0) { 933d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber return NO_INIT; 943d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber } 953d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9803475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if (mLength >= 0) { 9903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if (offset >= mLength) { 10003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber return 0; // read beyond EOF. 10103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 10203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber int64_t numAvailable = mLength - offset; 10303475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if ((int64_t)size > numAvailable) { 10403475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber size = numAvailable; 10503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 10603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 10703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 108dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED 109dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang == mDecryptHandle->decryptApiType) { 110dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return readAtDRM(offset, data, size); 111dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 112c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET); 113c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (result == -1) { 114ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("seek to %lld failed", (long long)(offset + mOffset)); 115dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; 116dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong return ::read(mFd, data, size); 119dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 12003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber} 12103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 122c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t FileSource::getSize(off64_t *size) { 1233a13fad63af40a8364fce796b1a54a8f0a2fbf32Andreas Huber Mutex::Autolock autoLock(mLock); 1243a13fad63af40a8364fce796b1a54a8f0a2fbf32Andreas Huber 125674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd < 0) { 1263d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber return NO_INIT; 1273d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber } 1283d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber 1294ee31e2603b4019e4ae76e027115f80b818527aaAndreas Huber *size = mLength; 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber return OK; 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1349d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongsp<DecryptHandle> FileSource::DrmInitialization(const char *mime) { 135889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDrmManagerClient == NULL) { 136889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDrmManagerClient = new DrmManagerClient(); 137889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang } 138889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang 139889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDrmManagerClient == NULL) { 140b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang return NULL; 141b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang } 142b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 143dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDecryptHandle == NULL) { 144dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDecryptHandle = mDrmManagerClient->openDecryptSession( 1459d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong mFd, mOffset, mLength, mime); 146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 148dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDecryptHandle == NULL) { 149889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang delete mDrmManagerClient; 150dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmManagerClient = NULL; 151dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 152dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 153dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return mDecryptHandle; 154dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 155dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 156b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangvoid FileSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) { 157b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang handle = mDecryptHandle; 158dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 159dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *client = mDrmManagerClient; 160dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 161dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 162c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t FileSource::readAtDRM(off64_t offset, void *data, size_t size) { 163dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t DRM_CACHE_SIZE = 1024; 164dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBuf == NULL) { 165dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf = new unsigned char[DRM_CACHE_SIZE]; 166dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 167dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 168dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset 169d066bc8faf68b9fcb034ceb203e8d7e8213dc1cePatrik Lindgren && (offset + mOffset + size) <= static_cast<size_t>(mDrmBufOffset + mDrmBufSize)) { 170dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang /* Use buffered data */ 171dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size); 172dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 173dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (size <= DRM_CACHE_SIZE) { 174dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang /* Buffer new data */ 175dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufOffset = offset + mOffset; 176dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf, 177dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang DRM_CACHE_SIZE, offset + mOffset); 178dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBufSize > 0) { 179dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int64_t dataRead = 0; 180d066bc8faf68b9fcb034ceb203e8d7e8213dc1cePatrik Lindgren dataRead = size > static_cast<size_t>(mDrmBufSize) ? mDrmBufSize : size; 181dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(data, (void*)mDrmBuf, dataRead); 182dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return dataRead; 183dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 184dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return mDrmBufSize; 185dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 186dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 187dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang /* Too big chunk to cache. Call DRM directly */ 188dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset); 189dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 190dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 192