• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 #include "ipc_cmd_register.h"
18 #include "ipc_skeleton.h"
19 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
20 #include "kv_adapter_manager.h"
21 #endif
22 #ifdef SUPPORT_MEMMGR
23 #include "mem_mgr_client.h"
24 #include "mem_mgr_proxy.h"
25 #endif // SUPPORT_MEMMGR
26 #include "system_ability_definition.h"
27 #include "device_manager_service.h"
28 #include "device_manager_service_notify.h"
29 #include "device_name_manager.h"
30 #include "dm_error_type.h"
31 #include "dm_device_info.h"
32 #include "ffrt.h"
33 #include <unistd.h>
34 #include <string>
35 #include <fcntl.h>
36 #include <sys/types.h>
37 #include "dm_log.h"
38 #include "multiple_user_connector.h"
39 #include "permission_manager.h"
40 
41 namespace OHOS {
42 namespace DistributedHardware {
43 DM_IMPLEMENT_SINGLE_INSTANCE(IpcServerStub);
44 
45 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&IpcServerStub::GetInstance());
46 constexpr int32_t DM_IPC_THREAD_NUM = 32;
47 constexpr int32_t MAX_CALLBACK_NUM = 5000;
48 constexpr int32_t RECLAIM_DELAY_TIME = 5 * 60 * 1000 * 1000; // 5 minutes
49 constexpr int32_t ECHO_COUNT = 2;
50 
IpcServerStub()51 IpcServerStub::IpcServerStub() : SystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID, true)
52 {
53     registerToService_ = false;
54     state_ = ServiceRunningState::STATE_NOT_START;
55 }
56 
OnStart()57 void IpcServerStub::OnStart()
58 {
59     LOGI("IpcServerStub::OnStart start");
60     if (state_ == ServiceRunningState::STATE_RUNNING) {
61         LOGI("IpcServerStub has already started.");
62         return;
63     }
64 
65     IPCSkeleton::SetMaxWorkThreadNum(DM_IPC_THREAD_NUM);
66 
67     LOGI("called:AddAbilityListener begin!");
68     AddSystemAbilityListener(DISTRIBUTED_HARDWARE_SA_ID);
69 #ifdef SUPPORT_MEMMGR
70     AddSystemAbilityListener(MEMORY_MANAGER_SA_ID);
71 #endif // SUPPORT_MEMMGR
72     AddSystemAbilityListener(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN);
73     AddSystemAbilityListener(SCREENLOCK_SERVICE_ID);
74     AddSystemAbilityListener(SOFTBUS_SERVER_SA_ID);
75     LOGI("called:AddAbilityListener end!");
76 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
77     AddSystemAbilityListener(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
78 #endif
79     AddSystemAbilityListener(DEVICE_AUTH_SERVICE_ID);
80     AddSystemAbilityListener(ACCESS_TOKEN_MANAGER_SERVICE_ID);
81     DeviceManagerService::GetInstance().SubscribePackageCommonEvent();
82 }
83 
ReclaimMemmgrFileMemForDM()84 void IpcServerStub::ReclaimMemmgrFileMemForDM()
85 {
86     int32_t memmgrPid = getpid();
87     int32_t echoCnt = ECHO_COUNT;
88     for (int32_t i = 0; i < echoCnt; ++i) {
89         if (memmgrPid <= 0) {
90             LOGE("Get invalid pid : %{public}d.", memmgrPid);
91             return;
92         }
93         std::string path = JoinPath("/proc/", std::to_string(memmgrPid), "reclaim");
94         std::string contentStr = "1";
95         LOGI("Start echo 1 to pid : %{public}d, path: %{public}s", memmgrPid, path.c_str());
96         int32_t fd = open(path.c_str(), O_WRONLY);
97         if (fd == -1) {
98             LOGE("ReclaimMemmgrFileMemForDM open file failed.");
99             return;
100         }
101         if (write(fd, contentStr.c_str(), strlen(contentStr.c_str())) < 0) {
102             LOGE("ReclaimMemmgrFileMemForDM write file failed.");
103             close(fd);
104             return;
105         }
106         close(fd);
107     }
108     LOGI("ReclaimMemmgrFileMemForDM success.");
109 }
110 
AddDelimiter(const std::string & path)111 std::string IpcServerStub::AddDelimiter(const std::string &path)
112 {
113     if (path.empty()) {
114         return path;
115     }
116     if (path.rfind("/") != path.size() - 1) {
117         return path + "/";
118     }
119     return path;
120 }
121 
JoinPath(const std::string & prefixPath,const std::string & subPath)122 std::string IpcServerStub::JoinPath(const std::string &prefixPath, const std::string &subPath)
123 {
124     return AddDelimiter(prefixPath) + subPath;
125 }
126 
JoinPath(const std::string & prefixPath,const std::string & midPath,const std::string & subPath)127 std::string IpcServerStub::JoinPath(const std::string &prefixPath, const std::string &midPath,
128     const std::string &subPath)
129 {
130     return JoinPath(JoinPath(prefixPath, midPath), subPath);
131 }
132 
HandleSoftBusServerAdd()133 void IpcServerStub::HandleSoftBusServerAdd()
134 {
135     DeviceManagerService::GetInstance().InitSoftbusListener();
136     if (!Init()) {
137         LOGE("failed to init IpcServerStub");
138         state_ = ServiceRunningState::STATE_NOT_START;
139         return;
140     }
141     state_ = ServiceRunningState::STATE_RUNNING;
142     DeviceNameManager::GetInstance().InitDeviceNameWhenSoftBusReady();
143     ReclaimMemmgrFileMemForDM();
144     std::function<void()> task = [this]() {
145         LOGI("HandleSoftBusServerAdd After 5mins.");
146         ReclaimMemmgrFileMemForDM();
147     };
148     ffrt::submit(task, ffrt::task_attr().delay(RECLAIM_DELAY_TIME));
149     return;
150 }
151 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)152 void IpcServerStub::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
153 {
154     LOGI("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
155     if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
156         HandleSoftBusServerAdd();
157         return;
158     }
159 
160 #ifdef SUPPORT_MEMMGR
161     if (systemAbilityId == MEMORY_MANAGER_SA_ID) {
162         int pid = getpid();
163         Memory::MemMgrClient::GetInstance().NotifyProcessStatus(pid, 1, 1, DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
164         return;
165     }
166 #endif // SUPPORT_MEMMGR
167 
168     if (systemAbilityId == SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
169         MultipleUserConnector::SetAccountInfo(MultipleUserConnector::GetCurrentAccountUserID(),
170             MultipleUserConnector::GetCurrentDMAccountInfo());
171         DeviceManagerService::GetInstance().InitAccountInfo();
172         return;
173     }
174 
175     if (systemAbilityId == SCREENLOCK_SERVICE_ID) {
176         DeviceManagerService::GetInstance().InitScreenLockEvent();
177         return;
178     }
179 
180 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
181     if (systemAbilityId == DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID) {
182         KVAdapterManager::GetInstance().ReInit();
183         return;
184     }
185 #endif
186     if (systemAbilityId == DEVICE_AUTH_SERVICE_ID) {
187         DeviceManagerService::GetInstance().InitHichainListener();
188         return;
189     }
190     if (systemAbilityId == ACCESS_TOKEN_MANAGER_SERVICE_ID) {
191         DeviceManagerService::GetInstance().InitHichainListener();
192         return;
193     }
194 }
195 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)196 void IpcServerStub::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
197 {
198     LOGI("OnRemoveSystemAbility systemAbilityId:%{public}d removed!", systemAbilityId);
199     if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
200         DeviceManagerService::GetInstance().UninitSoftbusListener();
201     } else if (systemAbilityId == DISTRIBUTED_HARDWARE_SA_ID) {
202         DeviceManagerService::GetInstance().LoadHardwareFwkService();
203     }
204 }
205 
Init()206 bool IpcServerStub::Init()
207 {
208     LOGI("IpcServerStub::Init ready to init.");
209     DeviceManagerService::GetInstance().InitDMServiceListener();
210     if (!registerToService_) {
211         bool ret = Publish(this);
212         if (!ret) {
213             LOGE("IpcServerStub::Init Publish failed!");
214             return false;
215         }
216         registerToService_ = true;
217         KVAdapterManager::GetInstance().Init();
218     }
219     return true;
220 }
221 
OnStop()222 void IpcServerStub::OnStop()
223 {
224     LOGI("IpcServerStub::OnStop ready to stop service.");
225     DeviceManagerService::GetInstance().UninitDMServiceListener();
226     state_ = ServiceRunningState::STATE_NOT_START;
227     registerToService_ = false;
228 #ifdef SUPPORT_MEMMGR
229     int pid = getpid();
230     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(pid, 1, 0, DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
231 #endif // SUPPORT_MEMMGR
232     LOGI("IpcServerStub::OnStop end.");
233 }
234 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)235 int32_t IpcServerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
236 {
237     auto remoteDescriptor = data.ReadInterfaceToken();
238     if (GetDescriptor() != remoteDescriptor) {
239         LOGI("ReadInterfaceToken fail!");
240         return ERR_DM_IPC_READ_FAILED;
241     }
242     int32_t ret = IpcCmdRegister::GetInstance().OnIpcCmd(static_cast<int32_t>(code), data, reply);
243     if (ret == ERR_DM_UNSUPPORTED_IPC_COMMAND) {
244         LOGW("unsupported code: %{public}d", code);
245         return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
246     }
247     return ret;
248 }
249 
SendCmd(int32_t cmdCode,std::shared_ptr<IpcReq> req,std::shared_ptr<IpcRsp> rsp)250 int32_t IpcServerStub::SendCmd(int32_t cmdCode, std::shared_ptr<IpcReq> req, std::shared_ptr<IpcRsp> rsp)
251 {
252     MessageParcel data;
253     MessageParcel reply;
254     MessageOption option;
255     if (cmdCode < 0 || cmdCode >= IPC_MSG_BUTT) {
256         LOGE("IpcServerStub::SendCmd error: Invalid para, cmdCode: %{public}d", (int32_t)cmdCode);
257         return IPCObjectStub::OnRemoteRequest(cmdCode, data, reply, option);
258     }
259 
260     if (IpcCmdRegister::GetInstance().SetRequest(cmdCode, req, data) != DM_OK) {
261         LOGE("set request cmd failed");
262         return ERR_DM_IPC_SEND_REQUEST_FAILED;
263     }
264     int32_t ret = IpcCmdRegister::GetInstance().OnIpcCmd(cmdCode, data, reply);
265     if (ret == ERR_DM_UNSUPPORTED_IPC_COMMAND) {
266         LOGW("unsupported code: %{public}d", cmdCode);
267         return IPCObjectStub::OnRemoteRequest(cmdCode, data, reply, option);
268     }
269     return IpcCmdRegister::GetInstance().ReadResponse(cmdCode, reply, rsp);
270 }
271 
QueryServiceState() const272 ServiceRunningState IpcServerStub::QueryServiceState() const
273 {
274     return state_;
275 }
276 
RegisterDeviceManagerListener(const ProcessInfo & processInfo,sptr<IpcRemoteBroker> listener)277 int32_t IpcServerStub::RegisterDeviceManagerListener(const ProcessInfo &processInfo, sptr<IpcRemoteBroker> listener)
278 {
279     LOGI("RegisterDeviceManagerListener start");
280     if (processInfo.pkgName.empty() || listener == nullptr) {
281         LOGE("RegisterDeviceManagerListener error: input parameter invalid.");
282         return ERR_DM_POINT_NULL;
283     }
284 
285     LOGI("Register device manager listener for package name: %{public}s", processInfo.pkgName.c_str());
286     std::lock_guard<std::mutex> autoLock(listenerLock_);
287     auto iter = dmListener_.find(processInfo);
288     if (iter != dmListener_.end()) {
289         LOGI("Listener already exists");
290         auto recipientIter = appRecipient_.find(processInfo);
291         if (recipientIter == appRecipient_.end()) {
292             LOGI("AppRecipient not exists");
293             dmListener_.erase(processInfo);
294         } else {
295             auto listener = iter->second;
296             auto appRecipient = recipientIter->second;
297             listener->AsObject()->RemoveDeathRecipient(appRecipient);
298             appRecipient_.erase(processInfo);
299             dmListener_.erase(processInfo);
300         }
301     }
302     sptr<AppDeathRecipient> appRecipient = sptr<AppDeathRecipient>(new AppDeathRecipient());
303     LOGI("Add death recipient.");
304     if (!listener->AsObject()->AddDeathRecipient(appRecipient)) {
305         LOGE("AddDeathRecipient Failed");
306     }
307     LOGI("Checking the number of listeners.");
308     if (dmListener_.size() > MAX_CALLBACK_NUM || appRecipient_.size() > MAX_CALLBACK_NUM) {
309         LOGE("dmListener_ or appRecipient_ size exceed the limit!");
310         return ERR_DM_FAILED;
311     }
312     dmListener_[processInfo] = listener;
313     appRecipient_[processInfo] = appRecipient;
314     LOGI("Add system sa.");
315     AddSystemSA(processInfo.pkgName);
316     LOGI("Register listener complete.");
317     return DM_OK;
318 }
319 
UnRegisterDeviceManagerListener(const ProcessInfo & processInfo)320 int32_t IpcServerStub::UnRegisterDeviceManagerListener(const ProcessInfo &processInfo)
321 {
322     if (processInfo.pkgName.empty()) {
323         LOGE("Invalid parameter, pkgName is empty.");
324         return ERR_DM_INPUT_PARA_INVALID;
325     }
326     LOGI("IpcServerStub::UnRegisterDeviceManagerListener In, pkgName: %{public}s", processInfo.pkgName.c_str());
327     std::lock_guard<std::mutex> autoLock(listenerLock_);
328     auto listenerIter = dmListener_.find(processInfo);
329     if (listenerIter == dmListener_.end()) {
330         LOGI("Listener not exists");
331         return DM_OK;
332     }
333     auto recipientIter = appRecipient_.find(processInfo);
334     if (recipientIter == appRecipient_.end()) {
335         LOGI("AppRecipient not exists");
336         dmListener_.erase(processInfo);
337         return DM_OK;
338     }
339     auto listener = listenerIter->second;
340     auto appRecipient = recipientIter->second;
341     listener->AsObject()->RemoveDeathRecipient(appRecipient);
342     appRecipient_.erase(processInfo);
343     dmListener_.erase(processInfo);
344     RemoveSystemSA(processInfo.pkgName);
345     DeviceManagerService::GetInstance().RemoveNotifyRecord(processInfo);
346     return DM_OK;
347 }
348 
GetAllProcessInfo()349 std::vector<ProcessInfo> IpcServerStub::GetAllProcessInfo()
350 {
351     std::vector<ProcessInfo> processInfoVec;
352     std::lock_guard<std::mutex> autoLock(listenerLock_);
353     for (const auto &iter : dmListener_) {
354         processInfoVec.push_back(iter.first);
355     }
356     return processInfoVec;
357 }
358 
GetDmListener(ProcessInfo processInfo) const359 const sptr<IpcRemoteBroker> IpcServerStub::GetDmListener(ProcessInfo processInfo) const
360 {
361     if (processInfo.pkgName.empty()) {
362         LOGE("Invalid parameter, pkgName is empty.");
363         return nullptr;
364     }
365     std::lock_guard<std::mutex> autoLock(listenerLock_);
366     auto iter = dmListener_.find(processInfo);
367     if (iter == dmListener_.end()) {
368         return nullptr;
369     }
370     return iter->second;
371 }
372 
GetDmListenerPkgName(const wptr<IRemoteObject> & remote) const373 const ProcessInfo IpcServerStub::GetDmListenerPkgName(const wptr<IRemoteObject> &remote) const
374 {
375     ProcessInfo processInfo;
376     std::lock_guard<std::mutex> autoLock(listenerLock_);
377     for (const auto &iter : dmListener_) {
378         if ((iter.second)->AsObject() == remote.promote()) {
379             processInfo = iter.first;
380             break;
381         }
382     }
383     return processInfo;
384 }
385 
Dump(int32_t fd,const std::vector<std::u16string> & args)386 int32_t IpcServerStub::Dump(int32_t fd, const std::vector<std::u16string>& args)
387 {
388     LOGI("DistributedHardwareService Dump.");
389     std::vector<std::string> argsStr {};
390     for (auto item : args) {
391         argsStr.emplace_back(Str16ToStr8(item));
392     }
393 
394     std::string result("");
395     int ret = DeviceManagerService::GetInstance().DmHiDumper(argsStr, result);
396     if (ret != DM_OK) {
397         LOGE("Dump error, ret = %{public}d", ret);
398     }
399 
400     ret = dprintf(fd, "%s\n", result.c_str());
401     if (ret < 0) {
402         LOGE("HiDumper dprintf error");
403         ret = ERR_DM_FAILED;
404     }
405     return ret;
406 }
407 
OnRemoteDied(const wptr<IRemoteObject> & remote)408 void AppDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
409 {
410     ProcessInfo processInfo = IpcServerStub::GetInstance().GetDmListenerPkgName(remote);
411     LOGI("AppDeathRecipient: OnRemoteDied for %{public}s", processInfo.pkgName.c_str());
412     IpcServerStub::GetInstance().UnRegisterDeviceManagerListener(processInfo);
413     DeviceManagerService::GetInstance().ClearDiscoveryCache(processInfo);
414     DeviceManagerServiceNotify::GetInstance().ClearDiedProcessCallback(processInfo);
415     DeviceManagerService::GetInstance().ClearPulishIdCache(processInfo.pkgName);
416 }
417 
AddSystemSA(const std::string & pkgName)418 void IpcServerStub::AddSystemSA(const std::string &pkgName)
419 {
420     if (PermissionManager::GetInstance().CheckSystemSA(pkgName)) {
421         systemSA_.insert(pkgName);
422     }
423 }
424 
RemoveSystemSA(const std::string & pkgName)425 void IpcServerStub::RemoveSystemSA(const std::string &pkgName)
426 {
427     if (PermissionManager::GetInstance().CheckSystemSA(pkgName) || systemSA_.find(pkgName) != systemSA_.end()) {
428         systemSA_.erase(pkgName);
429     }
430 }
431 
GetSystemSA()432 std::set<std::string> IpcServerStub::GetSystemSA()
433 {
434     std::lock_guard<std::mutex> autoLock(listenerLock_);
435     std::set<std::string> systemSA;
436     for (const auto &item : systemSA_) {
437         systemSA.insert(item);
438     }
439     return systemSA;
440 }
441 } // namespace DistributedHardware
442 } // namespace OHOS
443