blob: bb4ba75a46b3af4d90bdbf39521e11df1f2a91cf [file] [log] [blame]
Dongwon Kang9c6f7902019-10-14 11:16:39 -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
17//#define LOG_NDEBUG 0
18#define LOG_TAG "PlayerServiceFileSource"
19#include <utils/Log.h>
20
21#include <datasource/PlayerServiceFileSource.h>
22#include <media/stagefright/foundation/ADebug.h>
23#include <private/android_filesystem_config.h>
24
25namespace android {
26
27PlayerServiceFileSource::PlayerServiceFileSource(const char *filename)
28 : FileSource(filename),
29 mDecryptHandle(NULL),
30 mDrmManagerClient(NULL),
31 mDrmBufOffset(0),
32 mDrmBufSize(0),
33 mDrmBuf(NULL){
Marco Nelissen19b0be62019-11-15 07:51:15 -080034 (void) DrmInitialization(nullptr);
Dongwon Kang9c6f7902019-10-14 11:16:39 -070035}
36
37PlayerServiceFileSource::PlayerServiceFileSource(int fd, int64_t offset, int64_t length)
38 : FileSource(fd, offset, length),
39 mDecryptHandle(NULL),
40 mDrmManagerClient(NULL),
41 mDrmBufOffset(0),
42 mDrmBufSize(0),
43 mDrmBuf(NULL) {
Marco Nelissen19b0be62019-11-15 07:51:15 -080044 (void) DrmInitialization(nullptr);
Dongwon Kang9c6f7902019-10-14 11:16:39 -070045}
46
47PlayerServiceFileSource::~PlayerServiceFileSource() {
48 if (mDrmBuf != NULL) {
49 delete[] mDrmBuf;
50 mDrmBuf = NULL;
51 }
52
53 if (mDecryptHandle != NULL) {
54 // To release mDecryptHandle
55 CHECK(mDrmManagerClient);
56 mDrmManagerClient->closeDecryptSession(mDecryptHandle);
57 mDecryptHandle = NULL;
58 }
59
60 if (mDrmManagerClient != NULL) {
61 delete mDrmManagerClient;
62 mDrmManagerClient = NULL;
63 }
64}
65
66ssize_t PlayerServiceFileSource::readAt(off64_t offset, void *data, size_t size) {
67 if (mFd < 0) {
68 return NO_INIT;
69 }
70
71 Mutex::Autolock autoLock(mLock);
72
73 if (mLength >= 0) {
74 if (offset >= mLength) {
75 return 0; // read beyond EOF.
76 }
77 uint64_t numAvailable = mLength - offset;
78 if ((uint64_t)size > numAvailable) {
79 size = numAvailable;
80 }
81 }
82
83 if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
84 == mDecryptHandle->decryptApiType) {
85 return readAtDRM_l(offset, data, size);
86 } else {
87 return readAt_l(offset, data, size);
88 }
89}
90
91sp<DecryptHandle> PlayerServiceFileSource::DrmInitialization(const char *mime) {
Marco Nelissen19b0be62019-11-15 07:51:15 -080092 if (getuid() == AID_MEDIA_EX) {
93 return NULL; // no DRM in media extractor
94 }
Dongwon Kang9c6f7902019-10-14 11:16:39 -070095 if (mDrmManagerClient == NULL) {
96 mDrmManagerClient = new DrmManagerClient();
97 }
98
99 if (mDrmManagerClient == NULL) {
100 return NULL;
101 }
102
103 if (mDecryptHandle == NULL) {
104 mDecryptHandle = mDrmManagerClient->openDecryptSession(
105 mFd, mOffset, mLength, mime);
106 }
107
108 if (mDecryptHandle == NULL) {
109 delete mDrmManagerClient;
110 mDrmManagerClient = NULL;
111 }
112
113 return mDecryptHandle;
114}
115
116ssize_t PlayerServiceFileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
117 size_t DRM_CACHE_SIZE = 1024;
118 if (mDrmBuf == NULL) {
119 mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
120 }
121
122 if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset
123 && (offset + mOffset + size) <= static_cast<size_t>(mDrmBufOffset + mDrmBufSize)) {
124 /* Use buffered data */
125 memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size);
126 return size;
127 } else if (size <= DRM_CACHE_SIZE) {
128 /* Buffer new data */
129 mDrmBufOffset = offset + mOffset;
130 mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf,
131 DRM_CACHE_SIZE, offset + mOffset);
132 if (mDrmBufSize > 0) {
133 int64_t dataRead = 0;
134 dataRead = size > static_cast<size_t>(mDrmBufSize) ? mDrmBufSize : size;
135 memcpy(data, (void*)mDrmBuf, dataRead);
136 return dataRead;
137 } else {
138 return mDrmBufSize;
139 }
140 } else {
141 /* Too big chunk to cache. Call DRM directly */
142 return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset);
143 }
144}
145
146/* static */
147bool PlayerServiceFileSource::requiresDrm(int fd, int64_t offset, int64_t length, const char *mime) {
148 std::unique_ptr<DrmManagerClient> drmClient(new DrmManagerClient());
149 sp<DecryptHandle> decryptHandle =
150 drmClient->openDecryptSession(fd, offset, length, mime);
151 bool requiresDrm = false;
152 if (decryptHandle != nullptr) {
153 requiresDrm = decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED;
154 drmClient->closeDecryptSession(decryptHandle);
155 }
156 return requiresDrm;
157}
158
159} // namespace android