1 /*
2 * Copyright (c) 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 "ability_start_with_wait_observer_manager.h"
17
18 #include <chrono>
19
20 #include "ability_start_with_wait_observer_data.h"
21 #include "hilog_tag_wrapper.h"
22 #include "hitrace_meter.h"
23
24 namespace OHOS {
25 namespace AAFwk {
26
GetInstance()27 AbilityStartWithWaitObserverManager& AbilityStartWithWaitObserverManager::GetInstance()
28 {
29 static AbilityStartWithWaitObserverManager instance;
30 return instance;
31 }
32
RegisterObserver(Want & want,sptr<IAbilityStartWithWaitObserver> observer)33 int32_t AbilityStartWithWaitObserverManager::RegisterObserver(Want &want, sptr<IAbilityStartWithWaitObserver> observer)
34 {
35 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityStartWithWaitObserverManager::RegisterObserver called");
36 if (!observer || !observer->AsObject()) {
37 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
38 return ERR_NULL_OBJECT;
39 }
40
41 std::lock_guard<std::mutex> guard(oberverMutex_);
42 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer list size:%{public}zu", observerList_.size());
43 for (auto& ob : observerList_) {
44 if (!ob.first) {
45 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer in observerList_");
46 continue;
47 }
48 if (observer->AsObject() == ob.first->AsObject()) {
49 TAG_LOGI(AAFwkTag::ABILITYMGR, "observer already register");
50 return ERR_OK;
51 }
52 }
53 AbilityForegroundInfo abilityForegroundInfo;
54 observerId_ = (observerId_ == INT_MAX) ? 0 : (observerId_ + 1);
55 abilityForegroundInfo.observerId = observerId_;
56 abilityForegroundInfo.startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
57 std::chrono::system_clock::now().time_since_epoch()).count();
58 // 1.save deathRecipient_
59 abilityForegroundInfo.deathRecipient = GenerateDeathRecipient(observer);
60 observerList_.emplace(observer, abilityForegroundInfo);
61 want.SetParam(Want::START_ABILITY_WITH_WAIT_OBSERVER_ID_KEY, observerId_);
62 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer list size:%{public}zu", observerList_.size());
63 return ERR_OK;
64 }
65
UnregisterObserver(sptr<IAbilityStartWithWaitObserver> observer)66 void AbilityStartWithWaitObserverManager::UnregisterObserver(sptr<IAbilityStartWithWaitObserver> observer)
67 {
68 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityStartWithWaitObserverManager::UnregisterObserver called");
69 if (!observer || !observer->AsObject()) {
70 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
71 return;
72 }
73 std::lock_guard<std::mutex> guard(oberverMutex_);
74 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer list size:%{public}zu", observerList_.size());
75 for (auto& ob : observerList_) {
76 if (!ob.first) {
77 continue;
78 }
79 if (ob.first->AsObject() == observer->AsObject()) {
80 // 1.remove deathRecipient for proxy
81 observer->AsObject()->RemoveDeathRecipient(ob.second.deathRecipient);
82 observerList_.erase(ob.first);
83 break;
84 }
85 }
86 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer list size:%{public}zu", observerList_.size());
87 }
88
NotifyAATerminateWait(Want & want,TerminateReason reason)89 void AbilityStartWithWaitObserverManager::NotifyAATerminateWait(Want& want, TerminateReason reason)
90 {
91 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityStartWithWaitObserverManager::NotifyAATerminateWait called");
92 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
93 auto observerId = want.GetIntParam(Want::START_ABILITY_WITH_WAIT_OBSERVER_ID_KEY, -1);
94 if (observerId == -1) {
95 TAG_LOGE(AAFwkTag::ABILITYMGR, "invaid observerId");
96 return;
97 }
98 sptr<IAbilityStartWithWaitObserver> abilityStartWithWaitObserver = nullptr;
99 {
100 std::lock_guard<std::mutex> guard(oberverMutex_);
101 for (auto& observer : observerList_) {
102 if (!observer.first) {
103 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
104 continue;
105 }
106 if (observerId == observer.second.observerId) {
107 abilityStartWithWaitObserver = observer.first;
108 // 1.remove deathRecipient for abilityStartWithWaitObserver
109 if (observer.first->AsObject()) {
110 observer.first->AsObject()->RemoveDeathRecipient(observer.second.deathRecipient);
111 }
112 observerList_.erase(observer.first);
113 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer list size:%{public}zu", observerList_.size());
114 break;
115 }
116 }
117 }
118 if (abilityStartWithWaitObserver) {
119 AbilityStartWithWaitObserverData data;
120 data.reason = static_cast<uint32_t>(reason);
121 abilityStartWithWaitObserver->NotifyAATerminateWait(data);
122 } else {
123 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityStartWithWaitObserver is nullptr");
124 }
125 want.RemoveParam(Want::START_ABILITY_WITH_WAIT_OBSERVER_ID_KEY);
126 }
127
NotifyAATerminateWait(std::shared_ptr<AbilityRecord> abilityRecord,TerminateReason reason)128 void AbilityStartWithWaitObserverManager::NotifyAATerminateWait(
129 std::shared_ptr<AbilityRecord> abilityRecord, TerminateReason reason)
130 {
131 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
132 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityStartWithWaitObserverManager::NotifyAATerminateWait called");
133 if (!abilityRecord) {
134 TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityRecord");
135 return;
136 }
137 auto observerId = abilityRecord->GetWant().GetIntParam(Want::START_ABILITY_WITH_WAIT_OBSERVER_ID_KEY, -1);
138 if (observerId == -1) {
139 TAG_LOGW(AAFwkTag::ABILITYMGR, "invaid observerId");
140 return;
141 }
142 TAG_LOGD(AAFwkTag::ABILITYMGR, "observerId:%{public}d", observerId);
143 abilityRecord->RemoveSpecifiedWantParam(Want::START_ABILITY_WITH_WAIT_OBSERVER_ID_KEY);
144 sptr<IAbilityStartWithWaitObserver> proxy = nullptr;
145 AbilityStartWithWaitObserverData data;
146 {
147 std::lock_guard<std::mutex> guard(oberverMutex_);
148 for (auto& observer : observerList_) {
149 if (!observer.first) {
150 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
151 continue;
152 }
153 TAG_LOGD(AAFwkTag::ABILITYMGR, "observerId = %{public}d", observer.second.observerId);
154 if (observerId == observer.second.observerId) {
155 data.reason = static_cast<uint32_t>(reason);
156 data.coldStart = observer.second.coldStart;
157 data.startTime = observer.second.startTime;
158 data.foregroundTime = std::chrono::duration_cast<std::chrono::milliseconds>(
159 std::chrono::system_clock::now().time_since_epoch()).count();
160 data.bundleName = abilityRecord->GetAbilityInfo().bundleName;
161 data.abilityName = abilityRecord->GetAbilityInfo().name;
162 TAG_LOGI(AAFwkTag::ABILITYMGR, "notify aa, time:%{public}" PRId64 " foregroundTime:%{public}" PRId64
163 " ,bundleName:%{public}s ability:%{public}s", data.startTime, data.foregroundTime,
164 data.bundleName.c_str(), data.abilityName.c_str());
165 proxy = observer.first;
166 // 1.remove deathRecipient for proxy
167 if (observer.first->AsObject()) {
168 observer.first->AsObject()->RemoveDeathRecipient(observer.second.deathRecipient);
169 }
170 observerList_.erase(observer.first);
171 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer list size:%{public}zu", observerList_.size());
172 break;
173 }
174 }
175 }
176
177 if (proxy) {
178 proxy->NotifyAATerminateWait(data);
179 } else {
180 TAG_LOGE(AAFwkTag::ABILITYMGR, "proxy not find");
181 }
182 }
183
SetColdStartForShellCall(std::shared_ptr<AbilityRecord> abilityRecord)184 void AbilityStartWithWaitObserverManager::SetColdStartForShellCall(std::shared_ptr<AbilityRecord> abilityRecord)
185 {
186 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityStartWithWaitObserverManager::SetColdStartForShellCall called");
187 if (!abilityRecord) {
188 TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityRecord");
189 return;
190 }
191 auto observerId = abilityRecord->GetWant().GetIntParam(Want::START_ABILITY_WITH_WAIT_OBSERVER_ID_KEY, -1);
192 if (observerId == -1) {
193 TAG_LOGW(AAFwkTag::ABILITYMGR, "invaid observerId");
194 return;
195 }
196 std::lock_guard<std::mutex> guard(oberverMutex_);
197 for (auto& observer : observerList_) {
198 if (!observer.first) {
199 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
200 continue;
201 }
202 if (observerId == observer.second.observerId) {
203 TAG_LOGI(AAFwkTag::ABILITYMGR, "set cold start, bundleName:%{public}s ability:%{public}s",
204 abilityRecord->GetAbilityInfo().bundleName.c_str(), abilityRecord->GetAbilityInfo().name.c_str());
205 observer.second.coldStart = true;
206 }
207 }
208 }
209
GenerateDeathRecipient(sptr<IAbilityStartWithWaitObserver> observer)210 sptr<AbilityStartWithWaitObserverRecipient> AbilityStartWithWaitObserverManager::GenerateDeathRecipient(
211 sptr<IAbilityStartWithWaitObserver> observer)
212 {
213 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityStartWithWaitObserverManager::GenerateDeathRecipient called");
214 if (!observer || !observer->AsObject()) {
215 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
216 return nullptr;
217 }
218 auto deathRecipientFunc = [](const wptr<IRemoteObject> &remote) {
219 TAG_LOGD(AAFwkTag::ABILITYMGR, "death recipient call");
220 auto object = remote.promote();
221 if (object == nullptr) {
222 TAG_LOGE(AAFwkTag::ABILITYMGR, "object null");
223 return;
224 }
225 auto observer = iface_cast<IAbilityStartWithWaitObserver>(object);
226 AbilityStartWithWaitObserverManager::GetInstance().UnregisterObserver(observer);
227 };
228 auto deathRecipient = sptr<AbilityStartWithWaitObserverRecipient>::MakeSptr(deathRecipientFunc);
229 if (deathRecipient == nullptr) {
230 TAG_LOGE(AAFwkTag::ABILITYMGR, "null deathRecipient");
231 return nullptr;
232 }
233 if (!observer->AsObject()->AddDeathRecipient(deathRecipient)) {
234 TAG_LOGE(AAFwkTag::ABILITYMGR, "AddDeathRecipient fail");
235 }
236 return deathRecipient;
237 }
238 } // namespace AAFwk
239 } // namespace OHOS