blob: 0b91b85b3c413d7e5250414679da3572b5c7b2dd [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>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080028#include <mediadrm/DrmSessionManager.h>
Ronghua Wu10305cc2015-02-22 07:55:32 -080029#include <unistd.h>
30#include <utils/String8.h>
31
Robert Shihc3af31b2019-09-20 21:45:01 -070032#include <vector>
33
34#include "ResourceManagerService.h"
35
Ronghua Wu10305cc2015-02-22 07:55:32 -080036namespace android {
Chong Zhang181e6952019-10-09 13:23:39 -070037using android::binder::Status;
Ronghua Wu10305cc2015-02-22 07:55:32 -080038
39static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
40 String8 sessionIdStr;
41 for (size_t i = 0; i < sessionId.size(); ++i) {
42 sessionIdStr.appendFormat("%u ", sessionId[i]);
43 }
44 return sessionIdStr;
45}
46
Robert Shihc3af31b2019-09-20 21:45:01 -070047static std::vector<uint8_t> toStdVec(const Vector<uint8_t> &vector) {
48 const uint8_t *v = vector.array();
49 std::vector<uint8_t> vec(v, v + vector.size());
50 return vec;
51}
52
53static uint64_t toClientId(const sp<IResourceManagerClient>& drm) {
54 return reinterpret_cast<int64_t>(drm.get());
55}
56
Chong Zhang181e6952019-10-09 13:23:39 -070057static std::vector<MediaResourceParcel> toResourceVec(
58 const Vector<uint8_t> &sessionId, int64_t value) {
59 std::vector<MediaResourceParcel> resources;
60 resources.push_back(MediaResource::DrmSessionResource(toStdVec(sessionId), value));
Robert Shihc3af31b2019-09-20 21:45:01 -070061 return resources;
62}
63
64static sp<IResourceManagerService> getResourceManagerService() {
65 if (property_get_bool("persist.device_config.media_native.mediadrmserver", 1)) {
Chong Zhang181e6952019-10-09 13:23:39 -070066 return new android::media::ResourceManagerService();
Robert Shihc3af31b2019-09-20 21:45:01 -070067 }
68 sp<IServiceManager> sm = defaultServiceManager();
69 if (sm == NULL) {
70 return NULL;
71 }
72 sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
73 return interface_cast<IResourceManagerService>(binder);
74}
75
Ronghua Wu10305cc2015-02-22 07:55:32 -080076bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
77 if (sessionId1.size() != sessionId2.size()) {
78 return false;
79 }
80 for (size_t i = 0; i < sessionId1.size(); ++i) {
81 if (sessionId1[i] != sessionId2[i]) {
82 return false;
83 }
84 }
85 return true;
86}
87
Ronghua Wu5c3da202015-02-22 08:45:28 -080088sp<DrmSessionManager> DrmSessionManager::Instance() {
89 static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
Robert Shihc3af31b2019-09-20 21:45:01 -070090 drmSessionManager->init();
Ronghua Wu5c3da202015-02-22 08:45:28 -080091 return drmSessionManager;
92}
93
Ronghua Wu10305cc2015-02-22 07:55:32 -080094DrmSessionManager::DrmSessionManager()
Robert Shihc3af31b2019-09-20 21:45:01 -070095 : DrmSessionManager(getResourceManagerService()) {
96}
Ronghua Wu10305cc2015-02-22 07:55:32 -080097
Robert Shihc3af31b2019-09-20 21:45:01 -070098DrmSessionManager::DrmSessionManager(const sp<IResourceManagerService> &service)
99 : mService(service),
100 mInitialized(false) {
101 if (mService == NULL) {
102 ALOGE("Failed to init ResourceManagerService");
103 }
104}
Ronghua Wu10305cc2015-02-22 07:55:32 -0800105
Robert Shihc3af31b2019-09-20 21:45:01 -0700106DrmSessionManager::~DrmSessionManager() {
107 if (mService != NULL) {
108 IInterface::asBinder(mService)->unlinkToDeath(this);
109 }
110}
Ronghua Wu10305cc2015-02-22 07:55:32 -0800111
Robert Shihc3af31b2019-09-20 21:45:01 -0700112void DrmSessionManager::init() {
113 Mutex::Autolock lock(mLock);
114 if (mInitialized) {
115 return;
116 }
117 mInitialized = true;
118 if (mService != NULL) {
119 IInterface::asBinder(mService)->linkToDeath(this);
120 }
121}
122
123void DrmSessionManager::addSession(int pid,
124 const sp<IResourceManagerClient>& drm, const Vector<uint8_t> &sessionId) {
125 uid_t uid = IPCThreadState::self()->getCallingUid();
126 ALOGV("addSession(pid %d, uid %d, drm %p, sessionId %s)", pid, uid, drm.get(),
Ronghua Wu10305cc2015-02-22 07:55:32 -0800127 GetSessionIdString(sessionId).string());
128
129 Mutex::Autolock lock(mLock);
Robert Shihc3af31b2019-09-20 21:45:01 -0700130 if (mService == NULL) {
131 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800132 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700133
134 int64_t clientId = toClientId(drm);
135 mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
Chong Zhang181e6952019-10-09 13:23:39 -0700136 mService->addResource(pid, uid, clientId, drm, toResourceVec(sessionId, INT64_MAX));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800137}
138
139void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
140 ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
141
142 Mutex::Autolock lock(mLock);
Robert Shihc3af31b2019-09-20 21:45:01 -0700143 auto it = mSessionMap.find(toStdVec(sessionId));
144 if (mService == NULL || it == mSessionMap.end()) {
145 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800146 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700147
148 auto info = it->second;
Chong Zhang181e6952019-10-09 13:23:39 -0700149 mService->addResource(info.pid, info.uid, info.clientId, NULL, toResourceVec(sessionId, -1));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800150}
151
152void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
153 ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
154
155 Mutex::Autolock lock(mLock);
Robert Shihc3af31b2019-09-20 21:45:01 -0700156 auto it = mSessionMap.find(toStdVec(sessionId));
157 if (mService == NULL || it == mSessionMap.end()) {
158 return;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800159 }
Ronghua Wu10305cc2015-02-22 07:55:32 -0800160
Robert Shihc3af31b2019-09-20 21:45:01 -0700161 auto info = it->second;
Chong Zhang181e6952019-10-09 13:23:39 -0700162 mService->removeResource(info.pid, info.clientId, toResourceVec(sessionId, INT64_MAX));
Robert Shihc3af31b2019-09-20 21:45:01 -0700163 mSessionMap.erase(it);
Ronghua Wu10305cc2015-02-22 07:55:32 -0800164}
165
166bool DrmSessionManager::reclaimSession(int callingPid) {
167 ALOGV("reclaimSession(%d)", callingPid);
168
Robert Shihc3af31b2019-09-20 21:45:01 -0700169 // unlock early because reclaimResource might callback into removeSession
170 mLock.lock();
171 sp<IResourceManagerService> service(mService);
172 mLock.unlock();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800173
Robert Shihc3af31b2019-09-20 21:45:01 -0700174 if (service == NULL) {
Ronghua Wu10305cc2015-02-22 07:55:32 -0800175 return false;
176 }
177
Robert Shihc3af31b2019-09-20 21:45:01 -0700178 // cannot update mSessionMap because we do not know which sessionId is reclaimed;
179 // we rely on IResourceManagerClient to removeSession in reclaimResource
180 Vector<uint8_t> dummy;
Chong Zhang181e6952019-10-09 13:23:39 -0700181 bool success;
182 Status status = service->reclaimResource(callingPid, toResourceVec(dummy, INT64_MAX), &success);
183 return status.isOk() && success;
Ronghua Wu10305cc2015-02-22 07:55:32 -0800184}
185
Robert Shihc3af31b2019-09-20 21:45:01 -0700186size_t DrmSessionManager::getSessionCount() const {
187 Mutex::Autolock lock(mLock);
188 return mSessionMap.size();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800189}
190
Robert Shihc3af31b2019-09-20 21:45:01 -0700191bool DrmSessionManager::containsSession(const Vector<uint8_t>& sessionId) const {
192 Mutex::Autolock lock(mLock);
193 return mSessionMap.count(toStdVec(sessionId));
Ronghua Wu10305cc2015-02-22 07:55:32 -0800194}
195
Robert Shihc3af31b2019-09-20 21:45:01 -0700196void DrmSessionManager::binderDied(const wp<IBinder>& /*who*/) {
197 ALOGW("ResourceManagerService died.");
198 Mutex::Autolock lock(mLock);
199 mService.clear();
Ronghua Wu10305cc2015-02-22 07:55:32 -0800200}
201
202} // namespace android