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