1 /*
2 * Copyright (c) 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 "display_change_event_listener.h"
17
18 #include "devicestatus_define.h"
19 #include "product_name_definition_parser.h"
20 #include "parameters.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "DisplayChangeEventListener"
24
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace {
29 constexpr int32_t INDEX_FOLDED { 0 };
30 constexpr int32_t INDEX_EXPAND { 1 };
31 constexpr size_t MAX_INDEX_LENGTH { 2 };
32 const std::string SCREEN_ROTATION { "1" };
33 const std::string SYS_PRODUCT_TYPE = OHOS::system::GetParameter("const.build.product", "HYM");
34 } // namespace
35
DisplayChangeEventListener(IContext * context)36 DisplayChangeEventListener::DisplayChangeEventListener(IContext *context)
37 : context_(context)
38 {
39 }
40
OnCreate(Rosen::DisplayId displayId)41 void DisplayChangeEventListener::OnCreate(Rosen::DisplayId displayId)
42 {
43 FI_HILOGI("display:%{public}" PRIu64"", displayId);
44 sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
45 if (display == nullptr) {
46 FI_HILOGW("Get display info failed, display:%{public}" PRIu64"", displayId);
47 display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
48 if (display == nullptr) {
49 FI_HILOGE("Get display info failed, display is nullptr");
50 return;
51 }
52 }
53 Rosen::Rotation rotation = display->GetRotation();
54 CHKPV(context_);
55 context_->GetDragManager().SetRotation(displayId, rotation);
56 }
57
OnDestroy(Rosen::DisplayId displayId)58 void DisplayChangeEventListener::OnDestroy(Rosen::DisplayId displayId)
59 {
60 FI_HILOGI("display:%{public}" PRIu64"", displayId);
61 CHKPV(context_);
62 context_->GetDragManager().RemoveDisplayIdFromMap(displayId);
63 }
64
OnChange(Rosen::DisplayId displayId)65 void DisplayChangeEventListener::OnChange(Rosen::DisplayId displayId)
66 {
67 CHKPV(context_);
68 Rosen::Rotation lastRotation = context_->GetDragManager().GetRotation(displayId);
69 if (Rosen::DisplayManager::GetInstance().IsFoldable()) {
70 bool isScreenRotation = false;
71 std::vector<std::string> foldRotatePolicys;
72 GetRotatePolicy(isScreenRotation, foldRotatePolicys);
73 if (foldRotatePolicys.size() < MAX_INDEX_LENGTH) {
74 FI_HILOGE("foldRotatePolicys is invalid");
75 return;
76 }
77 Rosen::FoldStatus foldStatus = Rosen::DisplayManager::GetInstance().GetFoldStatus();
78 bool isExpand = (foldStatus == Rosen::FoldStatus::EXPAND || foldStatus == Rosen::FoldStatus::HALF_FOLD);
79 bool isFold = (foldStatus == Rosen::FoldStatus::FOLDED);
80 if (IsSecondaryDevice()) {
81 isExpand = (foldStatus == Rosen::FoldStatus::EXPAND || foldStatus == Rosen::FoldStatus::HALF_FOLD ||
82 foldStatus == Rosen::FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND ||
83 foldStatus == Rosen::FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_HALF_FOLDED ||
84 foldStatus == Rosen::FoldStatus::FOLD_STATE_HALF_FOLDED_WITH_SECOND_EXPAND ||
85 foldStatus == Rosen::FoldStatus::FOLD_STATE_HALF_FOLDED_WITH_SECOND_HALF_FOLDED);
86 isFold = (foldStatus == Rosen::FoldStatus::FOLDED ||
87 foldStatus == Rosen::FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND ||
88 foldStatus == Rosen::FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_HALF_FOLDED);
89 }
90 if ((isExpand && (foldRotatePolicys[INDEX_EXPAND] == SCREEN_ROTATION)) ||
91 (isFold && (foldRotatePolicys[INDEX_FOLDED] == SCREEN_ROTATION))) {
92 if (lastRotation == Rosen::Rotation::ROTATION_0) {
93 FI_HILOGD("Last rotation is zero");
94 return;
95 }
96 CHKPV(context_);
97 context_->GetDragManager().SetRotation(displayId, Rosen::Rotation::ROTATION_0);
98 int32_t ret = context_->GetDelegateTasks().PostAsyncTask([this, displayId] {
99 CHKPR(this->context_, RET_ERR);
100 return this->context_->GetDragManager().RotateDragWindow(displayId, Rosen::Rotation::ROTATION_0);
101 });
102 if (ret != RET_OK) {
103 FI_HILOGE("Post async task failed");
104 }
105 return;
106 }
107 }
108 sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
109 if (display == nullptr) {
110 FI_HILOGW("Get display info failed, display:%{public}" PRIu64"", displayId);
111 display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
112 if (display == nullptr) {
113 FI_HILOGE("Get display info failed, display is nullptr");
114 return;
115 }
116 }
117 Rosen::Rotation currentRotation = display->GetRotation();
118 if (!IsRotation(displayId, currentRotation)) {
119 return;
120 }
121
122 bool isScreenRotation = false;
123 std::vector<std::string> foldRotatePolicys;
124 GetRotatePolicy(isScreenRotation, foldRotatePolicys);
125 FI_HILOGI("Current rotation:%{public}d, lastRotation:%{public}d",
126 static_cast<int32_t>(currentRotation), static_cast<int32_t>(lastRotation));
127 if (isScreenRotation) {
128 ScreenRotate(currentRotation, lastRotation);
129 return;
130 }
131 RotateDragWindow(displayId, currentRotation);
132 }
133
RotateDragWindow(Rosen::DisplayId displayId,Rosen::Rotation rotation)134 void DisplayChangeEventListener::RotateDragWindow(Rosen::DisplayId displayId, Rosen::Rotation rotation)
135 {
136 FI_HILOGI("Rotation:%{public}d", static_cast<int32_t>(rotation));
137 CHKPV(context_);
138 int32_t ret = context_->GetDelegateTasks().PostAsyncTask([this, displayId, rotation] {
139 CHKPR(this->context_, RET_ERR);
140 return this->context_->GetDragManager().RotateDragWindow(displayId, rotation);
141 });
142 if (ret != RET_OK) {
143 FI_HILOGE("Post async task failed");
144 }
145 }
146
IsRotation(Rosen::DisplayId displayId,Rosen::Rotation currentRotation)147 bool DisplayChangeEventListener::IsRotation(Rosen::DisplayId displayId, Rosen::Rotation currentRotation)
148 {
149 CHKPF(context_);
150 Rosen::Rotation lastRotation = context_->GetDragManager().GetRotation(displayId);
151 if (lastRotation != currentRotation) {
152 FI_HILOGI("Need to rotate window for display id:%{public}d angle from %{public}d to %{public}d",
153 static_cast<int32_t>(displayId), static_cast<int32_t>(lastRotation), static_cast<int32_t>(currentRotation));
154 return true;
155 }
156 return false;
157 }
158
ScreenRotate(Rosen::Rotation rotation,Rosen::Rotation lastRotation)159 void DisplayChangeEventListener::ScreenRotate(Rosen::Rotation rotation, Rosen::Rotation lastRotation)
160 {
161 FI_HILOGI("Rotation:%{public}d, lastRotation:%{public}d",
162 static_cast<int32_t>(rotation), static_cast<int32_t>(lastRotation));
163 CHKPV(context_);
164 int32_t ret = context_->GetDelegateTasks().PostAsyncTask([this, rotation, lastRotation] {
165 CHKPR(this->context_, RET_ERR);
166 return this->context_->GetDragManager().ScreenRotate(rotation, lastRotation);
167 });
168 if (ret != RET_OK) {
169 FI_HILOGE("Post async task failed");
170 }
171 }
172
DisplayAbilityStatusChange(IContext * context)173 DisplayAbilityStatusChange::DisplayAbilityStatusChange(IContext *context)
174 : context_(context)
175 {}
176
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)177 void DisplayAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
178 {
179 FI_HILOGI("systemAbilityId:%{public}d", systemAbilityId);
180 if (systemAbilityId != DISPLAY_MANAGER_SERVICE_SA_ID) {
181 FI_HILOGE("systemAbilityId is not DISPLAY_MANAGER_SERVICE_SA_ID");
182 return;
183 }
184 CHKPV(context_);
185 displayChangeEventListener_ = sptr<DisplayChangeEventListener>::MakeSptr(context_);
186 CHKPV(displayChangeEventListener_);
187 Rosen::DisplayManager::GetInstance().RegisterDisplayListener(displayChangeEventListener_);
188 #ifdef OHOS_ENABLE_PULLTHROW
189 isFoldPC_.store(SYS_PRODUCT_TYPE == PRODUCT_NAME_DEFINITION_PARSER.GetProductName("DEVICE_TYPE_FOLD_PC"));
190 if (isFoldPC_) {
191 FI_HILOGI("device foldPC check ok");
192 if (!context_->GetDragManager().RegisterPullThrowListener()) {
193 FI_HILOGE("RegisterPullThrowListener fail");
194 return;
195 }
196 }
197 #endif // OHOS_ENABLE_PULLTHROW
198 }
199
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)200 void DisplayAbilityStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
201 {
202 FI_HILOGI("systemAbilityId:%{public}d", systemAbilityId);
203 }
204
AppStateObserverStatusChange(IContext * context)205 AppStateObserverStatusChange::AppStateObserverStatusChange(IContext *context)
206 : context_(context)
207 {}
208
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)209 void AppStateObserverStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
210 {
211 FI_HILOGI("systemAbilityId:%{public}d", systemAbilityId);
212 if (systemAbilityId != APP_MGR_SERVICE_ID) {
213 FI_HILOGE("systemAbilityId is not APP_MGR_SERVICE_ID");
214 return;
215 }
216 CHKPV(context_);
217 context_->GetSocketSessionManager().RegisterApplicationState();
218 }
219
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)220 void AppStateObserverStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
221 {
222 FI_HILOGI("systemAbilityId:%{public}d", systemAbilityId);
223 }
224 } // namespace DeviceStatus
225 } // namespace Msdp
226 } // namespace OHOS