1 /*
2  * Copyright (c) 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 #ifdef SUPPORT_GRAPHICS
17 #include "ability_first_frame_state_observer_manager.h"
18 
19 #include "ability_first_frame_state_observer_stub.h"
20 #include "hilog_tag_wrapper.h"
21 #include "permission_verification.h"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
AbilityFirstFrameStateObserverSet(bool isNotifyAllBundles)25 AbilityFirstFrameStateObserverSet::AbilityFirstFrameStateObserverSet(bool isNotifyAllBundles)
26     : isNotifyAllBundles_(isNotifyAllBundles) {}
27 
AddAbilityFirstFrameStateObserver(const sptr<IAbilityFirstFrameStateObserver> & observer,const std::string & targetBundleName)28 int32_t AbilityFirstFrameStateObserverSet::AddAbilityFirstFrameStateObserver(
29     const sptr<IAbilityFirstFrameStateObserver> &observer, const std::string &targetBundleName)
30 {
31     if (observer == nullptr || observer->AsObject() == nullptr) {
32         TAG_LOGE(AAFwkTag::ABILITYMGR, "The param observer or observer->AsObject is nullptr.");
33         return ERR_INVALID_VALUE;
34     }
35     {
36         std::lock_guard<ffrt::mutex> lockRegister(observerLock_);
37         for (auto it : observerMap_) {
38             if (it.first->AsObject() == observer->AsObject()) {
39                 TAG_LOGE(AAFwkTag::ABILITYMGR, "Observer exist.");
40                 return ERR_OK;
41             }
42         }
43         observerMap_.emplace(observer, targetBundleName);
44         TAG_LOGD(AAFwkTag::ABILITYMGR, "observerMap_ size:%{public}zu", observerMap_.size());
45         AddObserverDeathRecipient(observer);
46     }
47     return ERR_OK;
48 }
49 
AddObserverDeathRecipient(const sptr<IRemoteBroker> & observer)50 void AbilityFirstFrameStateObserverSet::AddObserverDeathRecipient(const sptr<IRemoteBroker> &observer)
51 {
52     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
53     if (observer == nullptr || observer->AsObject() == nullptr) {
54         TAG_LOGE(AAFwkTag::ABILITYMGR, "The param observer or observer->AsObject is nullptr.");
55         return;
56     }
57     auto it = recipientMap_.find(observer->AsObject());
58     if (it != recipientMap_.end()) {
59         TAG_LOGE(AAFwkTag::ABILITYMGR, "This death recipient has been added.");
60         return;
61     }
62     auto deathRecipientFunc = [](const wptr<IRemoteObject> &remote) {
63         auto object = remote.promote();
64         if (object == nullptr) {
65             TAG_LOGE(AAFwkTag::ABILITYMGR, "object is nullptr.");
66             return;
67         }
68         sptr<IAbilityFirstFrameStateObserver> observer = iface_cast<IAbilityFirstFrameStateObserver>(object);
69         AbilityFirstFrameStateObserverManager::GetInstance().UnregisterAbilityFirstFrameStateObserver(observer);
70     };
71     sptr<IRemoteObject::DeathRecipient> deathRecipient =
72         new (std::nothrow) AbilityFirstFrameStateObserverRecipient(deathRecipientFunc);
73     if (deathRecipient == nullptr) {
74         TAG_LOGE(AAFwkTag::ABILITYMGR, "deathRecipient is nullptr.");
75         return;
76     }
77     if (!observer->AsObject()->AddDeathRecipient(deathRecipient)) {
78         TAG_LOGE(AAFwkTag::ABILITYMGR, "AddDeathRecipient failed.");
79     }
80     recipientMap_.emplace(observer->AsObject(), deathRecipient);
81     TAG_LOGD(AAFwkTag::ABILITYMGR, "observerMap_ size:%{public}zu", recipientMap_.size());
82 }
83 
RemoveAbilityFirstFrameStateObserver(const sptr<IAbilityFirstFrameStateObserver> & observer)84 int32_t AbilityFirstFrameStateObserverSet::RemoveAbilityFirstFrameStateObserver(
85     const sptr<IAbilityFirstFrameStateObserver> &observer)
86 {
87     std::lock_guard<ffrt::mutex> lockRegister(observerLock_);
88     for (auto it = observerMap_.begin(); it != observerMap_.end(); ++it) {
89         if (it->first->AsObject() == observer->AsObject()) {
90             observerMap_.erase(it);
91             TAG_LOGD(AAFwkTag::ABILITYMGR, "observerMap_ size:%{public}zu", observerMap_.size());
92             RemoveObserverDeathRecipient(observer);
93             return ERR_OK;
94         }
95     }
96     TAG_LOGD(AAFwkTag::ABILITYMGR, "Remove observer failed.");
97     return ERR_INVALID_VALUE;
98 }
99 
RemoveObserverDeathRecipient(const sptr<IRemoteBroker> & observer)100 void AbilityFirstFrameStateObserverSet::RemoveObserverDeathRecipient(const sptr<IRemoteBroker> &observer)
101 {
102     if (observer == nullptr || observer->AsObject() == nullptr) {
103         TAG_LOGE(AAFwkTag::ABILITYMGR, "The param observer is nullptr.");
104         return;
105     }
106     auto it = recipientMap_.find(observer->AsObject());
107     if (it != recipientMap_.end()) {
108         it->first->RemoveDeathRecipient(it->second);
109         recipientMap_.erase(it);
110     }
111     TAG_LOGD(AAFwkTag::ABILITYMGR, "recipientMap_ size:%{public}zu", recipientMap_.size());
112 }
113 
OnAbilityFirstFrameState(const std::shared_ptr<AbilityRecord> & abilityRecord)114 void AbilityFirstFrameStateObserverSet::OnAbilityFirstFrameState(const std::shared_ptr<AbilityRecord> &abilityRecord)
115 {
116     if (abilityRecord == nullptr) {
117         TAG_LOGE(AAFwkTag::ABILITYMGR, "The param abilityRecord is nullptr.");
118         return;
119     }
120     const AppExecFwk::AbilityInfo abilityInfo = abilityRecord->GetAbilityInfo();
121     AbilityFirstFrameStateData abilityFirstFrameStateData;
122     abilityFirstFrameStateData.bundleName = abilityInfo.bundleName;
123     abilityFirstFrameStateData.moduleName = abilityInfo.moduleName;
124     abilityFirstFrameStateData.abilityName = abilityInfo.name;
125     abilityFirstFrameStateData.appIndex = abilityRecord->GetAppIndex();
126     abilityFirstFrameStateData.coldStart = abilityRecord->GetColdStartFlag();
127     std::lock_guard<ffrt::mutex> lockRegister(observerLock_);
128     for (auto it : observerMap_) {
129         if (!isNotifyAllBundles_) {
130             if (it.second == abilityInfo.bundleName) {
131                 it.first->OnAbilityFirstFrameState(abilityFirstFrameStateData);
132             }
133         } else {
134             it.first->OnAbilityFirstFrameState(abilityFirstFrameStateData);
135         }
136     }
137 }
138 
GetInstance()139 AbilityFirstFrameStateObserverManager &AbilityFirstFrameStateObserverManager::GetInstance()
140 {
141     static AbilityFirstFrameStateObserverManager instance;
142     return instance;
143 }
144 
Init()145 void AbilityFirstFrameStateObserverManager::Init()
146 {
147     if (!stateObserverSetForBundleName_) {
148         stateObserverSetForBundleName_ = std::make_unique<AbilityFirstFrameStateObserverSet>(false);
149     }
150     if (!stateObserverSetForAllBundles_) {
151         stateObserverSetForAllBundles_ = std::make_unique<AbilityFirstFrameStateObserverSet>(true);
152     }
153 }
154 
RegisterAbilityFirstFrameStateObserver(const sptr<IAbilityFirstFrameStateObserver> & observer,const std::string & targetBundleName)155 int32_t AbilityFirstFrameStateObserverManager::RegisterAbilityFirstFrameStateObserver(
156     const sptr<IAbilityFirstFrameStateObserver> &observer, const std::string &targetBundleName)
157 {
158     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
159     if (!PermissionVerification::GetInstance()->IsSystemAppCall()) {
160         TAG_LOGE(AAFwkTag::ABILITYMGR, "verify system app failed");
161         return ERR_NOT_SYSTEM_APP;
162     }
163     // verify permissions.
164     if (AAFwk::PermissionVerification::GetInstance()->VerifyAppStateObserverPermission() == ERR_PERMISSION_DENIED) {
165         TAG_LOGE(AAFwkTag::ABILITYMGR, "Permission verification failed.");
166         return ERR_PERMISSION_DENIED;
167     }
168     if (targetBundleName.empty()) {
169         return stateObserverSetForAllBundles_->AddAbilityFirstFrameStateObserver(observer, "");
170     } else {
171         return stateObserverSetForBundleName_->AddAbilityFirstFrameStateObserver(observer, targetBundleName);
172     }
173 }
174 
UnregisterAbilityFirstFrameStateObserver(const sptr<IAbilityFirstFrameStateObserver> & observer)175 int32_t AbilityFirstFrameStateObserverManager::UnregisterAbilityFirstFrameStateObserver(
176     const sptr<IAbilityFirstFrameStateObserver> &observer)
177 {
178     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
179     if (!PermissionVerification::GetInstance()->IsSystemAppCall()) {
180         TAG_LOGE(AAFwkTag::ABILITYMGR, "verify system app failed");
181         return ERR_NOT_SYSTEM_APP;
182     }
183     // verify permissions.
184     if (AAFwk::PermissionVerification::GetInstance()->VerifyAppStateObserverPermission() == ERR_PERMISSION_DENIED) {
185         TAG_LOGE(AAFwkTag::ABILITYMGR, "Permission verification failed.");
186         return ERR_PERMISSION_DENIED;
187     }
188     if (stateObserverSetForBundleName_->RemoveAbilityFirstFrameStateObserver(observer) == ERR_OK) {
189         return ERR_OK;
190     }
191     stateObserverSetForAllBundles_->RemoveAbilityFirstFrameStateObserver(observer);
192     return ERR_OK;
193 }
194 
HandleOnFirstFrameState(const std::shared_ptr<AbilityRecord> & abilityRecord)195 void AbilityFirstFrameStateObserverManager::HandleOnFirstFrameState(
196     const std::shared_ptr<AbilityRecord> &abilityRecord)
197 {
198     stateObserverSetForBundleName_->OnAbilityFirstFrameState(abilityRecord);
199     stateObserverSetForAllBundles_->OnAbilityFirstFrameState(abilityRecord);
200 }
201 }  // namespace AppExecFwk
202 }  // namespace OHOS
203 #endif // SUPPORT_GRAPHICS