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 "os_account_state_reply_callback_service.h"
17
18 #include "account_hisysevent_adapter.h"
19 #include "account_log_wrapper.h"
20 #include "ipc_skeleton.h"
21 #include "os_account_constants.h"
22
23 namespace OHOS {
24 namespace AccountSA {
25 namespace {
26 constexpr int64_t TIMEOUT_THRESHOLD = 5000000; // 5s
ConvertStateToSceneFlag(OsAccountState state)27 static const char *ConvertStateToSceneFlag(OsAccountState state)
28 {
29 switch (state) {
30 case OsAccountState::STOPPING:
31 case OsAccountState::STOPPED:
32 return Constants::OPERATION_STOP;
33 case OsAccountState::ACTIVATED:
34 case OsAccountState::ACTIVATING:
35 return Constants::OPERATION_ACTIVATE;
36 case OsAccountState::CREATED:
37 return Constants::OPERATION_CREATE;
38 case OsAccountState::REMOVED:
39 return Constants::OPERATION_REMOVE;
40 case OsAccountState::SWITCHING:
41 case OsAccountState::SWITCHED:
42 return Constants::OPERATION_SWITCH;
43 case OsAccountState::UNLOCKED:
44 return Constants::OPERATION_UNLOCK;
45 default:
46 return "";
47 }
48 }
49 }
50
~OsAccountStateReplyCallbackService()51 OsAccountStateReplyCallbackService::~OsAccountStateReplyCallbackService()
52 {}
53
OsAccountStateReplyCallbackService(int32_t accountId,OsAccountState state,const std::shared_ptr<std::condition_variable> & cvPtr,const std::shared_ptr<SafeQueue<uint8_t>> & safeQueue,int32_t subscriberUid)54 OsAccountStateReplyCallbackService::OsAccountStateReplyCallbackService(int32_t accountId, OsAccountState state,
55 const std::shared_ptr<std::condition_variable> &cvPtr, const std::shared_ptr<SafeQueue<uint8_t>> &safeQueue,
56 int32_t subscriberUid)
57 : accountId_(accountId), state_(state), cvPtr_(cvPtr), safeQueue_(safeQueue), subscriberUid_(subscriberUid)
58 {}
59
OnComplete()60 ErrCode OsAccountStateReplyCallbackService::OnComplete()
61 {
62 std::lock_guard lock(mutex_);
63 int64_t duration = 0;
64 if (startTime_.time_since_epoch().count() != 0) {
65 duration = std::chrono::duration_cast<std::chrono::microseconds>(
66 std::chrono::system_clock::now() - startTime_).count();
67 }
68 if (isCompleted_) {
69 ACCOUNT_LOGE("Already completed, callingUid: %{public}d", subscriberUid_);
70 return ERR_OK;
71 }
72 int32_t callerUid = IPCSkeleton::GetCallingUid();
73 if (callerUid != subscriberUid_) {
74 ACCOUNT_LOGE("Permission denied");
75 ReportOsAccountOperationFail(accountId_, ConvertStateToSceneFlag(state_), ERR_ACCOUNT_COMMON_PERMISSION_DENIED,
76 "Failed to check permission, callerUid=" + std::to_string(callerUid) + ", subscriberUid="
77 + std::to_string(subscriberUid_) + ", state=" + std::to_string(state_));
78 return ERR_OK;
79 }
80 isCompleted_ = true;
81 if (duration > TIMEOUT_THRESHOLD) {
82 ACCOUNT_LOGE("Timeout, callingUid: %{public}d, duration: %{public}lld us",
83 subscriberUid_, static_cast<long long>(duration));
84 ReportOsAccountOperationFail(accountId_, ConvertStateToSceneFlag(state_), ERR_ACCOUNT_COMMON_OPERATION_TIMEOUT,
85 "OnComplete timed out, duration=" + std::to_string(duration) + "us, uid=" + std::to_string(subscriberUid_)
86 + ", state=" + std::to_string(state_));
87 }
88 ACCOUNT_LOGI("Done, subscriberUid: %{public}d, state: %{public}d", subscriberUid_, state_);
89 if (cvPtr_ == nullptr || safeQueue_ == nullptr) {
90 ACCOUNT_LOGE("CvPtr or SafeQueue is nullptr");
91 return ERR_OK;
92 }
93 uint8_t tmp;
94 safeQueue_->Pop(tmp);
95 cvPtr_->notify_one();
96 return ERR_OK;
97 }
98
SetStartTime(const std::chrono::system_clock::time_point & startTime)99 void OsAccountStateReplyCallbackService::SetStartTime(const std::chrono::system_clock::time_point &startTime)
100 {
101 std::lock_guard lock(mutex_);
102 startTime_ = startTime;
103 }
104
GetSubscriberUid() const105 int32_t OsAccountStateReplyCallbackService::GetSubscriberUid() const
106 {
107 return subscriberUid_;
108 }
109 } // namespace AccountSA
110 } // namespace OHOS
111