• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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