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 "hdi_light_connection.h"
17
18 #include <memory>
19 #include <securec.h>
20 #include <thread>
21 #include <vector>
22
23 #include "hisysevent.h"
24 #include "v1_0/light_interface_proxy.h"
25 #include "sensors_errors.h"
26
27 namespace OHOS {
28 namespace Sensors {
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "HdiLightConnection" };
31 constexpr int32_t GET_HDI_SERVICE_COUNT = 10;
32 constexpr uint32_t WAIT_MS = 100;
33 } // namespace
34
ConnectHdi()35 int32_t HdiLightConnection::ConnectHdi()
36 {
37 CALL_LOG_ENTER;
38 int32_t retry = 0;
39 while (retry < GET_HDI_SERVICE_COUNT) {
40 lightInterface_ = ILightInterface::Get();
41 if (lightInterface_ != nullptr) {
42 RegisterHdiDeathRecipient();
43 return ERR_OK;
44 }
45 retry++;
46 MISC_HILOGW("Connect hdi service failed, retry:%{public}d", retry);
47 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
48 }
49 return ERR_INVALID_VALUE;
50 }
51
GetLightList(std::vector<LightInfo> & lightList) const52 int32_t HdiLightConnection::GetLightList(std::vector<LightInfo> &lightList) const
53 {
54 CALL_LOG_ENTER;
55 std::vector<HDI::Light::V1_0::HdfLightInfo> lightInfos;
56 CHKPR(lightInterface_, ERROR);
57 int32_t ret = lightInterface_->GetLightInfo(lightInfos);
58 if (ret != 0) {
59 MISC_HILOGE("Get light info failed");
60 return ret;
61 }
62 for (size_t i = 0; i < lightInfos.size(); ++i) {
63 LightInfo light;
64 light.lightId = lightInfos[i].lightId;
65 light.lightNumber = lightInfos[i].lightNumber;
66 ret = memcpy_s(light.lightName, NAME_MAX_LEN, lightInfos[i].lightName.c_str(),
67 lightInfos[i].lightName.length());
68 if (ret != EOK) {
69 MISC_HILOGE("memcpy_s failed, error number:%{public}d", errno);
70 return ret;
71 }
72 light.lightType = lightInfos[i].lightType;
73 lightList.push_back(light);
74 }
75 return ERR_OK;
76 }
77
TurnOn(int32_t lightId,const LightColor & color,const LightAnimation & animation)78 int32_t HdiLightConnection::TurnOn(int32_t lightId, const LightColor &color, const LightAnimation &animation)
79 {
80 CALL_LOG_ENTER;
81 HDI::Light::V1_0::HdfLightColor lightColor;
82 lightColor.colorValue.singleColor = color.singleColor;
83
84 HDI::Light::V1_0::HdfLightFlashEffect flashEffect;
85 flashEffect.flashMode = animation.mode;
86 flashEffect.onTime = animation.onTime;
87 flashEffect.offTime = animation.offTime;
88
89 HDI::Light::V1_0::HdfLightEffect effect;
90 effect.lightColor = lightColor;
91 effect.flashEffect = flashEffect;
92 CHKPR(lightInterface_, ERROR);
93 int32_t ret = lightInterface_->TurnOnLight(lightId, effect);
94 if (ret < 0) {
95 MISC_HILOGE("TurnOn failed");
96 return ret;
97 }
98 return ERR_OK;
99 }
100
TurnOff(int32_t lightId)101 int32_t HdiLightConnection::TurnOff(int32_t lightId)
102 {
103 CALL_LOG_ENTER;
104 CHKPR(lightInterface_, ERROR);
105 int32_t ret = lightInterface_->TurnOffLight(lightId);
106 if (ret < 0) {
107 MISC_HILOGE("TurnOff failed");
108 return ret;
109 }
110 return ERR_OK;
111 }
112
DestroyHdiConnection()113 int32_t HdiLightConnection::DestroyHdiConnection()
114 {
115 UnregisterHdiDeathRecipient();
116 return ERR_OK;
117 }
118
RegisterHdiDeathRecipient()119 void HdiLightConnection::RegisterHdiDeathRecipient()
120 {
121 CALL_LOG_ENTER;
122 if (lightInterface_ == nullptr) {
123 MISC_HILOGE("Connect v1_0 hdi failed");
124 return;
125 }
126 if (hdiDeathObserver_ == nullptr) {
127 hdiDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<HdiLightConnection *>(this));
128 CHKPV(hdiDeathObserver_);
129 }
130 OHOS::HDI::hdi_objcast<ILightInterface>(lightInterface_)->AddDeathRecipient(hdiDeathObserver_);
131 }
132
UnregisterHdiDeathRecipient()133 void HdiLightConnection::UnregisterHdiDeathRecipient()
134 {
135 CALL_LOG_ENTER;
136 if (lightInterface_ == nullptr || hdiDeathObserver_ == nullptr) {
137 MISC_HILOGE("lightInterface_ or hdiDeathObserver_ is nullptr");
138 return;
139 }
140 OHOS::HDI::hdi_objcast<ILightInterface>(lightInterface_)->RemoveDeathRecipient(hdiDeathObserver_);
141 }
142
ProcessDeathObserver(const wptr<IRemoteObject> & object)143 void HdiLightConnection::ProcessDeathObserver(const wptr<IRemoteObject> &object)
144 {
145 CALL_LOG_ENTER;
146 sptr<IRemoteObject> hdiService = object.promote();
147 if (hdiService == nullptr || hdiDeathObserver_ == nullptr) {
148 MISC_HILOGE("Invalid remote object or hdiDeathObserver_ is null");
149 return;
150 }
151 hdiService->RemoveDeathRecipient(hdiDeathObserver_);
152 Reconnect();
153 }
154
Reconnect()155 void HdiLightConnection::Reconnect()
156 {
157 if (ConnectHdi() != ERR_OK) {
158 MISC_HILOGE("Connect hdi failed");
159 }
160 }
161 } // namespace Sensors
162 } // namespace OHOS
163