1 /*
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 #ifndef DRM_SESSION_MANAGER_H_
18 
19 #define DRM_SESSION_MANAGER_H_
20 
21 #include <aidl/android/media/IResourceManagerClient.h>
22 #include <aidl/android/media/IResourceManagerService.h>
23 #include <android/binder_auto_utils.h>
24 #include <media/stagefright/foundation/ABase.h>
25 #include <utils/RefBase.h>
26 #include <utils/KeyedVector.h>
27 #include <utils/threads.h>
28 #include <utils/Vector.h>
29 
30 #include <future>
31 #include <map>
32 #include <memory>
33 #include <set>
34 #include <utility>
35 #include <vector>
36 
37 namespace android {
38 
39 class DrmSessionManagerTest;
40 
41 using aidl::android::media::IResourceManagerClient;
42 using aidl::android::media::IResourceManagerService;
43 using aidl::android::media::MediaResourceParcel;
44 
45 bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
46 
47 struct SessionInfo {
48     pid_t pid;
49     uid_t uid;
50     int64_t clientId;
51     std::shared_ptr<IResourceManagerClient> drm;
52     int64_t resourceValue;
53 
54 };
55 
56 typedef std::map<std::vector<uint8_t>, SessionInfo> SessionInfoMap;
57 
58 struct DrmSessionManager : public RefBase {
59     static sp<DrmSessionManager> Instance();
60 
61     DrmSessionManager();
62     explicit DrmSessionManager(const std::shared_ptr<IResourceManagerService> &service);
63 
64     void addSession(int pid,
65             const std::shared_ptr<IResourceManagerClient>& drm,
66             const Vector<uint8_t>& sessionId);
67     void useSession(const Vector<uint8_t>& sessionId);
68     void removeSession(const Vector<uint8_t>& sessionId);
69     bool reclaimSession(int callingPid);
70 
71     // inspection APIs
72     size_t getSessionCount() const;
73     bool containsSession(const Vector<uint8_t>& sessionId) const;
74 
75 protected:
76     virtual ~DrmSessionManager();
77 
78 private:
79     status_t init();
80 
81     // To set up the binder interface with the resource manager service.
getResourceManagerServiceDrmSessionManager82     void getResourceManagerService() {
83         Mutex::Autolock lock(mLock);
84         getResourceManagerService_l();
85     }
86     void getResourceManagerService_l();
87 
88     // To add/register all the resources currently added/registered with
89     // the ResourceManagerService.
90     // This function will be called right after the death of the Resource
91     // Manager to make sure that the newly started ResourceManagerService
92     // knows about the current resource usage.
93     void reRegisterAllResources_l();
94 
95     // For binder death handling
96     static void ResourceManagerServiceDied(void* cookie);
97     static void BinderUnlinkedCallback(void* cookie);
98     void binderDied();
99 
100     // BinderDiedContext defines the cookie that is passed as DeathRecipient.
101     // Since this can maintain more context than a raw pointer, we can
102     // validate the scope of DrmSessionManager,
103     // before deferencing it upon the binder death.
104     struct BinderDiedContext {
105         wp<DrmSessionManager> mDrmSessionManager;
106     };
107 
108     std::shared_ptr<IResourceManagerService> mService = nullptr;
109     mutable Mutex mLock;
110     SessionInfoMap mSessionMap;
111     bool mBinderDied = false;
112     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
113     /**
114      * Reconnecting with the ResourceManagerService, after its binder interface dies,
115      * is done asynchronously. It will also make sure that, all the resources
116      * asssociated with this DrmSessionManager are added with the new instance
117      * of the ResourceManagerService to persist the state of resources.
118      * We must store the reference of the furture to guarantee real asynchronous operation.
119      */
120     std::future<void> mGetServiceFuture;
121 
122     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
123 };
124 
125 }  // namespace android
126 
127 #endif  // DRM_SESSION_MANAGER_H_
128