1 /*
2 * Copyright (C) 2021 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 "media_service_stub.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "media_server_manager.h"
20 #include "player_xcollie.h"
21
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "MediaServiceStub"};
24 const std::string TASK_NAME = "OHOS::Media::MediaServiceStub::GetSystemAbility";
25 const int32_t TIME_OUT_SECOND = 30; // time out is 30 senconds
26 }
27
28 namespace OHOS {
29 namespace Media {
MediaServiceStub()30 MediaServiceStub::MediaServiceStub()
31 {
32 deathRecipientMap_.clear();
33 mediaListenerMap_.clear();
34 Init();
35 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
36 }
37
~MediaServiceStub()38 MediaServiceStub::~MediaServiceStub()
39 {
40 }
41
Init()42 void MediaServiceStub::Init()
43 {
44 mediaFuncs_[GET_SUBSYSTEM] =
45 [this](MessageParcel &data, MessageParcel &reply) { return GetSystemAbility(data, reply); };
46 }
47
DestroyStubForPid(pid_t pid)48 int32_t MediaServiceStub::DestroyStubForPid(pid_t pid)
49 {
50 {
51 std::lock_guard<std::mutex> lock(mutex_);
52 sptr<MediaDeathRecipient> deathRecipient = nullptr;
53 sptr<IStandardMediaListener> mediaListener = nullptr;
54
55 auto itDeath = deathRecipientMap_.find(pid);
56 if (itDeath != deathRecipientMap_.end()) {
57 deathRecipient = itDeath->second;
58
59 if (deathRecipient != nullptr) {
60 deathRecipient->SetNotifyCb(nullptr);
61 }
62
63 (void)deathRecipientMap_.erase(itDeath);
64 }
65
66 auto itListener = mediaListenerMap_.find(pid);
67 if (itListener != mediaListenerMap_.end()) {
68 mediaListener = itListener->second;
69
70 if (mediaListener != nullptr && mediaListener->AsObject() != nullptr && deathRecipient != nullptr) {
71 (void)mediaListener->AsObject()->RemoveDeathRecipient(deathRecipient);
72 }
73
74 (void)mediaListenerMap_.erase(itListener);
75 }
76 }
77
78 MediaServerManager::GetInstance().DestroyStubObjectForPid(pid);
79 return MSERR_OK;
80 }
81
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)82 int MediaServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
83 MessageOption &option)
84 {
85 MEDIA_LOGD("0x%{public}06" PRIXPTR " Stub: OnRemoteRequest of code: %{public}u is received",
86 FAKE_POINTER(this), code);
87
88 auto remoteDescriptor = data.ReadInterfaceToken();
89 if (MediaServiceStub::GetDescriptor() != remoteDescriptor) {
90 MEDIA_LOGE("Invalid descriptor");
91 return MSERR_INVALID_OPERATION;
92 }
93 auto itFunc = mediaFuncs_.find(code);
94 if (itFunc != mediaFuncs_.end()) {
95 int32_t ret = itFunc->second(data, reply);
96 if (ret != MSERR_OK) {
97 MEDIA_LOGE("Calling memberFunc is failed.");
98 }
99 return MSERR_OK;
100 }
101 MEDIA_LOGW("mediaFuncs_: no member func supporting, applying default process");
102 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
103 }
104
ClientDied(pid_t pid)105 void MediaServiceStub::ClientDied(pid_t pid)
106 {
107 MEDIA_LOGE("client pid is dead, pid:%{public}d", pid);
108 (void)DestroyStubForPid(pid);
109 }
110
SetDeathListener(const sptr<IRemoteObject> & object)111 int32_t MediaServiceStub::SetDeathListener(const sptr<IRemoteObject> &object)
112 {
113 std::lock_guard<std::mutex> lock(mutex_);
114 CHECK_AND_RETURN_RET_LOG(object != nullptr, MSERR_NO_MEMORY, "set listener object is nullptr");
115
116 sptr<IStandardMediaListener> mediaListener = iface_cast<IStandardMediaListener>(object);
117 CHECK_AND_RETURN_RET_LOG(mediaListener != nullptr, MSERR_NO_MEMORY,
118 "failed to convert IStandardMediaListener");
119
120 pid_t pid = IPCSkeleton::GetCallingPid();
121 sptr<MediaDeathRecipient> deathRecipient = new(std::nothrow) MediaDeathRecipient(pid);
122 CHECK_AND_RETURN_RET_LOG(deathRecipient != nullptr, MSERR_NO_MEMORY, "failed to new MediaDeathRecipient");
123
124 deathRecipient->SetNotifyCb(std::bind(&MediaServiceStub::ClientDied, this, std::placeholders::_1));
125
126 if (mediaListener->AsObject() != nullptr) {
127 (void)mediaListener->AsObject()->AddDeathRecipient(deathRecipient);
128 }
129
130 sptr<MediaDeathRecipient> oldDeathRecipient =
131 deathRecipientMap_.find(pid) != deathRecipientMap_.end() ? deathRecipientMap_[pid] : nullptr;
132 sptr<IStandardMediaListener> oldMediaListener =
133 mediaListenerMap_.find(pid) != mediaListenerMap_.end() ? mediaListenerMap_[pid] : nullptr;
134 if (oldDeathRecipient != nullptr) {
135 oldDeathRecipient->SetNotifyCb(nullptr);
136 }
137 if (oldMediaListener != nullptr && oldDeathRecipient != nullptr) {
138 oldMediaListener->AsObject()->RemoveDeathRecipient(oldDeathRecipient);
139 }
140
141 MEDIA_LOGD("client pid pid:%{public}d", pid);
142 mediaListenerMap_[pid] = mediaListener;
143 deathRecipientMap_[pid] = deathRecipient;
144 return MSERR_OK;
145 }
146
GetSystemAbility(MessageParcel & data,MessageParcel & reply)147 int32_t MediaServiceStub::GetSystemAbility(MessageParcel &data, MessageParcel &reply)
148 {
149 int32_t mediaSystemAbility = data.ReadInt32();
150 MediaSystemAbility id = static_cast<MediaSystemAbility>(mediaSystemAbility);
151 sptr<IRemoteObject> listenerObj = data.ReadRemoteObject();
152 LISTENER(reply.WriteRemoteObject(GetSubSystemAbility(id, listenerObj)),
153 TASK_NAME + ":" + std::to_string(mediaSystemAbility), false, TIME_OUT_SECOND);
154 return MSERR_OK;
155 }
156 } // namespace Media
157 } // namespace OHOS
158