1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <codecvt>
17 #include "ipc_skeleton.h"
18 #include "xcollie/xcollie.h"
19 #include "xcollie/xcollie_define.h"
20 #include "drm_error_code.h"
21 #include "drm_log.h"
22 #include "mediakeysystemfactory_service_stub.h"
23 
24 namespace {
25 constexpr uint32_t MAX_LISTNER_NUM = 64;
26 }
27 
28 namespace OHOS {
29 namespace DrmStandard {
MediaKeySystemFactoryServiceStub()30 MediaKeySystemFactoryServiceStub::MediaKeySystemFactoryServiceStub()
31 {
32     deathRecipientMap_.clear();
33 }
34 
~MediaKeySystemFactoryServiceStub()35 MediaKeySystemFactoryServiceStub::~MediaKeySystemFactoryServiceStub()
36 {
37 }
38 
MediaKeySystemFactoryClientDied(pid_t pid)39 void MediaKeySystemFactoryServiceStub::MediaKeySystemFactoryClientDied(pid_t pid)
40 {
41     DRM_ERR_LOG("MediaKeySystemFactory client has died, pid:%{public}d", pid);
42     std::lock_guard<std::recursive_mutex> lock(factoryServiceStubMutex_);
43     if (clientListenerMap_.find(pid) != clientListenerMap_.end()) {
44         if (clientListenerMap_[pid] != nullptr && clientListenerMap_[pid]->AsObject() != nullptr &&
45             deathRecipientMap_.find(pid) != deathRecipientMap_.end() && deathRecipientMap_[pid] != nullptr) {
46             (void)clientListenerMap_[pid]->AsObject()->RemoveDeathRecipient(deathRecipientMap_[pid]);
47         }
48         deathRecipientMap_.erase(pid);
49         clientListenerMap_.erase(pid);
50     }
51     DistroyForClientDied(pid);
52 }
53 
SetListenerObject(const sptr<IRemoteObject> & object)54 int32_t MediaKeySystemFactoryServiceStub::SetListenerObject(const sptr<IRemoteObject> &object)
55 {
56     pid_t pid = IPCSkeleton::GetCallingPid();
57     std::lock_guard<std::recursive_mutex> lock(factoryServiceStubMutex_);
58     if (clientListenerMap_.find(pid) != clientListenerMap_.end()) {
59         if (clientListenerMap_[pid] != nullptr && clientListenerMap_[pid]->AsObject() != nullptr &&
60             deathRecipientMap_.find(pid) != deathRecipientMap_.end() && deathRecipientMap_[pid] != nullptr) {
61             (void)clientListenerMap_[pid]->AsObject()->RemoveDeathRecipient(deathRecipientMap_[pid]);
62         }
63         deathRecipientMap_.erase(pid);
64         clientListenerMap_.erase(pid);
65     }
66     DRM_CHECK_AND_RETURN_RET_LOG(clientListenerMap_.size() < MAX_LISTNER_NUM,
67         DRM_OPERATION_NOT_ALLOWED, "the number of listeners exceeds MAX_LISTNER_NUM: 64");
68     DRM_CHECK_AND_RETURN_RET_LOG(object != nullptr, DRM_MEMORY_ERROR, "set listener object is nullptr");
69     sptr<IDrmListener> clientListener = iface_cast<IDrmListener>(object);
70     DRM_CHECK_AND_RETURN_RET_LOG(
71         clientListener != nullptr, DRM_MEMORY_ERROR, "failed to convert IDrmListener");
72     sptr<DrmDeathRecipient> deathRecipient = new (std::nothrow) DrmDeathRecipient(pid);
73     DRM_CHECK_AND_RETURN_RET_LOG(deathRecipient != nullptr, DRM_MEMORY_ERROR, "failed to new DrmDeathRecipient");
74     deathRecipient->SetNotifyCb([this] (pid_t pid) {
75         this->MediaKeySystemFactoryClientDied(pid);
76     });
77     if (clientListener->AsObject() != nullptr) {
78         (void)clientListener->AsObject()->AddDeathRecipient(deathRecipient);
79     }
80     DRM_DEBUG_LOG("MediaKeySystem client pid:%{public}d", pid);
81     deathRecipientMap_[pid] = deathRecipient;
82     clientListenerMap_[pid] = clientListener;
83     return DRM_OK;
84 }
85 
ProcessCreateMediaKeySystem(MediaKeySystemFactoryServiceStub * stub,MessageParcel & data,MessageParcel & reply,MessageOption & option)86 static int32_t ProcessCreateMediaKeySystem(MediaKeySystemFactoryServiceStub *stub, MessageParcel &data,
87     MessageParcel &reply, MessageOption &option)
88 {
89     sptr<IMediaKeySystemService> mediaKeysystemProxy = nullptr;
90     std::string name = data.ReadString();
91     int32_t ret = stub->CreateMediaKeySystem(name, mediaKeysystemProxy);
92     if (ret != DRM_OK) {
93         DRM_ERR_LOG("CreateMediaKeySystem failed, errCode: %{public}d", ret);
94         return ret;
95     }
96     if (!reply.WriteRemoteObject(mediaKeysystemProxy->AsObject())) {
97         DRM_ERR_LOG("CreateMediaKeySystem Write MediaKeySession object failed.");
98         return DRM_OPERATION_NOT_ALLOWED;
99     }
100     return ret;
101 }
102 
ProcessMediaKeySystemSupportedRequest(MediaKeySystemFactoryServiceStub * stub,MessageParcel & data,MessageParcel & reply,MessageOption & option)103 static int32_t ProcessMediaKeySystemSupportedRequest(MediaKeySystemFactoryServiceStub *stub, MessageParcel &data,
104     MessageParcel &reply, MessageOption &option)
105 {
106     int32_t paramNum = data.ReadInt32();
107     bool isSurpported = false;
108 
109     DRM_CHECK_AND_RETURN_RET_LOG((paramNum <= (int32_t)ARGS_NUM_THREE) && (paramNum >= (int32_t)ARGS_NUM_ONE),
110         IPC_STUB_WRITE_PARCEL_ERR, "paramNum is invalid");
111     std::string name = data.ReadString();
112     if (paramNum == ARGS_NUM_ONE) {
113         int32_t ret = stub->IsMediaKeySystemSupported(name, &isSurpported);
114         DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, ret, "IsMediaKeySystemSupported faild, errCode:%{public}d", ret);
115         DRM_CHECK_AND_RETURN_RET_LOG(reply.WriteBool(isSurpported), IPC_STUB_WRITE_PARCEL_ERR,
116             "Write isSurpported failed.");
117         return ret;
118     }
119     std::string mimeType = data.ReadString();
120     if (paramNum == ARGS_NUM_TWO) {
121         int32_t ret = stub->IsMediaKeySystemSupported(name, mimeType, &isSurpported);
122         DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, ret, "IsMediaKeySystemSupported faild, errCode:%{public}d", ret);
123         DRM_CHECK_AND_RETURN_RET_LOG(reply.WriteBool(isSurpported), IPC_STUB_WRITE_PARCEL_ERR,
124             "Write isSurpported failed.");
125         return ret;
126     }
127 
128     int32_t securityLevel = data.ReadInt32();
129     if (paramNum == ARGS_NUM_THREE) {
130         int32_t ret = stub->IsMediaKeySystemSupported(name, mimeType, securityLevel, &isSurpported);
131         DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, ret, "IsMediaKeySystemSupported faild, errCode:%{public}d", ret);
132         DRM_CHECK_AND_RETURN_RET_LOG(reply.WriteBool(isSurpported), IPC_STUB_WRITE_PARCEL_ERR,
133             "Write isSurpported failed.");
134         return ret;
135     }
136     return DRM_OK;
137 }
138 
ProcessSetListenerObject(MediaKeySystemFactoryServiceStub * stub,MessageParcel & data,MessageParcel & reply,MessageOption & option)139 static int32_t ProcessSetListenerObject(MediaKeySystemFactoryServiceStub *stub, MessageParcel &data,
140     MessageParcel &reply, MessageOption &option)
141 {
142     DRM_INFO_LOG("ProcessSetListenerObject enter.");
143     (void)reply;
144     sptr<IRemoteObject> object = data.ReadRemoteObject();
145     int32_t ret = stub->SetListenerObject(object);
146     DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, ret,
147         "ProcessSetListenerObject faild, errCode:%{public}d", ret);
148     return ret;
149 }
150 
ProcessGetMediaKeySystems(MediaKeySystemFactoryServiceStub * stub,MessageParcel & data,MessageParcel & reply,MessageOption & option)151 static int32_t ProcessGetMediaKeySystems(MediaKeySystemFactoryServiceStub *stub, MessageParcel &data,
152     MessageParcel &reply, MessageOption &option)
153 {
154     DRM_INFO_LOG("ProcessGetMediaKeySystems enter.");
155     std::map<std::string, std::string> mediaKeySystemNames;
156     int32_t ret = stub->GetMediaKeySystems(mediaKeySystemNames);
157     DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, ret, "GetMediaKeySystems faild, errCode:%{public}d", ret);
158     reply.WriteInt32(mediaKeySystemNames.size());
159     for (auto mediaKeySystemName : mediaKeySystemNames) {
160         DRM_CHECK_AND_RETURN_RET_LOG(reply.WriteString(mediaKeySystemName.first), IPC_STUB_WRITE_PARCEL_ERR,
161             "Write mediaKeySystem name failed.");
162         DRM_CHECK_AND_RETURN_RET_LOG(reply.WriteString(mediaKeySystemName.second), IPC_STUB_WRITE_PARCEL_ERR,
163             "Write mediaKeySystem uuid failed.");
164     }
165     return DRM_OK;
166 }
167 
ProcessGetMediaKeySystemUuid(MediaKeySystemFactoryServiceStub * stub,MessageParcel & data,MessageParcel & reply,MessageOption & option)168 static int32_t ProcessGetMediaKeySystemUuid(MediaKeySystemFactoryServiceStub *stub, MessageParcel &data,
169     MessageParcel &reply, MessageOption &option)
170 {
171     DRM_INFO_LOG("ProcessGetMediaKeySystemUuid enter.");
172     std::string name = data.ReadString();
173     std::string uuid;
174     int32_t ret = stub->GetMediaKeySystemUuid(name, uuid);
175     DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, ret, "ProcessGetMediaKeySystemUuid faild, errCode:%{public}d", ret);
176     if (!reply.WriteString(uuid)) {
177         DRM_ERR_LOG("ProcessGetMediaKeySystemUuid write value failed.");
178         return IPC_STUB_WRITE_PARCEL_ERR;
179     }
180     return DRM_OK;
181 }
182 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)183 int32_t MediaKeySystemFactoryServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
184     MessageOption &option)
185 {
186     int32_t ret = DRM_OK;
187     if (data.ReadInterfaceToken() != GetDescriptor()) {
188         DRM_DEBUG_LOG("ReadInterfaceToken failed.");
189         return -1;
190     }
191 
192     switch (code) {
193         case MEDIA_KEY_SYSTEM_FACTORY_IS_MEDIA_KEY_SYSTEM_SURPPORTED: {
194             DRM_INFO_LOG("IS_MEDIA_KEY_SYSTEM_SURPPORTED enter.");
195             return ProcessMediaKeySystemSupportedRequest(this, data, reply, option);
196         }
197         case MEDIA_KEY_SYSTEM_FACTORY_CREATE_MEDIA_KEYSYSTEM: {
198             DRM_INFO_LOG("IS_MEDIA_KEY_SYSTEM_SURPPORTED enter.");
199             return ProcessCreateMediaKeySystem(this, data, reply, option);
200         }
201         case MEDIA_KEY_SYSTEM_FACTORY_SET_LISTENER_OBJ: {
202             DRM_INFO_LOG("MEDIA_KEY_SYSTEM_FACTORY_SET_LISTENER_OBJ enter.");
203             return ProcessSetListenerObject(this, data, reply, option);
204         }
205         case MEDIA_KEY_SYSTEM_FACTORY_GET_MEDIA_KEYSYSTEM_NAME: {
206             DRM_INFO_LOG("MEDIA_KEY_SYSTEM_FACTORY_GST_MEDIA_KEYSYSTEM_NAME enter.");
207             return ProcessGetMediaKeySystems(this, data, reply, option);
208         }
209         case MEDIA_KEY_SYSTEM_FACTORY_GET_MEDIA_KEYSYSTEM_UUID: {
210             DRM_INFO_LOG("MEDIA_KEY_SYSTEM_FACTORY_GET_MEDIA_KEYSYSTEM_UUID enter.");
211             return ProcessGetMediaKeySystemUuid(this, data, reply, option);
212         }
213     }
214     return ret;
215 }
216 } // namespace DrmStandard
217 } // namespace OHOS