1 /*
2 * Copyright (c) 2023-2024 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 "app_running_status_module.h"
17
18 #include <algorithm>
19
20 #include "app_running_status_proxy.h"
21 #include "cpp/mutex.h"
22 #include "hilog_tag_wrapper.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
RegisterListener(const sptr<AppRunningStatusListenerInterface> & listener)26 int32_t AppRunningStatusModule::RegisterListener(const sptr<AppRunningStatusListenerInterface> &listener)
27 {
28 TAG_LOGD(AAFwkTag::APPMGR, "called");
29 if (listener == nullptr || listener->AsObject() == nullptr) {
30 TAG_LOGE(AAFwkTag::APPMGR, "Listener is null.");
31 return ERR_INVALID_OPERATION;
32 }
33
34 std::lock_guard<std::mutex> lock(listenerMutex_);
35 auto findTask =
36 [listener](
37 const std::pair<sptr<AppRunningStatusListenerInterface>, sptr<IRemoteObject::DeathRecipient>> &item) {
38 return listener->AsObject() == item.first->AsObject();
39 };
40 auto itemFind = std::find_if(listeners_.begin(), listeners_.end(), findTask);
41 if (itemFind != listeners_.end()) {
42 TAG_LOGD(AAFwkTag::APPMGR, "Listener is already exist.");
43 return ERR_OK;
44 }
45
46 sptr<ClientDeathRecipient> deathRecipient = new (std::nothrow) ClientDeathRecipient(shared_from_this());
47 if (deathRecipient == nullptr) {
48 TAG_LOGE(AAFwkTag::APPMGR, "Death recipient is null.");
49 return ERR_NO_MEMORY;
50 }
51
52 listener->AsObject()->AddDeathRecipient(deathRecipient);
53 listeners_.emplace(listener, deathRecipient);
54 return ERR_OK;
55 }
56
UnregisterListener(const sptr<AppRunningStatusListenerInterface> & listener)57 int32_t AppRunningStatusModule::UnregisterListener(const sptr<AppRunningStatusListenerInterface> &listener)
58 {
59 TAG_LOGD(AAFwkTag::APPMGR, "called");
60 if (listener == nullptr || listener->AsObject() == nullptr) {
61 TAG_LOGE(AAFwkTag::APPMGR, "Input param invalid.");
62 return ERR_INVALID_VALUE;
63 }
64
65 return RemoveListenerAndDeathRecipient(listener->AsObject());
66 }
67
NotifyAppRunningStatusEvent(const std::string & bundle,int32_t uid,RunningStatus runningStatus)68 void AppRunningStatusModule::NotifyAppRunningStatusEvent(
69 const std::string &bundle, int32_t uid, RunningStatus runningStatus)
70 {
71 TAG_LOGD(AAFwkTag::APPMGR, "called");
72 std::lock_guard<std::mutex> lock(listenerMutex_);
73 for (const auto &item : listeners_) {
74 if (item.first == nullptr) {
75 TAG_LOGW(AAFwkTag::APPMGR, "Invalid listener.");
76 continue;
77 }
78
79 item.first->NotifyAppRunningStatus(bundle, uid, runningStatus);
80 }
81 }
82
ClientDeathRecipient(const std::weak_ptr<AppRunningStatusModule> & weakPtr)83 AppRunningStatusModule::ClientDeathRecipient::ClientDeathRecipient(const std::weak_ptr<AppRunningStatusModule> &weakPtr)
84 {
85 weakPtr_ = weakPtr;
86 }
87
OnRemoteDied(const wptr<IRemoteObject> & remote)88 void AppRunningStatusModule::ClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
89 {
90 TAG_LOGD(AAFwkTag::APPMGR, "called");
91 auto appRunningStatus = weakPtr_.lock();
92 if (appRunningStatus == nullptr) {
93 TAG_LOGE(AAFwkTag::APPMGR, "appRunningStatus is nullptr.");
94 return;
95 }
96 appRunningStatus->RemoveListenerAndDeathRecipient(remote);
97 }
98
RemoveListenerAndDeathRecipient(const wptr<IRemoteObject> & remote)99 int32_t AppRunningStatusModule::RemoveListenerAndDeathRecipient(const wptr<IRemoteObject> &remote)
100 {
101 TAG_LOGD(AAFwkTag::APPMGR, "called");
102 auto listener = remote.promote();
103 if (listener == nullptr) {
104 TAG_LOGE(AAFwkTag::APPMGR, "Remote object is nullptr.");
105 return ERR_INVALID_VALUE;
106 }
107
108 std::lock_guard<std::mutex> lock(listenerMutex_);
109 auto findTask =
110 [listener](
111 const std::pair<sptr<AppRunningStatusListenerInterface>, sptr<IRemoteObject::DeathRecipient>> &item) {
112 return listener == item.first->AsObject();
113 };
114 auto itemFind = std::find_if(listeners_.begin(), listeners_.end(), findTask);
115 if (itemFind == listeners_.end()) {
116 TAG_LOGE(AAFwkTag::APPMGR, "Listener is not exist.");
117 return ERR_INVALID_OPERATION;
118 }
119 auto storedListener = itemFind->first;
120 auto deathRecipient = itemFind->second;
121 listeners_.erase(itemFind);
122
123 if (storedListener == nullptr || storedListener->AsObject() == nullptr) {
124 TAG_LOGE(AAFwkTag::APPMGR, "Invalid listener.");
125 return ERR_INVALID_OPERATION;
126 }
127
128 storedListener->AsObject()->RemoveDeathRecipient(deathRecipient);
129 return ERR_OK;
130 }
131 } // namespace AbilityRuntime
132 } // namespace OHOS
133