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