1 /*
2 * Copyright (c) 2025 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 "pull_throw_listener.h"
17
18 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
19 #include "devicestatus_define.h"
20 #include "drag_manager.h"
21 #include "fi_log.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "PullThrowListener"
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace {
29 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
30 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
31 const std::string SETTING_VK_KEY = "virtualKeyBoardType";
32 constexpr int32_t DATA_SHARE_READY = 0;
33 constexpr int32_t DATA_SHARE_NOT_READY = 1055;
34 constexpr int32_t DECEM_BASE = 10;
35 } // namespace
36
PullThrowListener(DragManager * manager)37 PullThrowListener::PullThrowListener(DragManager* manager) : manager_(manager)
38 {
39 FI_HILOGI("PullThrowListener initialized with DragManager");
40 }
41
~PullThrowListener()42 PullThrowListener::~PullThrowListener() {}
43
RegisterFoldStatusListener()44 bool PullThrowListener::RegisterFoldStatusListener()
45 {
46 foldStatusListener_ = new (std::nothrow) FoldStatusListener(this);
47 if (foldStatusListener_ == nullptr) {
48 FI_HILOGE("Allocate FoldStatusListener failed");
49 return false;
50 }
51 auto ret = Rosen::DisplayManager::GetInstance().RegisterFoldStatusListener(foldStatusListener_);
52 if (ret != Rosen::DMError::DM_OK) {
53 FI_HILOGE("RegisterFoldStatusListener failed");
54 delete foldStatusListener_;
55 return false;
56 }
57 FI_HILOGI("RegisterFoldStatusListener success");
58 return true;
59 }
60
OnFoldStatusChanged(Rosen::FoldStatus foldStatus)61 void PullThrowListener::FoldStatusListener::OnFoldStatusChanged(Rosen::FoldStatus foldStatus)
62 {
63 CHKPV(listener_);
64 CHKPV(listener_->manager_);
65 FI_HILOGD("OnFoldStatusChanged foldStatus is %{public}d, throw state: %{public}d",
66 static_cast<int32_t>(foldStatus), listener_->manager_->throwState_);
67
68 if (foldStatus != Rosen::FoldStatus::HALF_FOLD && listener_->manager_->throwState_ != ThrowState::NOT_THROW) {
69 std::shared_ptr<MMI::PointerEvent> pointerEvent = listener_->manager_->currentPointerEvent_;
70 CHKPV(pointerEvent);
71 pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_PULL_CANCEL);
72 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
73 FI_HILOGI("OnFoldStatusChanged throw stop");
74 }
75 }
76
RegisterScreenMagneticStateListener()77 bool PullThrowListener::RegisterScreenMagneticStateListener()
78 {
79 screenMagneticStateListener_ = new (std::nothrow) ScreenMagneticStateListener(this);
80 if (screenMagneticStateListener_ == nullptr) {
81 FI_HILOGE("Allocate ScreenMagneticStateListener failed");
82 return false;
83 }
84 auto ret = Rosen::DisplayManager::GetInstance().RegisterScreenMagneticStateListener(screenMagneticStateListener_);
85 if (ret != Rosen::DMError::DM_OK) {
86 FI_HILOGE("RegisterScreenMagneticStateListener failed");
87 delete screenMagneticStateListener_;
88 return false;
89 }
90 FI_HILOGI("RegisterScreenMagneticStateListener success");
91
92 return true;
93 }
94
OnScreenMagneticStateChanged(bool isMagneticState)95 void PullThrowListener::ScreenMagneticStateListener::OnScreenMagneticStateChanged(bool isMagneticState)
96 {
97 CHKPV(listener_);
98 CHKPV(listener_->manager_);
99 FI_HILOGD("ScreenMagneticListener, isMagneticState:%{public}u", isMagneticState);
100 listener_->currentMagneticState_ = isMagneticState;
101 if (isMagneticState != false && listener_->manager_->throwState_ != ThrowState::NOT_THROW) {
102 std::shared_ptr<MMI::PointerEvent> pointerEvent = listener_->manager_->currentPointerEvent_;
103 CHKPV(pointerEvent);
104 pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_PULL_CANCEL);
105 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
106 FI_HILOGI("OnScreenMagneticStateChanged throw stop");
107 }
108 }
109
CreateDataShareHelper()110 std::shared_ptr<DataShare::DataShareHelper> PullThrowListener::CreateDataShareHelper()
111 {
112 if (remoteObj_ == nullptr) {
113 FI_HILOGD("remoteObj_ is nullptr");
114 return nullptr;
115 }
116 auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
117 if (ret == DATA_SHARE_READY) {
118 return helper;
119 } else if (ret == DATA_SHARE_NOT_READY) {
120 FI_HILOGE("Create data_share helper failed, uri proxy:%{public}s", SETTING_URI_PROXY.c_str());
121 return nullptr;
122 }
123 FI_HILOGD("Data_share create unknown");
124 return nullptr;
125 }
126
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)127 bool PullThrowListener::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
128 {
129 CHKPF(helper);
130 if (!helper->Release()) {
131 FI_HILOGE("Release helper fail");
132 return false;
133 }
134 return true;
135 }
136
GetIntValue(const std::string & key,int32_t & value)137 int32_t PullThrowListener::GetIntValue(const std::string &key, int32_t &value)
138 {
139 int64_t valueLong;
140 int32_t ret = GetLongValue(key, valueLong);
141 if (ret != ERR_OK) {
142 FI_HILOGE("GetIntValue fail");
143 return ret;
144 }
145 value = static_cast<int32_t>(valueLong);
146 return ERR_OK;
147 }
148
GetLongValue(const std::string & key,int64_t & value)149 int32_t PullThrowListener::GetLongValue(const std::string &key, int64_t &value)
150 {
151 std::string valueStr;
152 int32_t ret = GetStringValue(key, valueStr);
153 if (ret != ERR_OK) {
154 FI_HILOGE("GetLongValue fail");
155 return ret;
156 }
157 value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, DECEM_BASE));
158 return ERR_OK;
159 }
160
GetStringValue(const std::string & key,std::string & value)161 int32_t PullThrowListener::GetStringValue(const std::string &key, std::string &value)
162 {
163 FI_HILOGI("enter");
164 auto helper = CreateDataShareHelper();
165 std::vector<std::string> columns = {"VALUE"};
166 DataShare::DataSharePredicates predicates;
167 predicates.EqualTo("KEYWORD", key);
168 Uri uri((SETTING_URI_PROXY + "&key=" + key));
169 CHKPR(helper, RET_ERR);
170 auto resultSet = helper->Query(uri, predicates, columns);
171 ReleaseDataShareHelper(helper);
172 const int32_t index = 0;
173 CHKPR(resultSet, RET_ERR);
174 resultSet->GoToRow(index);
175 int32_t ret = resultSet->GetString(index, value);
176 if (ret != ERR_OK) {
177 FI_HILOGE("GetString failed, ret:%{public}d", ret);
178 return ret;
179 }
180 resultSet->Close();
181 return ERR_OK;
182 }
183
RegisterVKObserver(const sptr<VKObserver> & observer)184 bool PullThrowListener::RegisterVKObserver(const sptr<VKObserver> &observer)
185 {
186 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
187 remoteObj_ = sm->GetSystemAbility(MSDP_DEVICESTATUS_SERVICE_ID);
188 if (observer == nullptr) {
189 FI_HILOGD("observer is nullptr");
190 return false;
191 }
192 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
193 auto helper = CreateDataShareHelper();
194 if (helper == nullptr) {
195 IPCSkeleton::SetCallingIdentity(callingIdentity);
196 return false;
197 }
198 Uri uriFeedback((SETTING_URI_PROXY + "&key=" + SETTING_VK_KEY));
199 helper->RegisterObserver(uriFeedback, observer);
200 helper->NotifyChange(uriFeedback);
201
202 ReleaseDataShareHelper(helper);
203 IPCSkeleton::SetCallingIdentity(callingIdentity);
204 FI_HILOGI("Succeed to register observer of virtual keyboard");
205 return true;
206 }
207
OnChange()208 void PullThrowListener::VKObserver::OnChange()
209 {
210 if (update_ != nullptr) {
211 update_();
212 }
213 }
214
SetUpdateFunc(const UpdateFunc & func)215 void PullThrowListener::VKObserver::SetUpdateFunc(const UpdateFunc &func)
216 {
217 update_ = func;
218 }
219
CreateVKObserver(const VKObserver::UpdateFunc & func)220 sptr<PullThrowListener::VKObserver> PullThrowListener::CreateVKObserver(const VKObserver::UpdateFunc &func)
221 {
222 sptr<VKObserver> observer = new VKObserver();
223 if (observer == nullptr) {
224 FI_HILOGD("observer is null");
225 return observer;
226 }
227 observer->SetUpdateFunc(func);
228 return observer;
229 }
230
RegisterPullThrowListener()231 bool PullThrowListener::RegisterPullThrowListener()
232 {
233 if (!RegisterFoldStatusListener() || !RegisterScreenMagneticStateListener()) {
234 FI_HILOGD("unable to register FoldStatusListener or MagneticStateListener");
235 return false;
236 }
237 return true;
238 }
239
RegisterVKListener()240 bool PullThrowListener::RegisterVKListener()
241 {
242 const VKObserver::UpdateFunc updateFunc = [&]() {
243 GetIntValue(SETTING_VK_KEY, obstatusVk_);
244 if (obstatusVk_ == 1) {
245 FI_HILOGI("VK UpdateFunc Thorw cancel; obstatusVk_: %{public}d", obstatusVk_);
246 CHKPV(manager_);
247 manager_->OnDragCancel(manager_->currentPointerEvent_);
248 } else {
249 FI_HILOGD("Virtual keyboard obstatusVk_: %{public}d", obstatusVk_);
250 }
251 };
252 auto VKobserver_ = CreateVKObserver(updateFunc);
253 if (!RegisterVKObserver(VKobserver_)) {
254 FI_HILOGD("unable to register VK listener");
255 return false;
256 }
257 return true;
258 }
259
ValidateThrowConditions()260 bool PullThrowListener::ValidateThrowConditions()
261 {
262 oldFoldStatus_ = Rosen::DisplayManager::GetInstance().GetFoldStatus();
263 FI_HILOGI("Listener params: VK Status=%{public}d, MK Status=%{public}d, Fold Status=%{public}u",
264 obstatusVk_, currentMagneticState_, oldFoldStatus_);
265 return !(obstatusVk_ == 1 || oldFoldStatus_ != Rosen::FoldStatus::HALF_FOLD || currentMagneticState_);
266 }
267 #endif // OHOS_BUILD_ENABLE_ARKUI_X
268
269 } // namespace DeviceStatus
270 } // namespace Msdp
271 } // namespace OHOS
272