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 "ipc_server_stub.h"
17
18 #include <algorithm>
19 #include <thread>
20
21 #include "if_system_ability_manager.h"
22 #include "ipc_skeleton.h"
23 #include "ipc_types.h"
24 #include "iservice_registry.h"
25 #include "string_ex.h"
26 #include "system_ability_definition.h"
27
28 #include "device_manager_errno.h"
29 #include "device_manager_log.h"
30
31 #include "ipc_server_adapter.h"
32 #include "ipc_cmd_register.h"
33
34 namespace OHOS {
35 namespace DistributedHardware {
36 IMPLEMENT_SINGLE_INSTANCE(IpcServerStub);
37
38 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&IpcServerStub::GetInstance());
39
IpcServerStub()40 IpcServerStub::IpcServerStub() : SystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID, true)
41 {
42 registerToService_ = false;
43 state_ = ServiceRunningState::STATE_NOT_START;
44 }
45
OnStart()46 void IpcServerStub::OnStart()
47 {
48 DMLOG(DM_LOG_INFO, "IpcServerStub::OnStart start");
49 if (state_ == ServiceRunningState::STATE_RUNNING) {
50 DMLOG(DM_LOG_DEBUG, "IpcServerStub has already started.");
51 return;
52 }
53 if (!Init()) {
54 DMLOG(DM_LOG_ERROR, "failed to init IpcServerStub");
55 return;
56 }
57 state_ = ServiceRunningState::STATE_RUNNING;
58 }
59
Init()60 bool IpcServerStub::Init()
61 {
62 DMLOG(DM_LOG_INFO, "IpcServerStub::Init ready to init.");
63 if (!registerToService_) {
64 bool ret = Publish(this);
65 if (!ret) {
66 DMLOG(DM_LOG_ERROR, "IpcServerStub::Init Publish failed!");
67 return false;
68 }
69 registerToService_ = true;
70 }
71
72 std::thread {
73 [] {
74 IpcServerAdapter::GetInstance().ModuleInit();
75 }
76 }.detach();
77 return true;
78 }
79
OnStop()80 void IpcServerStub::OnStop()
81 {
82 DMLOG(DM_LOG_INFO, "IpcServerStub::OnStop ready to stop service.");
83 state_ = ServiceRunningState::STATE_NOT_START;
84 registerToService_ = false;
85 }
86
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)87 int32_t IpcServerStub::OnRemoteRequest(uint32_t code,
88 MessageParcel &data, MessageParcel &reply, MessageOption &option)
89 {
90 DMLOG(DM_LOG_INFO, "code = %u, flags= %d.", code, option.GetFlags());
91 auto remoteDescriptor = data.ReadInterfaceToken();
92 if (GetDescriptor() != remoteDescriptor) {
93 DMLOG(DM_LOG_ERROR, "ReadInterfaceToken fail!");
94 return DEVICEMANAGER_FAILED;
95 }
96 int32_t ret = DEVICEMANAGER_OK;
97 ret = IpcCmdRegister::GetInstance().OnIpcCmd(code, data, reply);
98 if (ret == DEVICEMANAGER_IPC_NOT_REGISTER_FUNC) {
99 DMLOG(DM_LOG_WARN, "unsupport code: %d", code);
100 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
101 }
102 return ret;
103 }
104
SendCmd(int32_t cmdCode,std::shared_ptr<IpcReq> req,std::shared_ptr<IpcRsp> rsp)105 int32_t IpcServerStub::SendCmd(int32_t cmdCode, std::shared_ptr<IpcReq> req, std::shared_ptr<IpcRsp> rsp)
106 {
107 return DEVICEMANAGER_OK;
108 }
109
QueryServiceState() const110 ServiceRunningState IpcServerStub::QueryServiceState() const
111 {
112 return state_;
113 }
114
RegisterDeviceManagerListener(std::string & pkgName,sptr<IRemoteObject> listener)115 int32_t IpcServerStub::RegisterDeviceManagerListener(std::string &pkgName, sptr<IRemoteObject> listener)
116 {
117 if (pkgName.empty() || listener == nullptr) {
118 DMLOG(DM_LOG_ERROR, "Error: parameter invalid");
119 return DEVICEMANAGER_NULLPTR;
120 }
121
122 DMLOG(DM_LOG_INFO, "In, pkgName: %s", pkgName.c_str());
123 std::lock_guard<std::mutex> autoLock(listenerLock_);
124 auto iter = dmListener_.find(pkgName);
125 if (iter != dmListener_.end()) {
126 DMLOG(DM_LOG_INFO, "RegisterDeviceManagerListener: listener already exists");
127 return DEVICEMANAGER_OK;
128 }
129
130 sptr<AppDeathRecipient> appRecipient = sptr<AppDeathRecipient>(new AppDeathRecipient());
131 if (!listener->AddDeathRecipient(appRecipient)) {
132 DMLOG(DM_LOG_ERROR, "RegisterDeviceManagerListener: AddDeathRecipient Failed");
133 }
134 dmListener_[pkgName] = listener;
135 appRecipient_[pkgName] = appRecipient;
136 return DEVICEMANAGER_OK;
137 }
138
UnRegisterDeviceManagerListener(std::string & pkgName)139 int32_t IpcServerStub::UnRegisterDeviceManagerListener(std::string &pkgName)
140 {
141 if (pkgName.empty()) {
142 DMLOG(DM_LOG_ERROR, "Error: parameter invalid");
143 return DEVICEMANAGER_NULLPTR;
144 }
145
146 DMLOG(DM_LOG_INFO, "In, pkgName: %s", pkgName.c_str());
147 std::lock_guard<std::mutex> autoLock(listenerLock_);
148 auto listenerIter = dmListener_.find(pkgName);
149 if (listenerIter == dmListener_.end()) {
150 DMLOG(DM_LOG_INFO, "UnRegisterDeviceManagerListener: listener not exists");
151 return DEVICEMANAGER_OK;
152 }
153
154 auto recipientIter = appRecipient_.find(pkgName);
155 if (recipientIter == appRecipient_.end()) {
156 DMLOG(DM_LOG_INFO, "UnRegisterDeviceManagerListener: appRecipient not exists");
157 dmListener_.erase(pkgName);
158 return DEVICEMANAGER_OK;
159 }
160
161 auto listener = listenerIter->second;
162 auto appRecipient = recipientIter->second;
163 listener->RemoveDeathRecipient(appRecipient);
164 appRecipient_.erase(pkgName);
165 dmListener_.erase(pkgName);
166 return DEVICEMANAGER_OK;
167 }
168
GetDmListener()169 const std::map<std::string, sptr<IRemoteObject>> &IpcServerStub::GetDmListener()
170 {
171 return dmListener_;
172 }
173
GetDmListener(std::string pkgName) const174 const sptr<IpcRemoteBroker> IpcServerStub::GetDmListener(std::string pkgName) const
175 {
176 if (pkgName.empty()) {
177 DMLOG(DM_LOG_ERROR, "Error: parameter invalid");
178 return nullptr;
179 }
180 auto iter = dmListener_.find(pkgName);
181 if (iter == dmListener_.end()) {
182 return nullptr;
183 }
184 auto remote = iter->second;
185 sptr<IpcRemoteBroker> dmListener = iface_cast<IpcRemoteBroker>(remote);
186 return dmListener;
187 }
188
OnRemoteDied(const wptr<IRemoteObject> & remote)189 void AppDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
190 {
191 DMLOG(DM_LOG_WARN, "AppDeathRecipient: OnRemoteDied");
192 std::map<std::string, sptr<IRemoteObject>> listeners = IpcServerStub::GetInstance().GetDmListener();
193 std::string pkgName;
194 for (auto iter : listeners) {
195 if (iter.second == remote.promote()) {
196 pkgName = iter.first;
197 break;
198 }
199 }
200 if (pkgName.empty()) {
201 DMLOG(DM_LOG_ERROR, "AppDeathRecipient: OnRemoteDied, no pkgName matched");
202 return;
203 }
204 DMLOG(DM_LOG_INFO, "AppDeathRecipient: OnRemoteDied for %s", pkgName.c_str());
205 IpcServerStub::GetInstance().UnRegisterDeviceManagerListener(pkgName);
206 }
207 } // namespace DistributedHardware
208 } // namespace OHOS
209