1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "inter_ipc_stub.h"
17 #include "common/sharing_log.h"
18 #include "inter_ipc_stub_death_listener.h"
19 #include "ipc_msg_decoder.h"
20 #include "ipc_msg_encoder.h"
21 #include "ipc_skeleton.h"
22
23 namespace OHOS {
24 namespace Sharing {
25
InterIpcStub()26 InterIpcStub::InterIpcStub()
27 {
28 SHARING_LOGD("trace.");
29 }
30
~InterIpcStub()31 InterIpcStub::~InterIpcStub()
32 {
33 SHARING_LOGD("trace.");
34 sharedFromThis_.reset();
35 for (auto deathRecipient : deathRecipients_) {
36 if (deathRecipient.second != nullptr) {
37 deathRecipient.second->SetDeathListener(nullptr);
38 deathRecipient.second = nullptr;
39 }
40 }
41 }
42
SetStubListener(std::weak_ptr<IInterIpcStubListener> listener)43 void InterIpcStub::SetStubListener(std::weak_ptr<IInterIpcStubListener> listener)
44 {
45 SHARING_LOGD("trace.");
46 stubListener_ = listener;
47 }
48
OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)49 int InterIpcStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
50 {
51 SHARING_LOGD("trace.");
52 switch (code) {
53 case InterIpcMsg::INTER_IPC_MSG: {
54 SHARING_LOGD("INTER_IPC_MSG.");
55 DoIpcCommand(data, reply);
56 break;
57 }
58 case InterIpcMsg::SET_LISTENER_OBJ:
59 SHARING_LOGD("SET_LISTENER_OBJ.");
60 SetListenerObject(data, reply);
61 break;
62 case InterIpcMsg::GET_SUBSYSTEM:
63 SHARING_LOGD("GET_SUBSYSTEM.");
64 GetSystemAbility(data, reply);
65 break;
66 default:
67 SHARING_LOGI("none process case.");
68 break;
69 }
70
71 return 0;
72 }
73
SetListenerObject(MessageParcel &data, MessageParcel &reply)74 int32_t InterIpcStub::SetListenerObject(MessageParcel &data, MessageParcel &reply)
75 {
76 SHARING_LOGD("trace.");
77 std::string key = data.ReadString();
78 sptr<IRemoteObject> object = data.ReadRemoteObject();
79 (void)reply.WriteInt32(SetListenerObject(key, object));
80
81 return ERR_NONE;
82 }
83
DoIpcCommand(MessageParcel &data, MessageParcel &reply)84 int32_t InterIpcStub::DoIpcCommand(MessageParcel &data, MessageParcel &reply)
85 {
86 SHARING_LOGD("trace.");
87 std::shared_ptr<BaseMsg> msg = nullptr;
88 IpcMsgDecoder::GetInstance().MsgDecode(msg, data);
89 if (msg == nullptr) {
90 SHARING_LOGE("msg null!");
91 return -1;
92 }
93
94 std::shared_ptr<BaseMsg> replyMsg = std::make_shared<BaseMsg>();
95 DoIpcCommand(msg, replyMsg);
96 IpcMsgEncoder::GetInstance().MsgEncode(reply, replyMsg);
97
98 return 0;
99 }
100
GetSystemAbility(MessageParcel &data, MessageParcel &reply)101 int32_t InterIpcStub::GetSystemAbility(MessageParcel &data, MessageParcel &reply)
102 {
103 SHARING_LOGD("trace.");
104 std::string key = data.ReadString();
105 std::string className = data.ReadString();
106 SHARING_LOGD("subtype: %{public}s.", className.c_str());
107 (void)reply.WriteRemoteObject(GetSubSystemAbility(key, className));
108
109 return ERR_NONE;
110 }
111
SetListenerObject(std::string key, const sptr<IRemoteObject> &object)112 int32_t InterIpcStub::SetListenerObject(std::string key, const sptr<IRemoteObject> &object)
113 {
114 SHARING_LOGD("trace.");
115 (void)key;
116 (void)object;
117 return ERR_NONE;
118 }
119
DoIpcCommand(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &replyMsg)120 int32_t InterIpcStub::DoIpcCommand(std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &replyMsg)
121 {
122 SHARING_LOGD("traces.");
123 auto listener = stubListener_.lock();
124 if (listener) {
125 listener->OnIpcRequest(msg, replyMsg);
126 } else {
127 SHARING_LOGE("stub listener is null!");
128 }
129
130 return 0;
131 }
132
GetSubSystemAbility(std::string key, std::string className)133 sptr<IRemoteObject> InterIpcStub::GetSubSystemAbility(std::string key, std::string className)
134 {
135 SHARING_LOGD("traces.");
136 (void)key;
137 (void)className;
138 return nullptr;
139 }
140
CreateDeathListener(std::string key)141 void InterIpcStub::CreateDeathListener(std::string key)
142 {
143 if (deathRecipients_.find(key) != deathRecipients_.end()) {
144 SHARING_LOGI("key: %{public}s.", key.c_str());
145 if (sharedFromThis_ == nullptr) {
146 sharedFromThis_ = Ptr(this, [](InterIpcStub *) { SHARING_LOGD("traces."); });
147 }
148 deathRecipients_[key]->SetDeathListener(std::make_shared<InterIpcStubDeathListener>(sharedFromThis_));
149 } else {
150 SHARING_LOGE("key not find %{public}s.", key.c_str());
151 }
152 }
153
OnRemoteDied()154 void InterIpcStub::OnRemoteDied()
155 {
156 SHARING_LOGD("base On remote died trace.");
157 }
158
SendIpcRequest(std::string key, std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)159 int32_t InterIpcStub::SendIpcRequest(std::string key, std::shared_ptr<BaseMsg> msg, std::shared_ptr<BaseMsg> &reply)
160 {
161 SHARING_LOGD("trace.");
162 std::unique_lock<std::mutex> lock(mutex_);
163 auto iter = peerProxys_.find(key);
164 if (iter == peerProxys_.end()) {
165 SHARING_LOGE("peer proxy not found.");
166 return -1;
167 }
168 lock.unlock();
169
170 if (iter->second == nullptr) {
171 SHARING_LOGE("peer proxy null!");
172 return -1;
173 }
174
175 int32_t error = iter->second->DoIpcCommand(msg, reply);
176 if (error != ERR_NONE) {
177 SHARING_LOGE("do ipc command failed: %{public}d.", error);
178 return error;
179 }
180
181 return 0;
182 }
183
DelPeerProxy(std::string key)184 void InterIpcStub::DelPeerProxy(std::string key)
185 {
186 SHARING_LOGD("Delete sub peer proxy, key: %{public}s.", key.c_str());
187 std::lock_guard<std::mutex> lock(mutex_);
188 if (peerProxys_.find(key) != peerProxys_.end()) {
189 peerProxys_[key]->AsObject()->RemoveDeathRecipient(deathRecipients_[key]);
190 peerProxys_.erase(key);
191 deathRecipients_.erase(key);
192 } else {
193 SHARING_LOGE("Delete sub peer proxy, key: %{public}s not find.", key.c_str());
194 }
195 }
196
197 } // namespace Sharing
198 } // namespace OHOS