1 /*
2 * Copyright (c) 2022 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 "light_client.h"
17
18 #include <securec.h>
19 #include <thread>
20
21 #include "death_recipient_template.h"
22 #include "hisysevent.h"
23 #include "iservice_registry.h"
24 #include "sensors_errors.h"
25 #include "system_ability_definition.h"
26
27 namespace OHOS {
28 namespace Sensors {
29
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "LightClient" };
32 constexpr int32_t GET_SERVICE_MAX_COUNT = 30;
33 constexpr uint32_t MAX_LIGHT_LIST_SIZE = 0X00ff;
34 constexpr uint32_t WAIT_MS = 200;
35 } // namespace
36
InitLightClient()37 int32_t LightClient::InitLightClient()
38 {
39 CALL_LOG_ENTER;
40 std::lock_guard<std::mutex> clientLock(clientMutex_);
41 if (miscdeviceProxy_ != nullptr) {
42 MISC_HILOGD("miscdeviceProxy_ already init");
43 return ERR_OK;
44 }
45 auto systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
46 CHKPR(systemManager, MISC_NATIVE_SAM_ERR);
47 int32_t retry = 0;
48 while (retry < GET_SERVICE_MAX_COUNT) {
49 miscdeviceProxy_ = iface_cast<IMiscdeviceService>(systemManager->GetSystemAbility(
50 MISCDEVICE_SERVICE_ABILITY_ID));
51 if (miscdeviceProxy_ != nullptr) {
52 MISC_HILOGD("miscdeviceProxy_ get service success, retry:%{public}d", retry);
53 serviceDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<LightClient *>(this));
54 if (serviceDeathObserver_ != nullptr) {
55 miscdeviceProxy_->AsObject()->AddDeathRecipient(serviceDeathObserver_);
56 }
57 lightInfoList_ = miscdeviceProxy_->GetLightList();
58 return ERR_OK;
59 }
60 MISC_HILOGW("Get service failed, retry:%{public}d", retry);
61 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
62 retry++;
63 }
64 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_EXCEPTION",
65 HiviewDFX::HiSysEvent::EventType::FAULT, "PKG_NAME", "InitLightClient", "ERROR_CODE", MISC_NATIVE_GET_SERVICE_ERR);
66 MISC_HILOGE("Get service failed");
67 return MISC_NATIVE_GET_SERVICE_ERR;
68 }
69
IsLightIdValid(int32_t lightId)70 bool LightClient::IsLightIdValid(int32_t lightId)
71 {
72 int32_t ret = InitLightClient();
73 if (ret != ERR_OK) {
74 MISC_HILOGE("InitLightClient failed, ret:%{public}d", ret);
75 return false;
76 }
77 for (const auto &item : lightInfoList_) {
78 if (lightId == item.lightId) {
79 return true;
80 }
81 }
82 return false;
83 }
84
GetLightList(LightInfo ** lightInfo,int32_t & count)85 int32_t LightClient::GetLightList(LightInfo **lightInfo, int32_t &count)
86 {
87 CALL_LOG_ENTER;
88 CHKPR(lightInfo, ERROR);
89 int32_t ret = InitLightClient();
90 if (ret != ERR_OK) {
91 MISC_HILOGE("InitLightClient failed");
92 return ERROR;
93 }
94 std::lock_guard<std::mutex> lightInfosLock(lightInfosMutex_);
95 if (lightInfos_ == nullptr) {
96 int32_t ret = ConvertLightInfos();
97 if (ret != ERR_OK) {
98 MISC_HILOGE("Convert light lists failed");
99 ClearLightInfos();
100 return ERROR;
101 }
102 }
103 *lightInfo = lightInfos_;
104 count = lightInfoCount_;
105 return ERR_OK;
106 }
107
IsLightAnimationValid(const LightAnimation & animation)108 bool LightClient::IsLightAnimationValid(const LightAnimation &animation)
109 {
110 if ((animation.mode < 0) || (animation.mode >= LIGHT_MODE_BUTT)) {
111 MISC_HILOGE("animation mode is invalid, mode:%{pubilc}d", animation.mode);
112 return false;
113 }
114 if ((animation.onTime < 0) || (animation.offTime < 0)) {
115 MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{pubilc}d, offTime:%{pubilc}d",
116 animation.onTime, animation.offTime);
117 return false;
118 }
119 return true;
120 }
121
TurnOn(int32_t lightId,const LightColor & color,const LightAnimation & animation)122 int32_t LightClient::TurnOn(int32_t lightId, const LightColor &color, const LightAnimation &animation)
123 {
124 CALL_LOG_ENTER;
125 if (!IsLightIdValid(lightId)) {
126 MISC_HILOGE("lightId is invalid, lightId:%{pubilc}d", lightId);
127 return PARAMETER_ERROR;
128 }
129 if (!IsLightAnimationValid(animation)) {
130 MISC_HILOGE("animation is invalid");
131 return PARAMETER_ERROR;
132 }
133 CHKPR(miscdeviceProxy_, ERROR);
134 return miscdeviceProxy_->TurnOn(lightId, color, animation);
135 }
136
TurnOff(int32_t lightId)137 int32_t LightClient::TurnOff(int32_t lightId)
138 {
139 CALL_LOG_ENTER;
140 if (!IsLightIdValid(lightId)) {
141 MISC_HILOGE("lightId is invalid, lightId:%{pubilc}d", lightId);
142 return LIGHT_ID_NOT_SUPPORT;
143 }
144 CHKPR(miscdeviceProxy_, ERROR);
145 return miscdeviceProxy_->TurnOff(lightId);
146 }
147
ProcessDeathObserver(wptr<IRemoteObject> object)148 void LightClient::ProcessDeathObserver(wptr<IRemoteObject> object)
149 {
150 CALL_LOG_ENTER;
151 (void)object;
152 miscdeviceProxy_ = nullptr;
153 auto ret = InitLightClient();
154 if (ret != ERR_OK) {
155 MISC_HILOGE("InitLightClient failed, ret:%{public}d", ret);
156 return;
157 }
158 }
159
ClearLightInfos()160 void LightClient::ClearLightInfos()
161 {
162 CHKPV(lightInfos_);
163 free(lightInfos_);
164 lightInfos_ = nullptr;
165 }
166
ConvertLightInfos()167 int32_t LightClient::ConvertLightInfos()
168 {
169 CALL_LOG_ENTER;
170 if (lightInfoList_.empty()) {
171 MISC_HILOGE("get light lists failed");
172 return ERROR;
173 }
174 size_t count = lightInfoList_.size();
175 if (count > MAX_LIGHT_LIST_SIZE) {
176 MISC_HILOGE("The number of lights exceed the maximum value");
177 return ERROR;
178 }
179 lightInfos_ = (LightInfo *)malloc(sizeof(LightInfo) * count);
180 CHKPR(lightInfos_, ERROR);
181 for (size_t i = 0; i < count; ++i) {
182 *(lightInfos_ + i) = lightInfoList_[i];
183 }
184 lightInfoCount_ = static_cast<int32_t>(count);
185 return SUCCESS;
186 }
187 } // namespace Sensors
188 } // namespace OHOS
189