• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "shutdown_dialog.h"
17 
18 #include <atomic>
19 #include <memory>
20 #include <set>
21 
22 #include <ability_manager_client.h>
23 #include <input_manager.h>
24 #include <key_event.h>
25 #include <key_option.h>
26 #include <message_parcel.h>
27 
28 #include "ffrt_utils.h"
29 #include "power_log.h"
30 #include "power_mgr_service.h"
31 
32 using namespace OHOS::MMI;
33 using namespace OHOS::AAFwk;
34 
35 namespace OHOS {
36 namespace PowerMgr {
37 namespace {
38 static constexpr int32_t LONG_PRESS_DELAY_MS = 3000;
39 static constexpr int32_t INVALID_USERID = -1;
40 static constexpr int32_t MESSAGE_PARCEL_KEY_SIZE = 3;
41 static constexpr int32_t INIT_LONG_PRESS_RETRY = 3;
42 static constexpr uint32_t RETRY_TIME = 1000;
43 std::atomic_bool g_isDialogShow = false;
44 std::atomic_bool g_longPressShow = false;
45 int32_t g_retryCount = 1;
46 FFRTQueue g_queue("shutdown_dialog");
47 sptr<IRemoteObject> g_remoteObject = nullptr;
48 } // namespace
ShutdownDialog()49 ShutdownDialog::ShutdownDialog() : dialogConnectionCallback_(new DialogAbilityConnection()) {}
50 
~ShutdownDialog()51 ShutdownDialog::~ShutdownDialog()
52 {
53     dialogConnectionCallback_ = nullptr;
54 }
55 
KeyMonitorInit()56 void ShutdownDialog::KeyMonitorInit()
57 {
58     POWER_HILOGD(FEATURE_SHUTDOWN, "Initialize the long press powerkey");
59     std::shared_ptr<KeyOption> keyOption = std::make_shared<KeyOption>();
60     std::set<int32_t> preKeys;
61 
62     keyOption->SetPreKeys(preKeys);
63     keyOption->SetFinalKey(KeyEvent::KEYCODE_POWER);
64     keyOption->SetFinalKeyDown(true);
65     keyOption->SetFinalKeyDownDuration(LONG_PRESS_DELAY_MS);
66     longPressId_ =
67         InputManager::GetInstance()->SubscribeKeyEvent(keyOption, [this](std::shared_ptr<KeyEvent> keyEvent) {
68             POWER_HILOGI(FEATURE_SHUTDOWN, "Receive long press powerkey");
69             ConnectSystemUi();
70         });
71     if (longPressId_ < ERR_OK) {
72         if (g_retryCount <= INIT_LONG_PRESS_RETRY) {
73             POWER_HILOGI(FEATURE_SHUTDOWN, "SubscribeKey long press failed errcode = %{public}d, Try again in 1 second",
74                 longPressId_);
75             FFRTTask task = [this] {
76                 KeyMonitorInit();
77             };
78             FFRTUtils::SubmitDelayTask(task, RETRY_TIME, g_queue);
79             g_retryCount++;
80         }
81         return;
82     }
83     POWER_HILOGI(FEATURE_SHUTDOWN, "SubscribeKey long press success");
84 }
85 
KeyMonitorCancel()86 void ShutdownDialog::KeyMonitorCancel()
87 {
88     InputManager* inputManager = InputManager::GetInstance();
89     if (inputManager == nullptr) {
90         POWER_HILOGW(FEATURE_SHUTDOWN, "InputManager is null");
91         return;
92     }
93     if (longPressId_ >= ERR_OK) {
94         inputManager->UnsubscribeKeyEvent(longPressId_);
95     }
96     longPressId_ = 0;
97 }
98 
ConnectSystemUi()99 bool ShutdownDialog::ConnectSystemUi()
100 {
101     if (g_isDialogShow) {
102         AppExecFwk::ElementName element;
103         dialogConnectionCallback_->OnAbilityConnectDone(element, g_remoteObject, INVALID_USERID);
104         POWER_HILOGW(FEATURE_SHUTDOWN, "power dialog has been show");
105         return true;
106     }
107     auto ams = AbilityManagerClient::GetInstance();
108     if (ams == nullptr) {
109         POWER_HILOGW(FEATURE_SHUTDOWN, "AbilityManagerClient is nullptr");
110         return false;
111     }
112 
113     Want want;
114     want.SetElementName("com.ohos.systemui", "com.ohos.systemui.dialog");
115     ErrCode result = ams->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
116     if (result != ERR_OK) {
117         POWER_HILOGW(FEATURE_SHUTDOWN, "ConnectAbility systemui dialog failed, result = %{public}d", result);
118         return false;
119     }
120     POWER_HILOGI(FEATURE_SHUTDOWN, "ConnectAbility systemui dialog success.");
121     return true;
122 }
123 
IsLongPress() const124 bool ShutdownDialog::IsLongPress() const
125 {
126     return g_longPressShow;
127 }
128 
ResetLongPressFlag()129 void ShutdownDialog::ResetLongPressFlag()
130 {
131     g_longPressShow = false;
132 }
133 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)134 void ShutdownDialog::DialogAbilityConnection::OnAbilityConnectDone(
135     const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
136 {
137     POWER_HILOGD(FEATURE_SHUTDOWN, "OnAbilityConnectDone");
138     std::lock_guard lock(mutex_);
139     if (remoteObject == nullptr) {
140         POWER_HILOGW(FEATURE_SHUTDOWN, "remoteObject is nullptr");
141         return;
142     }
143     if (g_remoteObject == nullptr) {
144         g_remoteObject = remoteObject;
145     }
146     FFRTUtils::SubmitTask([remoteObject] {
147         MessageParcel data;
148         MessageParcel reply;
149         MessageOption option;
150         data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE);
151         data.WriteString16(u"bundleName");
152         data.WriteString16(u"com.ohos.powerdialog");
153         data.WriteString16(u"abilityName");
154         data.WriteString16(u"PowerUiExtensionAbility");
155         data.WriteString16(u"parameters");
156         // sysDialogZOrder = 2 displayed on the lock screen
157         data.WriteString16(u"{\"ability.want.params.uiExtensionType\":\"sysDialog/power\",\"sysDialogZOrder\":2}");
158         POWER_HILOGD(FEATURE_SHUTDOWN, "show power dialog is begin");
159         const uint32_t cmdCode = 1;
160         int32_t ret = remoteObject->SendRequest(cmdCode, data, reply, option);
161         if (ret != ERR_OK) {
162             POWER_HILOGW(FEATURE_SHUTDOWN, "show power dialog is failed: %{public}d", ret);
163             return;
164         }
165         g_isDialogShow = true;
166         g_longPressShow = true;
167         POWER_HILOGI(FEATURE_SHUTDOWN, "show power dialog is success");
168         auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
169         if (pms == nullptr) {
170             return;
171         }
172         pms->RefreshActivity(
173             static_cast<int64_t>(time(nullptr)), UserActivityType::USER_ACTIVITY_TYPE_ATTENTION, false);
174     });
175 }
176 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)177 void ShutdownDialog::DialogAbilityConnection::OnAbilityDisconnectDone(
178     const AppExecFwk::ElementName& element, int resultCode)
179 {
180     POWER_HILOGD(FEATURE_SHUTDOWN, "OnAbilityDisconnectDone");
181     std::lock_guard lock(mutex_);
182     g_isDialogShow = false;
183     g_longPressShow = false;
184     g_remoteObject = nullptr;
185 }
186 } // namespace PowerMgr
187 } // namespace OHOS
188