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