blob: 0b927ef9a830e5761ecaf65711439ec56f2a65a8 [file] [log] [blame]
Ronghua Wu10305cc2015-02-22 07:55:32 -08001/*
2 * Copyright (C) 2015 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 "DrmSessionManager"
19#include <utils/Log.h>
20
Ronghua Wu10305cc2015-02-22 07:55:32 -080021#include <binder/IPCThreadState.h>
Ronghua Wu5c3da202015-02-22 08:45:28 -080022#include <binder/IProcessInfoService.h>
23#include <binder/IServiceManager.h>
Robert Shih79673cf2019-09-20 21:45:01 -070024#include <cutils/properties.h>
25#include <media/IResourceManagerClient.h>
26#include <media/MediaResource.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080027#include <mediadrm/DrmSessionManager.h>
Ronghua Wu10305cc2015-02-22 07:55:32 -080028#include <unistd.h>
29#include <utils/String8.h>
30
Robert Shih79673cf2019-09-20 21:45:01 -070031#include <vector>
32
33#include "ResourceManagerService.h"
34
Ronghua Wu10305cc2015-02-22 07:55:32 -080035namespace android {
36
37static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
38 String8 sessionIdStr;
39 for (size_t i = 0; i < sessionId.size(); ++i) {
40 sessionIdStr.appendFormat("%u ", sessionId[i]);
41 }
42 return sessionIdStr;
43}
44
Robert Shih79673cf2019-09-20 21:45:01 -070045static std::vector<uint8_t> toStdVec(const Vector<uint8_t> &vector) {
46 const uint8_t *v = vector.array();
47 std::vector<uint8_t> vec(v, v + vector.size());
48 return vec;
49}
50
51static uint64_t toClientId(const sp<IResourceManagerClient>& drm) {
52 return reinterpret_cast<int64_t>(drm.get());
53}
54
55static Vector<MediaResource> toResourceVec(const Vector<uint8_t> &sessionId) {
56 Vector<MediaResource> resources;
57 // use UINT64_MAX to decrement through addition overflow
58 resources.push_back(MediaResource(MediaResource::kDrmSession, toStdVec(sessionId), UINT64_MAX));
59 return resources;
60}
61
62static sp<IResourceManagerService> getResourceManagerService() {
63 if (property_get_bool("persist.device_config.media_native.mediadrmserver", 1)) {
64 return new ResourceManagerService();
65 }
66 sp<IServiceManager> sm = defaultServiceManager();
67 if (sm == NULL) {
68 return NULL;
69 }
70 sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
71 return interface_cast<IResourceManagerService>(binder);
72}
73
Ronghua Wu10305cc2015-02-22 07:55:32 -080074bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
75 if (sessionId1.size() != sessionId2.size()) {
76 return false;
77 }
78 for (size_t i = 0; i < sessionId1.size(); ++i) {
79 if (sessionId1[i] != sessionId2[i]) {
80 return false;
81 }
82 }
83 return true;
84}
85
Ronghua Wu5c3da202015-02-22 08:45:28 -080086sp<DrmSessionManager> DrmSessionManager::Instance() {
87 static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
Robert Shih79673cf2019-09-20 21:45:01 -070088 drmSessionManager->init();
Ronghua Wu5c3da202015-02-22 08:45:28 -080089 return drmSessionManager;
90}
91
Ronghua Wu10305cc2015-02-22 07:55:32 -080092DrmSessionManager::DrmSessionManager()
Robert Shih79673cf2019-09-20 21:45:01 -070093 : DrmSessionManager(getResourceManagerService()) {
94}
Ronghua Wu10305cc2015-02-22 07:55:32 -080095
Robert Shih79673cf2019-09-20 21:45:01 -070096DrmSessionManager::DrmSessionManager(const sp<IResourceManagerService> &service)
97 : mService(service),
98 mInitialized(false) {
99 if (mService == NULL) {
100 ALOGE("Failed to init ResourceManagerService");
101 }
102}
Ronghua Wu10305cc2015-02-22 07:55:32 -0800103
Robert Shih79673cf2019-09-20 21:45:01 -0700104DrmSessionManager::~DrmSessionManager() {
105 if (mService != NULL) {
106 IInterface::asBinder(mService)->unlinkToDeath(this);
107 }
108}
Ronghua Wu10305cc2015-02-22 07:55:32 -0800109
Robert Shih79673cf2019-09-20 21:45:01 -0700110void DrmSessionManager::init() {
111 Mutex::Autolock lock(mLock);
112 if (mInitialized) {
113 return;
114 }
115 mInitialized = true;
116 if (mService != NULL) {
117 IInterface::asBinder(mService)->linkToDeath(this);
118 }
119}
120
121void DrmSessionManager::addSession(int pid,
122 const sp<IResourceManagerClient>& drm, const Vector<uint8_t> &sessionId) {
123 uid_t uid = IPCThreadState::self()->getCallingUid();
124 ALOGV("addSession(pid %d, uid %d, drm %p, sessionId %s)", pid, uid, drm.get(),
Ronghua Wu10305cc2015-02-22 07:55:32 -0800125 GetSessionIdString(sessionId).string());
126
127 Mutex::Autolock lock(mLock);
Robert Shih79673cf2019-09-20 21:45:01 -0700128 if (mService == NULL) {
129 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800130 }
Robert Shih79673cf2019-09-20 21:45:01 -0700131
132 int64_t clientId = toClientId(drm);
133 mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
134 mService->addResource(pid, uid, clientId, drm, toResourceVec(sessionId));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800135}
136
137void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
138 ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
139
140 Mutex::Autolock lock(mLock);
Robert Shih79673cf2019-09-20 21:45:01 -0700141 auto it = mSessionMap.find(toStdVec(sessionId));
142 if (mService == NULL || it == mSessionMap.end()) {
143 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800144 }
Robert Shih79673cf2019-09-20 21:45:01 -0700145
146 auto info = it->second;
147 mService->addResource(info.pid, info.uid, info.clientId, NULL, toResourceVec(sessionId));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800148}
149
150void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
151 ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
152
153 Mutex::Autolock lock(mLock);
Robert Shih79673cf2019-09-20 21:45:01 -0700154 auto it = mSessionMap.find(toStdVec(sessionId));
155 if (mService == NULL || it == mSessionMap.end()) {
156 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800157 }
Ronghua Wu10305cc2015-02-22 07:55:32 -0800158
Robert Shih79673cf2019-09-20 21:45:01 -0700159 auto info = it->second;
160 mService->removeResource(info.pid, info.clientId, toResourceVec(sessionId));
161 mSessionMap.erase(it);
Ronghua Wu10305cc2015-02-22 07:55:32 -0800162}
163
164bool DrmSessionManager::reclaimSession(int callingPid) {
165 ALOGV("reclaimSession(%d)", callingPid);
166
Robert Shih79673cf2019-09-20 21:45:01 -0700167 // unlock early because reclaimResource might callback into removeSession
168 mLock.lock();
169 sp<IResourceManagerService> service(mService);
170 mLock.unlock();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800171
Robert Shih79673cf2019-09-20 21:45:01 -0700172 if (service == NULL) {
Ronghua Wu10305cc2015-02-22 07:55:32 -0800173 return false;
174 }
175
Robert Shih79673cf2019-09-20 21:45:01 -0700176 // cannot update mSessionMap because we do not know which sessionId is reclaimed;
177 // we rely on IResourceManagerClient to removeSession in reclaimResource
178 Vector<uint8_t> dummy;
179 return service->reclaimResource(callingPid, toResourceVec(dummy));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800180}
181
Robert Shih79673cf2019-09-20 21:45:01 -0700182size_t DrmSessionManager::getSessionCount() const {
183 Mutex::Autolock lock(mLock);
184 return mSessionMap.size();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800185}
186
Robert Shih79673cf2019-09-20 21:45:01 -0700187bool DrmSessionManager::containsSession(const Vector<uint8_t>& sessionId) const {
188 Mutex::Autolock lock(mLock);
189 return mSessionMap.count(toStdVec(sessionId));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800190}
191
Robert Shih79673cf2019-09-20 21:45:01 -0700192void DrmSessionManager::binderDied(const wp<IBinder>& /*who*/) {
193 ALOGW("ResourceManagerService died.");
194 Mutex::Autolock lock(mLock);
195 mService.clear();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800196}
197
198} // namespace android