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 #include "app_scheduler.h"
17 #include "assert_fault_callback_death_mgr.h"
18 #include "hilog_tag_wrapper.h"
19 #include "hitrace_meter.h"
20 #include "in_process_call_wrapper.h"
21 
22 namespace OHOS {
23 namespace AbilityRuntime {
~AssertFaultCallbackDeathMgr()24 AssertFaultCallbackDeathMgr::~AssertFaultCallbackDeathMgr()
25 {
26     for (auto &item : assertFaultSessionDialogs_) {
27         if (item.second.iremote_ == nullptr || item.second.deathObj_ == nullptr) {
28             TAG_LOGW(AAFwkTag::ABILITYMGR, "Callback is nullptr.");
29             continue;
30         }
31         item.second.iremote_->RemoveDeathRecipient(item.second.deathObj_);
32     }
33 
34     assertFaultSessionDialogs_.clear();
35 }
36 
AddAssertFaultCallback(sptr<IRemoteObject> & remote,CallbackTask callback)37 void AssertFaultCallbackDeathMgr::AddAssertFaultCallback(sptr<IRemoteObject> &remote, CallbackTask callback)
38 {
39     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
40     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
41     if (remote == nullptr) {
42         TAG_LOGE(AAFwkTag::ABILITYMGR, "Params remote is nullptr.");
43         return;
44     }
45 
46     std::weak_ptr<AssertFaultCallbackDeathMgr> weakThis = shared_from_this();
47     sptr<AssertFaultRemoteDeathRecipient> deathRecipient =
48         new (std::nothrow) AssertFaultRemoteDeathRecipient([weakThis] (const wptr<IRemoteObject> &remote) {
49             auto callbackDeathMgr = weakThis.lock();
50             if (callbackDeathMgr == nullptr) {
51                 TAG_LOGE(AAFwkTag::ABILITYMGR, "Invalid manager instance.");
52                 return;
53             }
54             callbackDeathMgr->RemoveAssertFaultCallback(remote, true);
55         });
56 
57     remote->AddDeathRecipient(deathRecipient);
58     auto callerPid = IPCSkeleton::GetCallingPid();
59     uint64_t assertFaultSessionId = reinterpret_cast<uint64_t>(remote.GetRefPtr());
60     std::unique_lock<std::mutex> lock(assertFaultSessionMutex_);
61     assertFaultSessionDialogs_[assertFaultSessionId] = {callerPid, remote, deathRecipient, callback};
62     auto appScheduler = DelayedSingleton<AAFwk::AppScheduler>::GetInstance();
63     if (appScheduler == nullptr) {
64         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get app scheduler instance is nullptr.");
65         return;
66     }
67 }
68 
RemoveAssertFaultCallback(const wptr<IRemoteObject> & remote,bool isCallbackDeath)69 void AssertFaultCallbackDeathMgr::RemoveAssertFaultCallback(const wptr<IRemoteObject> &remote, bool isCallbackDeath)
70 {
71     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
72     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
73     auto callback = remote.promote();
74     if (callback == nullptr) {
75         TAG_LOGE(AAFwkTag::ABILITYMGR, "Invalid dead remote object.");
76         return;
77     }
78 
79     uint64_t assertFaultSessionId = reinterpret_cast<uint64_t>(callback.GetRefPtr());
80     std::unique_lock<std::mutex> lock(assertFaultSessionMutex_);
81     auto iter = assertFaultSessionDialogs_.find(assertFaultSessionId);
82     if (iter == assertFaultSessionDialogs_.end()) {
83         TAG_LOGE(AAFwkTag::ABILITYMGR, "Find assert fault session id failed.");
84         return;
85     }
86 
87     if (isCallbackDeath && iter->second.callbackTask_ != nullptr) {
88         TAG_LOGD(AAFwkTag::ABILITYMGR, "Application Death, close assert fault Dialog.");
89         iter->second.callbackTask_(std::to_string(assertFaultSessionId));
90     }
91 
92     if (iter->second.iremote_ != nullptr && iter->second.deathObj_ != nullptr) {
93         iter->second.iremote_->RemoveDeathRecipient(iter->second.deathObj_);
94     }
95 
96     assertFaultSessionDialogs_.erase(iter);
97 }
98 
CallAssertFaultCallback(uint64_t assertFaultSessionId,AAFwk::UserStatus status)99 void AssertFaultCallbackDeathMgr::CallAssertFaultCallback(uint64_t assertFaultSessionId, AAFwk::UserStatus status)
100 {
101     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
102     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
103     DeathItem item;
104     {
105         std::unique_lock<std::mutex> lock(assertFaultSessionMutex_);
106         auto iter = assertFaultSessionDialogs_.find(assertFaultSessionId);
107         if (iter == assertFaultSessionDialogs_.end()) {
108             TAG_LOGE(AAFwkTag::ABILITYMGR, "Not find assert fault session by id.");
109             return;
110         }
111 
112         item = iter->second;
113     }
114 
115     RemoveAssertFaultCallback(item.iremote_);
116     sptr<AssertFaultProxy> callback = iface_cast<AssertFaultProxy>(item.iremote_);
117     if (callback == nullptr) {
118         TAG_LOGE(AAFwkTag::ABILITYMGR, "Convert assert fault proxy failed, callback is nullptr.");
119         return;
120     }
121     callback->NotifyDebugAssertResult(status);
122     auto appScheduler = DelayedSingleton<AAFwk::AppScheduler>::GetInstance();
123     if (appScheduler == nullptr) {
124         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get app scheduler instance is nullptr.");
125         return;
126     }
127 }
128 } // namespace AbilityRuntime
129 } // namespace OHOS
130