1 /*
2 * Copyright (c) 2023-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 "modal_system_ui_extension.h"
17
18 #include <memory>
19
20 #include <ability_manager_client.h>
21 #include <ffrt.h>
22 #include <iremote_object.h>
23 #include <message_parcel.h>
24
25 #include "window_manager_hilog.h"
26
27 using namespace OHOS::AAFwk;
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32 constexpr int32_t INVALID_USERID = -1;
33 constexpr int32_t MESSAGE_PARCEL_KEY_SIZE = 5;
34 constexpr int32_t VALUE_TYPE_STRING = 9;
35 constexpr uint64_t DISCONNECT_ABILITY_DELAY_TIME_MICROSECONDS = 5000000;
36 } // namespace
37
ModalSystemUiExtension()38 ModalSystemUiExtension::ModalSystemUiExtension() {}
39
~ModalSystemUiExtension()40 ModalSystemUiExtension::~ModalSystemUiExtension()
41 {
42 dialogConnectionCallback_ = nullptr;
43 }
44
CreateModalUIExtension(const AAFwk::Want & want)45 bool ModalSystemUiExtension::CreateModalUIExtension(const AAFwk::Want& want)
46 {
47 auto abilityManagerClient = AbilityManagerClient::GetInstance();
48 if (abilityManagerClient == nullptr) {
49 TLOGE(WmsLogTag::WMS_UIEXT, "AbilityManagerClient is nullptr");
50 return false;
51 }
52
53 AAFwk::Want systemUIWant;
54 systemUIWant.SetElementName("com.ohos.sceneboard", "com.ohos.sceneboard.systemdialog");
55 dialogConnectionCallback_ = sptr<DialogAbilityConnection>::MakeSptr(want);
56 auto result = abilityManagerClient->ConnectAbility(systemUIWant, dialogConnectionCallback_, INVALID_USERID);
57 if (result != ERR_OK) {
58 TLOGE(WmsLogTag::WMS_UIEXT, "ConnectAbility failed, result=%{public}d", result);
59 return false;
60 }
61 TLOGI(WmsLogTag::WMS_UIEXT, "ConnectAbility success");
62 return true;
63 }
64
ToString(const AAFwk::WantParams & wantParams)65 std::string ModalSystemUiExtension::ToString(const AAFwk::WantParams& wantParams)
66 {
67 std::string result;
68 if (wantParams.Size() != 0) {
69 result += "{";
70 for (auto it : wantParams.GetParams()) {
71 int typeId = AAFwk::WantParams::GetDataType(it.second);
72 result += "\"" + it.first + "\":";
73 if (typeId == VALUE_TYPE_STRING && AAFwk::WantParams::GetStringByType(it.second, typeId)[0] != '{') {
74 result += "\"" + AAFwk::WantParams::GetStringByType(it.second, typeId) + "\"";
75 } else {
76 result += AAFwk::WantParams::GetStringByType(it.second, typeId);
77 }
78 if (it != *wantParams.GetParams().rbegin()) {
79 result += ",";
80 }
81 }
82 result += "}";
83 } else {
84 result += "{}";
85 }
86 return result;
87 }
88
SendWant(const sptr<IRemoteObject> & remoteObject)89 bool ModalSystemUiExtension::DialogAbilityConnection::SendWant(const sptr<IRemoteObject>& remoteObject)
90 {
91 MessageParcel data;
92 MessageParcel reply;
93 MessageOption option(MessageOption::TF_ASYNC);
94 if (!data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE)) {
95 TLOGE(WmsLogTag::WMS_UIEXT, "write message parcel key size failed");
96 return false;
97 }
98 if (!data.WriteString16(u"bundleName") || !data.WriteString16(Str8ToStr16(want_.GetElement().GetBundleName()))) {
99 TLOGE(WmsLogTag::WMS_UIEXT, "write bundleName failed");
100 return false;
101 }
102 if (!data.WriteString16(u"abilityName") || !data.WriteString16(Str8ToStr16(want_.GetElement().GetAbilityName()))) {
103 TLOGE(WmsLogTag::WMS_UIEXT, "write abilityName failed");
104 return false;
105 }
106 if (!data.WriteString16(u"parameters") ||
107 !data.WriteString16(Str8ToStr16(ModalSystemUiExtension::ToString(want_.GetParams())))) {
108 TLOGE(WmsLogTag::WMS_UIEXT, "write parameters failed");
109 return false;
110 }
111 if (!data.WriteString16(u"uri") || !data.WriteString16(Str8ToStr16(want_.GetUri().ToString()))) {
112 TLOGE(WmsLogTag::WMS_UIEXT, "write uri failed");
113 return false;
114 }
115 if (!data.WriteString16(u"flags") || !data.WriteUint32(want_.GetFlags())) {
116 TLOGE(WmsLogTag::WMS_UIEXT, "write flags failed");
117 return false;
118 }
119 int32_t ret = remoteObject->SendRequest(AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
120 if (ret != ERR_OK) {
121 TLOGE(WmsLogTag::WMS_UIEXT, "show dialog failed");
122 return false;
123 }
124 return true;
125 }
126
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)127 void ModalSystemUiExtension::DialogAbilityConnection::OnAbilityConnectDone(
128 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
129 {
130 TLOGI(WmsLogTag::WMS_UIEXT, "called");
131 if (remoteObject == nullptr) {
132 TLOGE(WmsLogTag::WMS_UIEXT, "remoteObject is nullptr");
133 return;
134 }
135 if (!SendWant(remoteObject)) {
136 return;
137 }
138 auto task = [weakThis = wptr(this)] {
139 auto connection = weakThis.promote();
140 if (!connection) {
141 TLOGI(WmsLogTag::WMS_UIEXT, "session is null or already disconnected");
142 return;
143 }
144 auto abilityManagerClient = AbilityManagerClient::GetInstance();
145 if (abilityManagerClient == nullptr) {
146 TLOGE(WmsLogTag::WMS_UIEXT, "AbilityManagerClient is nullptr");
147 return;
148 }
149 auto result = abilityManagerClient->DisconnectAbility(connection);
150 if (result != ERR_OK) {
151 TLOGE(WmsLogTag::WMS_UIEXT, "DisconnectAbility failed, result=%{public}d", result);
152 } else {
153 TLOGI(WmsLogTag::WMS_UIEXT, "DisconnectAbility success");
154 }
155 };
156 ffrt::task_handle handle = ffrt::submit_h(std::move(task),
157 ffrt::task_attr().delay(DISCONNECT_ABILITY_DELAY_TIME_MICROSECONDS));
158 if (handle == nullptr) {
159 TLOGE(WmsLogTag::WMS_UIEXT, "Failed to post task");
160 }
161 }
162
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)163 void ModalSystemUiExtension::DialogAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element,
164 int resultCode)
165 {
166 TLOGI(WmsLogTag::WMS_UIEXT, "called");
167 }
168 } // namespace Rosen
169 } // namespace OHOS