• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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