• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 APP_NO_RESPONSE_DIALOG
17 #include "modal_system_app_freeze_uiextension.h"
18 
19 #include <chrono>
20 #include <mutex>
21 
22 #include "ability_record.h"
23 #include "hilog_tag_wrapper.h"
24 #include "hitrace_meter.h"
25 #include "in_process_call_wrapper.h"
26 #include "scene_board_judgement.h"
27 #include "session_manager_lite.h"
28 #include "window_visibility_info.h"
29 
30 using namespace OHOS::AAFwk;
31 using namespace OHOS::Rosen;
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 const std::string UIEXTENSION_TYPE_KEY = "ability.want.params.uiExtensionType";
36 const std::string UIEXTENSION_SYS_COMMON_UI = "sysDialog/common";
37 const std::string APP_FREEZE_PID = "APP_FREEZE_PID";
38 const std::string FREEZE_WINDOW_POSX = "FREEZE_WINDOW_POSX";
39 const std::string FREEZE_WINDOW_POSY = "FREEZE_WINDOW_POSY";
40 const std::string FREEZE_WINDOW_WIDTH = "FREEZE_WINDOW_WIDTH";
41 const std::string FREEZE_WINDOW_HEIGHT = "FREEZE_WINDOW_HEIGHT";
42 const std::string START_BUNDLE_NAME = "startBundleName";
43 const std::string APP_FREEZE_TOKEN = "freezeToken";
44 constexpr int32_t INVALID_USERID = -1;
45 constexpr int32_t MESSAGE_PARCEL_KEY_SIZE = 3;
46 constexpr uint32_t COMMAND_START_DIALOG = 1;
47 constexpr char INVALID_PID[] = "-1";
48 constexpr uint64_t TIMEOUT_INTERVAL_MS = 8000;
49 
GetInstance()50 ModalSystemAppFreezeUIExtension &ModalSystemAppFreezeUIExtension::GetInstance()
51 {
52     static ModalSystemAppFreezeUIExtension instance;
53     return instance;
54 }
55 
~ModalSystemAppFreezeUIExtension()56 ModalSystemAppFreezeUIExtension::~ModalSystemAppFreezeUIExtension()
57 {}
58 
ProcessAppFreeze(bool focusFlag,const FaultData & faultData,std::string pid,std::string bundleName,std::function<void ()> callback,bool isDialogExist)59 void ModalSystemAppFreezeUIExtension::ProcessAppFreeze(bool focusFlag, const FaultData &faultData, std::string pid,
60     std::string bundleName, std::function<void()> callback, bool isDialogExist)
61 {
62     const std::string SCENE_BAOARD_NAME = "com.ohos.sceneboard";
63     if ((bundleName == SCENE_BAOARD_NAME || faultData.waitSaveState) && callback) {
64         callback();
65         return;
66     }
67     FaultDataType faultType = faultData.faultType;
68     std::string name = faultData.errorObject.name;
69     bool isAppFreezeDialog = name == AppFreezeType::THREAD_BLOCK_6S || name == AppFreezeType::APP_INPUT_BLOCK ||
70         name == AppFreezeType::BUSSINESS_THREAD_BLOCK_6S;
71     uint64_t now =
72         std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch())
73             .count();
74     bool timeout = now - lastFreezeTime > TIMEOUT_INTERVAL_MS;
75     TAG_LOGI(AAFwkTag::ABILITYMGR,
76         "%{public}s is %{public}s.pid:%{public}s lastFreezePid:%{public}s", bundleName.c_str(),
77         focusFlag ? "focus" : "not focus", pid.c_str(), lastFreezePid.c_str());
78     bool isPullUpBox =
79         isAppFreezeDialog && (pid != lastFreezePid || (pid == lastFreezePid && timeout && !isDialogExist));
80     bool updateTypeName = name == AppFreezeType::THREAD_BLOCK_6S || name == AppFreezeType::BUSSINESS_THREAD_BLOCK_6S;
81     if (pid == lastFreezePid && updateTypeName) {
82         lastFreezeTime = now;
83     }
84     if (focusFlag && isPullUpBox) {
85         CreateModalUIExtension(pid, bundleName);
86     } else if (callback && (faultType != FaultDataType::APP_FREEZE || !isAppFreezeDialog)) {
87         callback();
88     }
89     if (!isDialogExist && !focusFlag && lastFreezePid == pid) {
90         lastFreezePid = INVALID_PID;
91         lastFocusStatus = false;
92     }
93 }
94 
CreateModalUIExtension(std::string & pid,std::string & bundleName)95 bool ModalSystemAppFreezeUIExtension::CreateModalUIExtension(std::string& pid, std::string& bundleName)
96 {
97     TAG_LOGD(AAFwkTag::ABILITYMGR, "Create Modal UIExtension Called");
98     sptr<IRemoteObject> token;
99     AAFwk::Want want;
100     std::unique_lock<std::mutex> lockAssertResult(appFreezeResultMutex_);
101     if (!CreateSystemDialogWant(pid, bundleName, token, want)) {
102         return false;
103     }
104     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
105     if (abilityManagerClient == nullptr) {
106         TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityManagerClient");
107         return false;
108     }
109     auto result = IN_PROCESS_CALL(abilityManagerClient->StartExtensionAbility(want, token));
110     if (result != ERR_OK) {
111         TAG_LOGE(AAFwkTag::ABILITYMGR, "StartExtensionAbility failed, result = %{public}d", result);
112         return false;
113     }
114     lastFreezePid = pid;
115     lastFocusStatus = true;
116     lastFreezeTime = std::chrono::duration_cast<std::chrono::milliseconds>(
117         std::chrono::steady_clock::now().time_since_epoch()).count();
118     TAG_LOGI(AAFwkTag::ABILITYMGR, "success, result = %{public}d", result);
119     return true;
120 }
121 
CreateSystemDialogWant(std::string & pid,std::string & bundleName,sptr<IRemoteObject> token,AAFwk::Want & want)122 bool ModalSystemAppFreezeUIExtension::CreateSystemDialogWant(
123     std::string& pid, std::string& bundleName, sptr<IRemoteObject> token, AAFwk::Want &want)
124 {
125     want.SetElementName(APP_NO_RESPONSE_BUNDLENAME, APP_NO_RESPONSE_ABILITY);
126     want.SetParam(UIEXTENSION_TYPE_KEY, UIEXTENSION_SYS_COMMON_UI);
127     want.SetParam(APP_FREEZE_PID, pid);
128     want.SetParam(START_BUNDLE_NAME, bundleName);
129 
130     auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy();
131     if (!sceneSessionManager) {
132         TAG_LOGE(AAFwkTag::ABILITYMGR, "sceneSessionManager is null proxy!");
133         return false;
134     }
135     auto ret = static_cast<int>(sceneSessionManager->GetFocusSessionToken(token));
136     if (ret != ERR_OK) {
137         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get focus session token err: %{public}d", ret);
138         return false;
139     }
140     want.SetParam(APP_FREEZE_TOKEN, token);
141     std::vector<sptr<Rosen::WindowVisibilityInfo>> infos;
142     ret = static_cast<int>(sceneSessionManager->GetVisibilityWindowInfo(infos));
143     if (ret != ERR_OK) {
144         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get visibility window info err: %{public}d", ret);
145         return false;
146     }
147 
148     int32_t posX = 0;
149     int32_t posY = 0;
150     int32_t width = 10;
151     int32_t height  = 10;
152     int32_t focusPid = -1;
153     for (const auto &info : infos) {
154         if (info != nullptr) {
155             if (info->IsFocused()) {
156                 posX = info->rect_.posX_;
157                 posY = info->rect_.posY_;
158                 width = info->rect_.width_;
159                 height = info->rect_.height_;
160                 focusPid = info->pid_;
161                 break;
162             }
163         }
164     }
165     if ((focusPid == -1) || (std::to_string(focusPid) != pid)) {
166         TAG_LOGE(AAFwkTag::ABILITYMGR, "fucused window pid is %{public}d, not freeze pid!", focusPid);
167         return false;
168     }
169     want.SetParam(FREEZE_WINDOW_POSX, std::to_string(posX));
170     want.SetParam(FREEZE_WINDOW_POSY, std::to_string(posY));
171     want.SetParam(FREEZE_WINDOW_WIDTH, std::to_string(width));
172     want.SetParam(FREEZE_WINDOW_HEIGHT, std::to_string(height));
173     return true;
174 }
175 
176 }  // namespace AppExecFwk
177 }  // namespace OHOS
178 #endif  // APP_NO_RESPONSE_DIALOG
179