blob: 165a4d6916b9ad25d487f248a752da64d9b19fbf [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
Chong Zhang181e6952019-10-09 13:23:39 -070021#include <android/media/IResourceManagerClient.h>
22#include <android/media/IResourceManagerService.h>
Ronghua Wu10305cc2015-02-22 07:55:32 -080023#include <binder/IPCThreadState.h>
Ronghua Wu5c3da202015-02-22 08:45:28 -080024#include <binder/IProcessInfoService.h>
25#include <binder/IServiceManager.h>
Robert Shihc3af31b2019-09-20 21:45:01 -070026#include <cutils/properties.h>
Robert Shihc3af31b2019-09-20 21:45:01 -070027#include <media/MediaResource.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070028#include <mediadrm/DrmUtils.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080029#include <mediadrm/DrmSessionManager.h>
Ronghua Wu10305cc2015-02-22 07:55:32 -080030#include <unistd.h>
31#include <utils/String8.h>
32
Robert Shihc3af31b2019-09-20 21:45:01 -070033#include <vector>
34
35#include "ResourceManagerService.h"
36
Ronghua Wu10305cc2015-02-22 07:55:32 -080037namespace android {
Chong Zhang181e6952019-10-09 13:23:39 -070038using android::binder::Status;
Ronghua Wu10305cc2015-02-22 07:55:32 -080039
40static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
41 String8 sessionIdStr;
42 for (size_t i = 0; i < sessionId.size(); ++i) {
43 sessionIdStr.appendFormat("%u ", sessionId[i]);
44 }
45 return sessionIdStr;
46}
47
Robert Shihc3af31b2019-09-20 21:45:01 -070048static std::vector<uint8_t> toStdVec(const Vector<uint8_t> &vector) {
49 const uint8_t *v = vector.array();
50 std::vector<uint8_t> vec(v, v + vector.size());
51 return vec;
52}
53
54static uint64_t toClientId(const sp<IResourceManagerClient>& drm) {
55 return reinterpret_cast<int64_t>(drm.get());
56}
57
Chong Zhang181e6952019-10-09 13:23:39 -070058static std::vector<MediaResourceParcel> toResourceVec(
59 const Vector<uint8_t> &sessionId, int64_t value) {
60 std::vector<MediaResourceParcel> resources;
61 resources.push_back(MediaResource::DrmSessionResource(toStdVec(sessionId), value));
Robert Shihc3af31b2019-09-20 21:45:01 -070062 return resources;
63}
64
65static sp<IResourceManagerService> getResourceManagerService() {
Robert Shih28c2ed32019-10-27 22:55:12 -070066 if (DrmUtils::UseDrmService()) {
67 // Create ResourceManagerService object in mediadrmserver process
Chong Zhang181e6952019-10-09 13:23:39 -070068 return new android::media::ResourceManagerService();
Robert Shihc3af31b2019-09-20 21:45:01 -070069 }
70 sp<IServiceManager> sm = defaultServiceManager();
71 if (sm == NULL) {
72 return NULL;
73 }
74 sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
75 return interface_cast<IResourceManagerService>(binder);
76}
77
Ronghua Wu10305cc2015-02-22 07:55:32 -080078bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
79 if (sessionId1.size() != sessionId2.size()) {
80 return false;
81 }
82 for (size_t i = 0; i < sessionId1.size(); ++i) {
83 if (sessionId1[i] != sessionId2[i]) {
84 return false;
85 }
86 }
87 return true;
88}
89
Ronghua Wu5c3da202015-02-22 08:45:28 -080090sp<DrmSessionManager> DrmSessionManager::Instance() {
91 static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
Robert Shihc3af31b2019-09-20 21:45:01 -070092 drmSessionManager->init();
Ronghua Wu5c3da202015-02-22 08:45:28 -080093 return drmSessionManager;
94}
95
Ronghua Wu10305cc2015-02-22 07:55:32 -080096DrmSessionManager::DrmSessionManager()
Robert Shihc3af31b2019-09-20 21:45:01 -070097 : DrmSessionManager(getResourceManagerService()) {
98}
Ronghua Wu10305cc2015-02-22 07:55:32 -080099
Robert Shihc3af31b2019-09-20 21:45:01 -0700100DrmSessionManager::DrmSessionManager(const sp<IResourceManagerService> &service)
101 : mService(service),
102 mInitialized(false) {
103 if (mService == NULL) {
104 ALOGE("Failed to init ResourceManagerService");
105 }
106}
Ronghua Wu10305cc2015-02-22 07:55:32 -0800107
Robert Shihc3af31b2019-09-20 21:45:01 -0700108DrmSessionManager::~DrmSessionManager() {
109 if (mService != NULL) {
110 IInterface::asBinder(mService)->unlinkToDeath(this);
111 }
112}
Ronghua Wu10305cc2015-02-22 07:55:32 -0800113
Robert Shihc3af31b2019-09-20 21:45:01 -0700114void DrmSessionManager::init() {
115 Mutex::Autolock lock(mLock);
116 if (mInitialized) {
117 return;
118 }
119 mInitialized = true;
120 if (mService != NULL) {
121 IInterface::asBinder(mService)->linkToDeath(this);
122 }
123}
124
125void DrmSessionManager::addSession(int pid,
126 const sp<IResourceManagerClient>& drm, const Vector<uint8_t> &sessionId) {
127 uid_t uid = IPCThreadState::self()->getCallingUid();
128 ALOGV("addSession(pid %d, uid %d, drm %p, sessionId %s)", pid, uid, drm.get(),
Ronghua Wu10305cc2015-02-22 07:55:32 -0800129 GetSessionIdString(sessionId).string());
130
131 Mutex::Autolock lock(mLock);
Robert Shihc3af31b2019-09-20 21:45:01 -0700132 if (mService == NULL) {
133 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800134 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700135
136 int64_t clientId = toClientId(drm);
137 mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
Chong Zhang181e6952019-10-09 13:23:39 -0700138 mService->addResource(pid, uid, clientId, drm, toResourceVec(sessionId, INT64_MAX));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800139}
140
141void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
142 ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
143
144 Mutex::Autolock lock(mLock);
Robert Shihc3af31b2019-09-20 21:45:01 -0700145 auto it = mSessionMap.find(toStdVec(sessionId));
146 if (mService == NULL || it == mSessionMap.end()) {
147 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800148 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700149
150 auto info = it->second;
Chong Zhang181e6952019-10-09 13:23:39 -0700151 mService->addResource(info.pid, info.uid, info.clientId, NULL, toResourceVec(sessionId, -1));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800152}
153
154void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
155 ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
156
157 Mutex::Autolock lock(mLock);
Robert Shihc3af31b2019-09-20 21:45:01 -0700158 auto it = mSessionMap.find(toStdVec(sessionId));
159 if (mService == NULL || it == mSessionMap.end()) {
160 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800161 }
Ronghua Wu10305cc2015-02-22 07:55:32 -0800162
Robert Shihc3af31b2019-09-20 21:45:01 -0700163 auto info = it->second;
Chong Zhang181e6952019-10-09 13:23:39 -0700164 mService->removeResource(info.pid, info.clientId, toResourceVec(sessionId, INT64_MAX));
Robert Shihc3af31b2019-09-20 21:45:01 -0700165 mSessionMap.erase(it);
Ronghua Wu10305cc2015-02-22 07:55:32 -0800166}
167
168bool DrmSessionManager::reclaimSession(int callingPid) {
169 ALOGV("reclaimSession(%d)", callingPid);
170
Robert Shihc3af31b2019-09-20 21:45:01 -0700171 // unlock early because reclaimResource might callback into removeSession
172 mLock.lock();
173 sp<IResourceManagerService> service(mService);
174 mLock.unlock();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800175
Robert Shihc3af31b2019-09-20 21:45:01 -0700176 if (service == NULL) {
Ronghua Wu10305cc2015-02-22 07:55:32 -0800177 return false;
178 }
179
Robert Shihc3af31b2019-09-20 21:45:01 -0700180 // cannot update mSessionMap because we do not know which sessionId is reclaimed;
181 // we rely on IResourceManagerClient to removeSession in reclaimResource
182 Vector<uint8_t> dummy;
Chong Zhang181e6952019-10-09 13:23:39 -0700183 bool success;
184 Status status = service->reclaimResource(callingPid, toResourceVec(dummy, INT64_MAX), &success);
185 return status.isOk() && success;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800186}
187
Robert Shihc3af31b2019-09-20 21:45:01 -0700188size_t DrmSessionManager::getSessionCount() const {
189 Mutex::Autolock lock(mLock);
190 return mSessionMap.size();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800191}
192
Robert Shihc3af31b2019-09-20 21:45:01 -0700193bool DrmSessionManager::containsSession(const Vector<uint8_t>& sessionId) const {
194 Mutex::Autolock lock(mLock);
195 return mSessionMap.count(toStdVec(sessionId));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800196}
197
Robert Shihc3af31b2019-09-20 21:45:01 -0700198void DrmSessionManager::binderDied(const wp<IBinder>& /*who*/) {
199 ALOGW("ResourceManagerService died.");
200 Mutex::Autolock lock(mLock);
201 mService.clear();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800202}
203
204} // namespace android