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 = 3;
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 int32_t ret = remoteObject->SendRequest(AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
112 if (ret != ERR_OK) {
113 TLOGE(WmsLogTag::WMS_UIEXT, "show dialog failed");
114 return false;
115 }
116 return true;
117 }
118
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)119 void ModalSystemUiExtension::DialogAbilityConnection::OnAbilityConnectDone(
120 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
121 {
122 TLOGI(WmsLogTag::WMS_UIEXT, "called");
123 if (remoteObject == nullptr) {
124 TLOGE(WmsLogTag::WMS_UIEXT, "remoteObject is nullptr");
125 return;
126 }
127 if (!SendWant(remoteObject)) {
128 return;
129 }
130 auto task = [weakThis = wptr(this)] {
131 auto connection = weakThis.promote();
132 if (!connection) {
133 TLOGI(WmsLogTag::WMS_UIEXT, "session is null or already disconnected");
134 return;
135 }
136 auto abilityManagerClient = AbilityManagerClient::GetInstance();
137 if (abilityManagerClient == nullptr) {
138 TLOGE(WmsLogTag::WMS_UIEXT, "AbilityManagerClient is nullptr");
139 return;
140 }
141 auto result = abilityManagerClient->DisconnectAbility(connection);
142 if (result != ERR_OK) {
143 TLOGE(WmsLogTag::WMS_UIEXT, "DisconnectAbility failed, result = %{public}d", result);
144 } else {
145 TLOGI(WmsLogTag::WMS_UIEXT, "DisconnectAbility success");
146 }
147 };
148 ffrt::task_handle handle = ffrt::submit_h(std::move(task),
149 ffrt::task_attr().delay(DISCONNECT_ABILITY_DELAY_TIME_MICROSECONDS));
150 if (handle == nullptr) {
151 TLOGE(WmsLogTag::WMS_UIEXT, "Failed to post task");
152 }
153 }
154
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)155 void ModalSystemUiExtension::DialogAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element,
156 int resultCode)
157 {
158 TLOGI(WmsLogTag::WMS_UIEXT, "called");
159 }
160 } // namespace Rosen
161 } // namespace OHOS