• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #include "tui_event.h"
14 #include <cctype>
15 #include <cstdint>
16 #include <cstring>
17 #include <ctime>
18 #include <cstdio>
19 #include <memory>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <securec.h>
23 #include <securectype.h>
24 #include <sys/ioctl.h>
25 
26 #include "tee_log.h"
27 #include "tc_ns_client.h"
28 #include "power_mgr_client.h"
29 #include "display_info.h"
30 #include "cutout_info.h"
31 #include "call_manager_client.h"
32 #include "system_ability_definition.h"
33 #include "iservice_registry.h"
34 #include "tee_file.h"
35 #ifdef SCENE_BOARD_ENABLE
36 #include "display_manager_lite.h"
37 #include "display_lite.h"
38 #else
39 #include "display_manager.h"
40 #include "display.h"
41 #endif
42 
43 #ifdef LOG_TAG
44 #undef LOG_TAG
45 #endif
46 #define LOG_TAG "tee_tui_daemon"
47 
48 using namespace std;
49 using namespace OHOS::PowerMgr;
50 using namespace OHOS::Rosen;
51 using namespace OHOS::Telephony;
52 
53 TUIEvent *TUIEvent::tuiInstance = nullptr;
54 
55 static const uint32_t NOTCH_SIZE_MAX  = 200;
56 static const double INCH_CM_FACTOR    = 2.54;
57 static const uint32_t TUI_POLL_CANCEL = 7;
58 static const uint32_t TUI_POLL_NOTCH  = 24;
59 static const uint32_t TUI_POLL_FOLD   = 26;
60 static const uint32_t TUI_NEED_ROTATE = 256;
61 
62 static const uint8_t TTF_HASH_SIZE   = 32;
63 static const uint8_t TTF_STRING_SIZE = 64;
64 static const uint8_t HEX_BASE        = 16;
65 static const uint8_t ASCII_DIGIT_GAP = 10;
66 static uint8_t g_ttfHash[TTF_HASH_SIZE];
67 
68 static char g_hashVal[TTF_STRING_SIZE + 1] = {0};
69 static uint32_t g_hashLen = 0;
70 static bool g_tuiSendHashSuccess = false;
71 static bool g_tuiDisplayListenerRegisted = false;
72 static bool g_tuiCallBackRegisted = false;
73 static const int32_t RETRY_TIMES = 20;
74 static const uint32_t RETRY_SLEEP_TIME = 2;
75 static std::unique_ptr<TUICallManagerCallback> mTUITelephonyCallBack_ = nullptr;
76 static std::shared_ptr<OHOS::Telephony::CallManagerClient> callManagerClientPtr = nullptr;
77 
TUISaveTTFHash(void)78 static void TUISaveTTFHash(void)
79 {
80 #ifndef FONT_HASH_VAL
81     tlogi("tui font hash not defined\n");
82 #else
83     const char *hashStr = FONT_HASH_VAL;
84     if (hashStr == NULL) {
85         tloge("get hashstr error\n");
86         return;
87     }
88 
89     g_hashLen = (uint32_t)strlen(hashStr);
90     if (g_hashLen != TTF_STRING_SIZE) {
91         tloge("ttf hash invalid\n");
92         g_hashLen = 0;
93         return;
94     }
95     if (memcpy_s(g_hashVal, TTF_STRING_SIZE, hashStr, g_hashLen) != EOK) {
96         tloge("copy hash string failed\n");
97         g_hashLen = 0;
98         return;
99     }
100 #endif
101     return;
102 }
103 
Ascii2Digit(char a)104 static uint8_t Ascii2Digit(char a)
105 {
106     uint8_t hex = 0;
107 
108     if ((a >= '0') && (a <= '9')) {
109         hex = a - '0';
110     } else if ((a >= 'a') && (a <= 'f')) {
111         hex = (a - 'a') + ASCII_DIGIT_GAP;
112     } else if ((a >= 'A') && (a <= 'F')) {
113         hex = (a - 'A') + ASCII_DIGIT_GAP;
114     }
115 
116     return hex;
117 }
118 
TUISendEventToTz(TuiParameter * tuiParam)119 static bool TUISendEventToTz(TuiParameter *tuiParam)
120 {
121     int32_t fd = tee_open(TC_NS_CLIENT_DEV_NAME, O_RDWR, 0);
122     if (fd < 0) {
123         tloge("open tzdriver fd failed\n");
124         return false;
125     }
126     tlogd("TUISendEventToTz get fd = %" PUBLIC "d\n", fd);
127 
128     int32_t ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_TUI_EVENT, tuiParam);
129     tee_close(&fd);
130     if (ret != 0) {
131         tloge("Failed to send tui event[%" PUBLIC "d] to tzdriver, ret is %" PUBLIC "d \n",
132             tuiParam->eventType, ret);
133         return false;
134     }
135     return true;
136 }
137 
TUISendTTFHashToTeeos(void)138 static void TUISendTTFHashToTeeos(void)
139 {
140     uint32_t i, j;
141     TuiParameter tuiParam = {.eventType = TUI_POLL_NOTCH};
142 
143     if (g_tuiSendHashSuccess) {
144         return;
145     }
146 
147     if (g_hashLen != TTF_STRING_SIZE) {
148         tloge("tui font hash len invalid\n");
149         g_hashLen = 0;
150         return;
151     }
152     tlogd("tui font hash is : %" PUBLIC "s \n", g_hashVal);
153 
154     for (i = 0, j = 0; g_hashLen > 0 && i < (g_hashLen - 1) && j < sizeof(g_ttfHash); j++) {
155         g_ttfHash[j] = Ascii2Digit(g_hashVal[i++]) * HEX_BASE;
156         g_ttfHash[j] += Ascii2Digit(g_hashVal[i++]);
157     }
158 
159     int rc = memcpy_s(&tuiParam.value,
160         sizeof(tuiParam) - sizeof(tuiParam.eventType),
161         g_ttfHash, sizeof(g_ttfHash));
162     if (rc == EOK) {
163         if (TUISendEventToTz(&tuiParam)) {
164             g_tuiSendHashSuccess = true;
165         } else {
166             tloge("send notch msg failed\n");
167         }
168     } else {
169         tloge("memcpy tui font hash failed");
170     }
171 }
172 
TUISetStatus(bool status)173 void TUIEvent::TUISetStatus(bool status)
174 {
175     mTUIStatus = status;
176 }
177 
TUIGetStatus()178 bool TUIEvent::TUIGetStatus()
179 {
180     return mTUIStatus;
181 }
182 
TUIGetFoldableStatus()183 bool TUIEvent::TUIGetFoldableStatus()
184 {
185     return mTUIFoldable;
186 }
187 
TUIGetNotch(OHOS::sptr<CutoutInfo> cutoutInfo,uint32_t displayMode)188 static int TUIGetNotch(OHOS::sptr<CutoutInfo> cutoutInfo, uint32_t displayMode)
189 {
190     tlogi("tui get cutoutinfo--->boundingRects for notch\n");
191     std::vector<OHOS::Rosen::DMRect> boundingRects = cutoutInfo->GetBoundingRects();
192     if (boundingRects.empty()) {
193         tlogi("get boundingRects failed\n");
194         return 0;
195     }
196     for (uint32_t i = 0; i < boundingRects.size(); i++) {
197         tlogi("tui print boundingRects[%" PUBLIC "d] info: \
198 posX[%" PUBLIC "d], posY[%" PUBLIC "d], width[%" PUBLIC "d], height[%" PUBLIC "d] \n",
199             i, boundingRects[i].posX_, boundingRects[i].posY_,
200             boundingRects[i].width_, boundingRects[i].height_);
201     }
202     /* calc notch, here is px, double height of the hole */
203     int notch = boundingRects[0].height_ + boundingRects[0].height_;
204     if (notch < 0 || notch > NOTCH_SIZE_MAX) {
205         /* 200 is too large for notch, just use 0 */
206         return 0;
207     }
208     return notch;
209 }
210 
TUIGetDisplayMode(uint32_t foldState)211 static uint32_t TUIGetDisplayMode(uint32_t foldState)
212 {
213     if (foldState == FOLD_STATE_EXPANDED) {
214         return DISPLAY_MODE_FULL;
215     }
216 
217 #ifdef SCENE_BOARD_ENABLE
218     uint32_t displayMode = static_cast<uint32_t>(OHOS::Rosen::DisplayManagerLite::GetInstance().GetFoldDisplayMode());
219 #else
220     uint32_t displayMode = static_cast<uint32_t>(OHOS::Rosen::DisplayManager::GetInstance().GetFoldDisplayMode());
221 #endif
222     if (displayMode < DISPLAY_MODE_MAX) {
223         return displayMode;
224     }
225 
226     return DISPLAY_MODE_UNKNOWN; /* default mode */
227 }
228 
CheckSAStarted(int32_t targetSAId)229 bool CheckSAStarted(int32_t targetSAId)
230 {
231     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
232         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
233     if (!systemAbilityManager) {
234         tlogi("Failed to get system ability mgr\n");
235         return false;
236     }
237 
238     OHOS::sptr<OHOS::IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(targetSAId);
239     if (!remoteObject) {
240         tlogi("SA service [targetID = %" PUBLIC "d] is not exist\n", targetSAId);
241         return false;
242     }
243 
244     tlogd("get SA service, targetID = %" PUBLIC "d\n", targetSAId);
245     return true;
246 }
247 
IsDisplaySAReady()248 static bool IsDisplaySAReady()
249 {
250     int32_t retry = 0;
251 #ifdef SCENE_BOARD_ENABLE
252     while (!CheckSAStarted(OHOS::WINDOW_MANAGER_SERVICE_ID)) {
253 #else
254     while (!CheckSAStarted(OHOS::DISPLAY_MANAGER_SERVICE_SA_ID)) {
255 #endif
256         if (retry++ >= RETRY_TIMES) {
257             tlogi("can not get display service now\n");
258             return false;
259         }
260         sleep(RETRY_SLEEP_TIME);
261     }
262 
263     return true;
264 }
265 
266 bool TUIEvent::TUIGetPannelInfo()
267 {
268     if (!IsDisplaySAReady()) {
269         return false;
270     }
271 
272 #ifdef SCENE_BOARD_ENABLE
273     auto display = OHOS::Rosen::DisplayManagerLite::GetInstance().GetDefaultDisplay();
274 #else
275     auto display = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
276 #endif
277     if (display == nullptr) {
278         tloge("GetDefaultDisplay: failed!\n");
279         return false;
280     }
281 
282     OHOS::sptr<DisplayInfo> displayInfo = display->GetDisplayInfo();
283     if (displayInfo != nullptr) {
284         tlogi("get xdpi %" PUBLIC "f, ydpi %" PUBLIC "f, displaystate %" PUBLIC "u, DPI %" PUBLIC "d \n",
285             displayInfo->GetXDpi(), displayInfo->GetYDpi(),
286             (uint32_t)displayInfo->GetDisplayState(), displayInfo->GetDpi());
287     } else {
288         tloge("get displayInfo failed\n");
289         return false;
290     }
291 
292     TUIGetFoldable();
293 
294     mTUIPanelInfo.width = display->GetWidth();
295     mTUIPanelInfo.height = display->GetHeight();
296 
297     if (displayInfo->GetXDpi() != 0 && displayInfo->GetYDpi() != 0) {
298         mTUIPanelInfo.phyWidth = mTUIPanelInfo.width * INCH_CM_FACTOR / displayInfo->GetXDpi();
299         mTUIPanelInfo.phyHeight = mTUIPanelInfo.height * INCH_CM_FACTOR / displayInfo->GetYDpi();
300     }
301 
302     OHOS::sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
303     if (cutoutInfo == nullptr) {
304         tloge("get cutoutinfo failed\n");
305     } else {
306         mTUIPanelInfo.notch = TUIGetNotch(cutoutInfo, mTUIPanelInfo.displayMode);
307     }
308 
309     tlogi("tui panelinfo: w %" PUBLIC "d, h %" PUBLIC "d, fold %" PUBLIC "u, "
310         "displayMode %" PUBLIC "u, notch %" PUBLIC "u\n",
311         mTUIPanelInfo.width, mTUIPanelInfo.height, mTUIPanelInfo.foldState,
312         mTUIPanelInfo.displayMode, mTUIPanelInfo.notch);
313 
314     return true;
315 }
316 
317 void TUIEvent::TUIGetFoldable()
318 {
319 #ifdef SCENE_BOARD_ENABLE
320     mTUIFoldable = OHOS::Rosen::DisplayManagerLite::GetInstance().IsFoldable();
321 #else
322     mTUIFoldable = OHOS::Rosen::DisplayManager::GetInstance().IsFoldable();
323 #endif
324     tlogi("TuiDaemonInit mTUIFoldable %" PUBLIC "d\n", mTUIFoldable);
325     if (mTUIFoldable) {
326         tlogi("tui get fold state\n");
327     #ifdef SCENE_BOARD_ENABLE
328         mTUIPanelInfo.foldState = static_cast<uint32_t>(OHOS::Rosen::DisplayManagerLite::GetInstance().GetFoldStatus());
329     #else
330         mTUIPanelInfo.foldState = static_cast<uint32_t>(OHOS::Rosen::DisplayManager::GetInstance().GetFoldStatus());
331     #endif
332         if (mTUIPanelInfo.foldState >= FOLD_STATE_HALF_FOLDED) {
333             mTUIPanelInfo.foldState = FOLD_STATE_UNKNOWN; /* default state */
334         }
335     } else {
336         mTUIPanelInfo.foldState = FOLD_STATE_UNKNOWN;
337     }
338 
339     mTUIPanelInfo.displayMode = TUIGetDisplayMode(mTUIPanelInfo.foldState);
340     if (mTUIPanelInfo.foldState == FOLD_STATE_EXPANDED) {
341         mTUIPanelInfo.foldState += TUI_NEED_ROTATE;
342     }
343 
344     return;
345 }
346 
347 void TUIEvent::TUIGetRunningLock()
348 {
349     if (mRunningLock_ == nullptr) {
350         auto &powerMgrClient = OHOS::PowerMgr::PowerMgrClient::GetInstance();
351         mRunningLock_ = powerMgrClient.CreateRunningLock("TuiDaemonRunningLock",
352             OHOS::PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
353     }
354 
355     if (mRunningLock_ != nullptr) {
356         mRunningLock_->Lock();
357         tlogi("TUI Get RunningLock\n");
358     }
359     return;
360 }
361 
362 void TUIEvent::TUIReleaseRunningLock()
363 {
364     if (mRunningLock_ != nullptr) {
365         mRunningLock_->UnLock();
366     }
367 
368     tlogi("TUI Release RunningLock\n");
369     return;
370 }
371 
372 void TUIEvent::TuiEventInit()
373 {
374     mRunningLock_ = nullptr;
375 
376     mTUIPanelInfo = { 0 };
377     mTUIStatus = false;
378     mTUIFoldable = false;
379 
380     return;
381 }
382 
383 bool TUIEvent::TUISendCmd(uint32_t tuiEvent)
384 {
385     TuiParameter tuiParam = {0};
386 
387     if (tuiEvent == TUI_POLL_CANCEL) {
388         tuiParam.eventType = TUI_POLL_CANCEL;
389         tuiParam.value = 0;
390     } else {
391         (void)memcpy_s(&tuiParam, sizeof(tuiParam), &mTUIPanelInfo, sizeof(mTUIPanelInfo));
392         tuiParam.eventType = TUI_POLL_FOLD;
393         tuiParam.value = 0;
394     }
395 
396     /* if not send hash success, try again */
397     TUISendTTFHashToTeeos();
398 
399     if (TUISendEventToTz(&tuiParam) == false) {
400         tloge("tui send cmd failed\n");
401         return false;
402     }
403 
404     return true;
405 }
406 
407 void TUIEvent::TUIDealWithEvent(bool state)
408 {
409     if (state == false) {
410         /* not need send cmd to tzdriver */
411         TUIReleaseRunningLock();
412         TUISetStatus(false);
413         return;
414     }
415 
416     TUIGetRunningLock();
417     TUIGetPannelInfo();
418     TUISetStatus(true);
419     TUISendCmd(TUI_POLL_FOLD);
420 }
421 
422 void TUIDisplayListener::OnFoldStatusChanged(OHOS::Rosen::FoldStatus foldState)
423 {
424     if (foldState != OHOS::Rosen::FoldStatus::EXPAND && foldState != OHOS::Rosen::FoldStatus::FOLDED) {
425         tloge("foldState = %" PUBLIC "u invalid\n", static_cast<uint32_t>(foldState));
426         return;
427     }
428 
429     /* if foldState changed, should:
430      * 1. get pannelinfo,
431      * 2. send infos to teeos,
432      * 3. cancel current running proc
433      */
434     auto tempTUIInstance = TUIEvent::GetInstance();
435     if (tempTUIInstance == nullptr) {
436         return;
437     }
438     tlogi("get TUIStatus is %" PUBLIC "x\n", tempTUIInstance->TUIGetStatus());
439     if (tempTUIInstance->TUIGetPannelInfo()) {
440         (void)tempTUIInstance->TUISendCmd(TUI_POLL_FOLD);  /* EVENT TUI_POLL_FOLD */
441     }
442     if (tempTUIInstance->TUIGetStatus()) {
443         tlogi("foldState changed, need cancel TUI proc\n");
444         (void)tempTUIInstance->TUISendCmd(TUI_POLL_CANCEL); /* EVENT Exit */
445     }
446 }
447 
448 int32_t TUICallManagerCallback::OnCallDetailsChange(const OHOS::Telephony::CallAttributeInfo &info)
449 {
450     tlogd("----------OnCallDetailsChange--------\n");
451     tlogd("callId: %" PUBLIC "x\n", info.callId);
452     tlogd("callType: %" PUBLIC "x\n", (int32_t)info.callType);
453     tlogd("callState: %" PUBLIC "x\n", (int32_t)info.callState);
454     tlogd("conferenceState: %" PUBLIC "x\n", (int32_t)info.conferenceState);
455     tlogd("accountNumber: %" PUBLIC "s\n", info.accountNumber);
456 
457     if (info.callState == OHOS::Telephony::TelCallState::CALL_STATUS_INCOMING) {
458         auto tempTUIInstance = TUIEvent::GetInstance();
459         if (tempTUIInstance->TUIGetStatus()) {
460             tlogi("new call state CALL_STATUS_INCOMING, need send cmd to teeos to cancel TUI proc\n");
461             tempTUIInstance->TUISetStatus(false); /* change tuiStatus to false */
462             (void)tempTUIInstance->TUISendCmd(TUI_POLL_CANCEL);  /* EVENT Exit */
463         }
464         tlogd("tui get new call state CALL_STATUS_INCOMING\n");
465     }
466     return 0;
467 }
468 
469 void TUIDaemon::TuiRegisteCallBack()
470 {
471     if (g_tuiCallBackRegisted) {
472         return;
473     }
474 
475     int32_t retry = 0;
476     while (CheckSAStarted(OHOS::TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID) == false) {
477         sleep(RETRY_SLEEP_TIME);
478         retry++;
479         if (retry >= RETRY_TIMES) {
480             tlogi("can not get telephony service now\n");
481             return;
482         }
483     }
484 
485     if (mTUITelephonyCallBack_ == nullptr) {
486         mTUITelephonyCallBack_ = std::make_unique<TUICallManagerCallback>();
487         if (mTUITelephonyCallBack_ == nullptr) {
488             tloge("init callback instance failed\n");
489             return;
490         }
491     }
492 
493     if (callManagerClientPtr == nullptr) {
494         callManagerClientPtr = OHOS::DelayedSingleton<OHOS::Telephony::CallManagerClient>::GetInstance();
495         if (callManagerClientPtr == nullptr) {
496             tloge("get callManagerClientPtr failed\n");
497             return;
498         }
499     }
500 
501     tlogi("callback get instance finish\n");
502     callManagerClientPtr->Init(OHOS::TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID);
503     tlogi("callback init finish\n");
504     int32_t ret = callManagerClientPtr->RegisterCallBack(std::move(mTUITelephonyCallBack_));
505     if (ret != TEEC_SUCCESS) {
506         tloge("regist telephony callback failed ret = 0x%" PUBLIC "x\n", ret);
507     } else {
508         g_tuiCallBackRegisted = true;
509         tlogi("regist telephony callback done\n");
510     }
511 }
512 
513 void TUIDaemon::TuiRegisteDisplayListener()
514 {
515     if (g_tuiDisplayListenerRegisted) {
516         return;
517     }
518 
519     if (!IsDisplaySAReady()) {
520         return;
521     }
522 
523     if (mTUIDisplayListener_ == nullptr) {
524         mTUIDisplayListener_ = new TUIDisplayListener();
525         if (mTUIDisplayListener_ == nullptr) {
526             tloge("create listener obj failed\n");
527             return;
528         }
529     }
530 #ifdef SCENE_BOARD_ENABLE
531     OHOS::Rosen::DisplayManagerLite &dmPtr = (OHOS::Rosen::DisplayManagerLite::GetInstance());
532 #else
533     OHOS::Rosen::DisplayManager &dmPtr = (OHOS::Rosen::DisplayManager::GetInstance());
534 #endif
535     int32_t result = (int32_t)dmPtr.RegisterFoldStatusListener(mTUIDisplayListener_);
536     if (result == TEEC_SUCCESS) {
537         g_tuiDisplayListenerRegisted = true;
538         tlogi("regist display listener done\n");
539     } else {
540         tloge("regist display listener failed\n");
541     }
542 }
543 
544 void TUIDaemon::TuiDaemonInit(bool onlyConfigRes)
545 {
546     TUISaveTTFHash();
547     auto tuiEvent = TUIEvent::GetInstance();
548     tuiEvent->TuiEventInit();
549 
550     if (!onlyConfigRes) {
551         TuiRegisteCallBack();
552         TuiRegisteDisplayListener();
553     }
554 
555     tlogi("TUIDaemon init ok\n");
556 }
557 
558 TUIDaemon::~TUIDaemon()
559 {
560     if (mTUIDisplayListener_ != nullptr) {
561 #ifdef SCENE_BOARD_ENABLE
562         OHOS::Rosen::DisplayManagerLite::GetInstance().UnregisterFoldStatusListener(mTUIDisplayListener_);
563 #else
564         OHOS::Rosen::DisplayManager::GetInstance().UnregisterFoldStatusListener(mTUIDisplayListener_);
565 #endif
566         mTUIDisplayListener_ = nullptr;
567     }
568 
569     if (g_tuiCallBackRegisted) {
570         OHOS::DelayedSingleton<OHOS::Telephony::CallManagerClient>::GetInstance()->UnRegisterCallBack();
571         g_tuiCallBackRegisted = false;
572     }
573 
574     tlogi("TUIDaemon released\n");
575 }
576