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 "authorization_dialog.h"
17 
18 #include <atomic>
19 
20 #include "ability_manager_client.h"
21 #include "message_parcel.h"
22 
23 #include "mmi_log.h"
24 
25 #undef MMI_LOG_DOMAIN
26 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
27 #undef MMI_LOG_TAG
28 #define MMI_LOG_TAG "AuthorizationDialog"
29 
30 namespace OHOS {
31 namespace MMI {
32 namespace {
33 constexpr int32_t INVALID_USERID { -1 };
34 constexpr int32_t MESSAGE_PARCEL_KEY_SIZE { 3 };
35 }
36 
37 std::string AuthorizationDialog::bundleName_ = "com.ohos.powerdialog";
38 std::string AuthorizationDialog::abilityName_ = "PowerUiExtensionAbility";
39 std::string AuthorizationDialog::uiExtensionType_ = "sysDialog/power";
40 
AuthorizationDialog()41 AuthorizationDialog::AuthorizationDialog() : dialogConnectionCallback_(new DialogAbilityConnection()) {}
42 
~AuthorizationDialog()43 AuthorizationDialog::~AuthorizationDialog()
44 {
45     CALL_DEBUG_ENTER;
46     CloseDialog();
47     dialogConnectionCallback_ = nullptr;
48 }
49 
ConnectSystemUi()50 bool AuthorizationDialog::ConnectSystemUi()
51 {
52     CALL_DEBUG_ENTER;
53     CHKPR(dialogConnectionCallback_, false);
54     if (dialogConnectionCallback_->DialogIsOpen()) {
55         MMI_HILOGW("Power dialog has been show");
56         return true;
57     }
58 
59     if (dialogConnectionCallback_->IsConnected()) {
60         MMI_HILOGW("Dialog reopens");
61         dialogConnectionCallback_->OpenDialog();
62         return true;
63     }
64     MMI_HILOGI("ConnectAbility systemui beigin");
65     auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance();
66     CHKPF(abilityMgr);
67 
68     AAFwk::Want want;
69     want.SetElementName("com.ohos.sceneboard", "com.ohos.sceneboard.systemdialog");
70     ErrCode result = abilityMgr->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
71     if (result != ERR_OK) {
72         MMI_HILOGW("ConnectAbility systemui dialog failed, result:%{public}d", result);
73         return false;
74     }
75     MMI_HILOGI("ConnectAbility systemui dialog success");
76     return true;
77 }
78 
CloseDialog()79 void AuthorizationDialog::CloseDialog()
80 {
81     CALL_DEBUG_ENTER;
82     dialogConnectionCallback_->CloseDialog();
83 }
84 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)85 void AuthorizationDialog::DialogAbilityConnection::OnAbilityConnectDone(
86     const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
87 {
88     CALL_DEBUG_ENTER;
89     std::lock_guard lock(mutex_);
90     CHKPV(remoteObject);
91     if (remoteObject_ == nullptr) {
92         remoteObject_ = remoteObject;
93     }
94     ffrt::submit([&] {
95         this->OpenDialog();
96     });
97 }
98 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)99 void AuthorizationDialog::DialogAbilityConnection::OnAbilityDisconnectDone(
100     const AppExecFwk::ElementName& element, int resultCode)
101 {
102     CALL_DEBUG_ENTER;
103     std::lock_guard lock(mutex_);
104     remoteObject_ = nullptr;
105     // disconnted window must be shutdown
106     isDialogShow_ = false;
107 }
108 
CloseDialog()109 void AuthorizationDialog::DialogAbilityConnection::CloseDialog()
110 {
111     CALL_DEBUG_ENTER;
112     std::lock_guard lock(mutex_);
113     CHKPV(remoteObject_);
114     if (!isDialogShow_) {
115         MMI_HILOGI("Has closed!");
116         return;
117     }
118     MessageParcel data;
119     MessageParcel reply;
120     MessageOption option;
121     const uint32_t cmdCode = 3;
122     int32_t ret = remoteObject_->SendRequest(cmdCode, data, reply, option);
123     int32_t replyCode = -1;
124     bool success = false;
125     if (ret == ERR_OK) {
126         success = reply.ReadInt32(replyCode);
127     }
128     isDialogShow_ = false;
129     MMI_HILOGI("CloseDialog: ret=%d, %d, %d", ret, success, replyCode);
130 }
131 
OpenDialog()132 void AuthorizationDialog::DialogAbilityConnection::OpenDialog()
133 {
134     CALL_DEBUG_ENTER;
135     MessageParcel data;
136     MessageParcel reply;
137     MessageOption option;
138     data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE);
139     data.WriteString16(u"bundleName");
140     data.WriteString16(Str8ToStr16(AuthorizationDialog::GetBundleName()));
141     data.WriteString16(u"abilityName");
142     data.WriteString16(Str8ToStr16(AuthorizationDialog::GetAbilityName()));
143     data.WriteString16(u"parameters");
144     std::string midStr = "\"";
145     std::string paramStr = "{\"ability.want.params.uiExtensionType\":"+ midStr +
146         AuthorizationDialog::GetUiExtensionType() + midStr + ",\"sysDialogZOrder\":2,\"isInputDlg\":true}";
147     data.WriteString16(Str8ToStr16(paramStr));
148     MMI_HILOGI("Show power dialog is begin");
149     const uint32_t cmdCode = 1;
150     std::lock_guard lock(mutex_);
151     CHKPV(remoteObject_);
152     int32_t ret = remoteObject_->SendRequest(cmdCode, data, reply, option);
153     if (ret != ERR_OK) {
154         MMI_HILOGW("Show power dialog is failed:%{public}d", ret);
155         return;
156     }
157     isDialogShow_ = true;
158     MMI_HILOGI("Show power dialog is success");
159 }
160 
DialogIsOpen()161 bool AuthorizationDialog::DialogAbilityConnection::DialogIsOpen()
162 {
163     CALL_DEBUG_ENTER;
164     std::lock_guard lock(mutex_);
165     return isDialogShow_;
166 }
167 
IsConnected()168 bool AuthorizationDialog::DialogAbilityConnection::IsConnected()
169 {
170     std::lock_guard lock(mutex_);
171     if (remoteObject_ != nullptr) {
172         return true;
173     }
174     return false;
175 }
176 } // namespace MMI
177 } // namespace OHOS