FileSource.cpp revision 8f64134f749e4f7861a08a3063450fc714c4651d
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 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/FileSource.h> 180c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 19c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong#include <sys/types.h> 20c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong#include <unistd.h> 21674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <sys/types.h> 22674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <sys/stat.h> 23674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <fcntl.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberFileSource::FileSource(const char *filename) 28674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(-1), 2903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber mOffset(0), 30dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mLength(-1), 31dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDecryptHandle(NULL), 32dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmManagerClient(NULL), 33dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufOffset(0), 34dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufSize(0), 35dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf(NULL){ 36674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong 37674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = open(filename, O_LARGEFILE | O_RDONLY); 3803475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber} 3903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 4003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas HuberFileSource::FileSource(int fd, int64_t offset, int64_t length) 41674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(fd), 4203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber mOffset(offset), 43dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mLength(length), 44dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDecryptHandle(NULL), 45dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmManagerClient(NULL), 46dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufOffset(0), 47dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufSize(0), 48dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf(NULL){ 4903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber CHECK(offset >= 0); 5003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber CHECK(length >= 0); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberFileSource::~FileSource() { 54674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd >= 0) { 55674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 56674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 59dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBuf != NULL) { 60dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete[] mDrmBuf; 61dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf = NULL; 62dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 63889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang 64889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDecryptHandle != NULL) { 65889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang // To release mDecryptHandle 668f64134f749e4f7861a08a3063450fc714c4651dGloria Wang CHECK(mDrmManagerClient); 67889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDrmManagerClient->closeDecryptSession(mDecryptHandle); 68889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDecryptHandle = NULL; 69889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang } 70889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang 71889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDrmManagerClient != NULL) { 72889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang delete mDrmManagerClient; 73889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDrmManagerClient = NULL; 74889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang } 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huberstatus_t FileSource::initCheck() const { 78674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong return mFd >= 0 ? OK : NO_INIT; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t FileSource::readAt(off64_t offset, void *data, size_t size) { 82674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd < 0) { 833d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber return NO_INIT; 843d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber } 853d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8803475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if (mLength >= 0) { 8903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if (offset >= mLength) { 9003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber return 0; // read beyond EOF. 9103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 9203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber int64_t numAvailable = mLength - offset; 9303475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if ((int64_t)size > numAvailable) { 9403475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber size = numAvailable; 9503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 9603475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 9703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 98dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED 99dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang == mDecryptHandle->decryptApiType) { 100dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return readAtDRM(offset, data, size); 101dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 102c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET); 103c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (result == -1) { 104dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang LOGE("seek to %lld failed", offset + mOffset); 105dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; 106dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong return ::read(mFd, data, size); 109dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 11003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber} 11103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 112c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t FileSource::getSize(off64_t *size) { 113674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd < 0) { 1143d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber return NO_INIT; 1153d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber } 1163d8055ac96170de7a8c49b9ffbe83ed447ccddceAndreas Huber 11703475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber if (mLength >= 0) { 11803475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber *size = mLength; 11903475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 12003475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber return OK; 12103475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber } 12203475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber 123c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong *size = lseek64(mFd, 0, SEEK_END); 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12503475f5af25e4aa32d46d41dd2ec756853d8dd9dAndreas Huber return OK; 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128889b340ec736a9d3e3e690256d305cc8740f0c4bGloria WangDecryptHandle* FileSource::DrmInitialization() { 129889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDrmManagerClient == NULL) { 130889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang mDrmManagerClient = new DrmManagerClient(); 131889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang } 132889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang 133889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang if (mDrmManagerClient == NULL) { 134b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang return NULL; 135b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang } 136b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 137dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDecryptHandle == NULL) { 138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDecryptHandle = mDrmManagerClient->openDecryptSession( 139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFd, mOffset, mLength); 140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 141dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 142dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDecryptHandle == NULL) { 143889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang delete mDrmManagerClient; 144dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmManagerClient = NULL; 145dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return mDecryptHandle; 148dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 149dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 150dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangvoid FileSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) { 151dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *handle = mDecryptHandle; 152dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 153dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *client = mDrmManagerClient; 154dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 155dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 156c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t FileSource::readAtDRM(off64_t offset, void *data, size_t size) { 157dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t DRM_CACHE_SIZE = 1024; 158dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBuf == NULL) { 159dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBuf = new unsigned char[DRM_CACHE_SIZE]; 160dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 161dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 162dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset 163dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang && (offset + mOffset + size) <= (mDrmBufOffset + mDrmBufSize)) { 164dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang /* Use buffered data */ 165dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size); 166dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 167dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (size <= DRM_CACHE_SIZE) { 168dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang /* Buffer new data */ 169dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufOffset = offset + mOffset; 170dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf, 171dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang DRM_CACHE_SIZE, offset + mOffset); 172dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDrmBufSize > 0) { 173dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int64_t dataRead = 0; 174dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataRead = size > mDrmBufSize ? mDrmBufSize : size; 175dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(data, (void*)mDrmBuf, dataRead); 176dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return dataRead; 177dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 178dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return mDrmBufSize; 179dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 180dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 181dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang /* Too big chunk to cache. Call DRM directly */ 182dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset); 183dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 184dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 186