blob: 65780e348075efb1e45424efeae0617194844ddf [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
2 * Copyright (C) 2009 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
Marco Nelissen4f82a252014-12-22 10:18:15 -080017//#define LOG_NDEBUG 0
18#define LOG_TAG "FileSource"
19#include <utils/Log.h>
20
Marco Nelissenfa8be7d2019-09-23 12:15:57 -070021#include <datasource/FileSource.h>
James Dongf1d5aa12012-02-06 23:46:37 -080022#include <media/stagefright/foundation/ADebug.h>
Andy Hungd49dbd62016-07-07 14:20:35 -070023#include <private/android_filesystem_config.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070024
25namespace android {
26
27FileSource::FileSource(const char *filename)
Dongwon Kang1e1bcaa2018-08-01 12:44:46 -070028 : ClearFileSource(filename),
Gloria Wangdcd25ef2010-06-22 13:55:38 -070029 mDecryptHandle(NULL),
30 mDrmManagerClient(NULL),
31 mDrmBufOffset(0),
32 mDrmBufSize(0),
33 mDrmBuf(NULL){
Andreas Huber03475f52009-11-16 15:34:01 -080034}
35
36FileSource::FileSource(int fd, int64_t offset, int64_t length)
Dongwon Kang1e1bcaa2018-08-01 12:44:46 -070037 : ClearFileSource(fd, offset, length),
Gloria Wangdcd25ef2010-06-22 13:55:38 -070038 mDecryptHandle(NULL),
39 mDrmManagerClient(NULL),
40 mDrmBufOffset(0),
41 mDrmBufSize(0),
Marco Nelissen63690d12016-04-06 09:28:05 -070042 mDrmBuf(NULL) {
Andreas Huber20111aa2009-07-14 16:56:47 -070043}
44
45FileSource::~FileSource() {
Gloria Wangdcd25ef2010-06-22 13:55:38 -070046 if (mDrmBuf != NULL) {
47 delete[] mDrmBuf;
48 mDrmBuf = NULL;
49 }
Gloria Wang889b3402011-02-07 11:41:11 -080050
51 if (mDecryptHandle != NULL) {
52 // To release mDecryptHandle
Gloria Wang8f641342011-02-08 13:24:08 -080053 CHECK(mDrmManagerClient);
Gloria Wang889b3402011-02-07 11:41:11 -080054 mDrmManagerClient->closeDecryptSession(mDecryptHandle);
55 mDecryptHandle = NULL;
56 }
57
58 if (mDrmManagerClient != NULL) {
59 delete mDrmManagerClient;
60 mDrmManagerClient = NULL;
61 }
Andreas Huber20111aa2009-07-14 16:56:47 -070062}
63
James Dongc7fc37a2010-11-16 14:04:54 -080064ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
James Dong674ebd02010-11-18 20:59:13 -080065 if (mFd < 0) {
Andreas Huber3d8055a2010-05-24 09:18:36 -070066 return NO_INIT;
67 }
68
Andreas Huber20111aa2009-07-14 16:56:47 -070069 Mutex::Autolock autoLock(mLock);
70
Andreas Huber03475f52009-11-16 15:34:01 -080071 if (mLength >= 0) {
72 if (offset >= mLength) {
73 return 0; // read beyond EOF.
74 }
Wei Jia0eaf8202015-08-19 16:48:47 -070075 uint64_t numAvailable = mLength - offset;
76 if ((uint64_t)size > numAvailable) {
Andreas Huber03475f52009-11-16 15:34:01 -080077 size = numAvailable;
78 }
79 }
80
Gloria Wangdcd25ef2010-06-22 13:55:38 -070081 if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
82 == mDecryptHandle->decryptApiType) {
Dongwon Kang1e1bcaa2018-08-01 12:44:46 -070083 return readAtDRM_l(offset, data, size);
Gloria Wangdcd25ef2010-06-22 13:55:38 -070084 } else {
Dongwon Kang1e1bcaa2018-08-01 12:44:46 -070085 return readAt_l(offset, data, size);
Gloria Wangdcd25ef2010-06-22 13:55:38 -070086 }
Andreas Huber03475f52009-11-16 15:34:01 -080087}
Andreas Huber20111aa2009-07-14 16:56:47 -070088
James Dong9d2f3862012-01-10 08:24:37 -080089sp<DecryptHandle> FileSource::DrmInitialization(const char *mime) {
Andy Hungd49dbd62016-07-07 14:20:35 -070090 if (getuid() == AID_MEDIA_EX) return nullptr; // no DRM in media extractor
Gloria Wang889b3402011-02-07 11:41:11 -080091 if (mDrmManagerClient == NULL) {
92 mDrmManagerClient = new DrmManagerClient();
93 }
94
95 if (mDrmManagerClient == NULL) {
Gloria Wangb3714262010-11-01 15:53:16 -070096 return NULL;
97 }
Gloria Wangb3714262010-11-01 15:53:16 -070098
Gloria Wangdcd25ef2010-06-22 13:55:38 -070099 if (mDecryptHandle == NULL) {
100 mDecryptHandle = mDrmManagerClient->openDecryptSession(
James Dong9d2f3862012-01-10 08:24:37 -0800101 mFd, mOffset, mLength, mime);
Gloria Wangdcd25ef2010-06-22 13:55:38 -0700102 }
103
104 if (mDecryptHandle == NULL) {
Gloria Wang889b3402011-02-07 11:41:11 -0800105 delete mDrmManagerClient;
Gloria Wangdcd25ef2010-06-22 13:55:38 -0700106 mDrmManagerClient = NULL;
107 }
108
109 return mDecryptHandle;
110}
111
Dongwon Kang1e1bcaa2018-08-01 12:44:46 -0700112ssize_t FileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
Gloria Wangdcd25ef2010-06-22 13:55:38 -0700113 size_t DRM_CACHE_SIZE = 1024;
114 if (mDrmBuf == NULL) {
115 mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
116 }
117
118 if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset
Patrik Lindgrend066bc82014-12-22 09:06:21 +0100119 && (offset + mOffset + size) <= static_cast<size_t>(mDrmBufOffset + mDrmBufSize)) {
Gloria Wangdcd25ef2010-06-22 13:55:38 -0700120 /* Use buffered data */
121 memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size);
122 return size;
123 } else if (size <= DRM_CACHE_SIZE) {
124 /* Buffer new data */
125 mDrmBufOffset = offset + mOffset;
126 mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf,
127 DRM_CACHE_SIZE, offset + mOffset);
128 if (mDrmBufSize > 0) {
129 int64_t dataRead = 0;
Patrik Lindgrend066bc82014-12-22 09:06:21 +0100130 dataRead = size > static_cast<size_t>(mDrmBufSize) ? mDrmBufSize : size;
Gloria Wangdcd25ef2010-06-22 13:55:38 -0700131 memcpy(data, (void*)mDrmBuf, dataRead);
132 return dataRead;
133 } else {
134 return mDrmBufSize;
135 }
136 } else {
137 /* Too big chunk to cache. Call DRM directly */
138 return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset);
139 }
140}
Andy Hungd49dbd62016-07-07 14:20:35 -0700141
142/* static */
143bool FileSource::requiresDrm(int fd, int64_t offset, int64_t length, const char *mime) {
144 std::unique_ptr<DrmManagerClient> drmClient(new DrmManagerClient());
145 sp<DecryptHandle> decryptHandle =
146 drmClient->openDecryptSession(fd, offset, length, mime);
147 bool requiresDrm = false;
148 if (decryptHandle != nullptr) {
149 requiresDrm = decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED;
150 drmClient->closeDecryptSession(decryptHandle);
151 }
152 return requiresDrm;
153}
154
Andreas Huber20111aa2009-07-14 16:56:47 -0700155} // namespace android