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 }
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 auto 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 .colorValue = color.singleColor
83 };
84 HDI::Light::V1_0::HdfLightFlashEffect flashEffect = {
85 .flashMode = animation.mode,
86 .onTime = animation.onTime,
87 .offTime = animation.offTime
88 };
89 HDI::Light::V1_0::HdfLightEffect effect = {
90 .lightColor = lightColor,
91 .flashEffect = flashEffect
92 };
93 CHKPR(lightInterface_, ERROR);
94 int32_t ret = lightInterface_->TurnOnLight(lightId, effect);
95 if (ret < 0) {
96 MISC_HILOGE("TurnOn failed");
97 return ret;
98 }
99 return ERR_OK;
100 }
101
TurnOff(int32_t lightId)102 int32_t HdiLightConnection::TurnOff(int32_t lightId)
103 {
104 CALL_LOG_ENTER;
105 CHKPR(lightInterface_, ERROR);
106 int32_t ret = lightInterface_->TurnOffLight(lightId);
107 if (ret < 0) {
108 MISC_HILOGE("TurnOff failed");
109 return ret;
110 }
111 return ERR_OK;
112 }
113
DestroyHdiConnection()114 int32_t HdiLightConnection::DestroyHdiConnection()
115 {
116 UnregisterHdiDeathRecipient();
117 return ERR_OK;
118 }
119
RegisterHdiDeathRecipient()120 void HdiLightConnection::RegisterHdiDeathRecipient()
121 {
122 CALL_LOG_ENTER;
123 if (lightInterface_ == nullptr) {
124 MISC_HILOGE("connect v1_0 hdi failed");
125 return;
126 }
127 hdiDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<HdiLightConnection *>(this));
128 if (hdiDeathObserver_ == nullptr) {
129 MISC_HILOGE("hdiDeathObserver_ is nullptr");
130 return;
131 }
132 OHOS::HDI::hdi_objcast<ILightInterface>(lightInterface_)->AddDeathRecipient(hdiDeathObserver_);
133 }
134
UnregisterHdiDeathRecipient()135 void HdiLightConnection::UnregisterHdiDeathRecipient()
136 {
137 CALL_LOG_ENTER;
138 if (lightInterface_ == nullptr || hdiDeathObserver_ == nullptr) {
139 MISC_HILOGE("lightInterface_ or hdiDeathObserver_ is nullptr");
140 return;
141 }
142 OHOS::HDI::hdi_objcast<ILightInterface>(lightInterface_)->RemoveDeathRecipient(hdiDeathObserver_);
143 }
144
ProcessDeathObserver(const wptr<IRemoteObject> & object)145 void HdiLightConnection::ProcessDeathObserver(const wptr<IRemoteObject> &object)
146 {
147 CALL_LOG_ENTER;
148 sptr<IRemoteObject> hdiService = object.promote();
149 if (hdiService == nullptr || hdiDeathObserver_ == nullptr) {
150 MISC_HILOGE("invalid remote object or hdiDeathObserver_ is null");
151 return;
152 }
153 hdiService->RemoveDeathRecipient(hdiDeathObserver_);
154 Reconnect();
155 }
156
Reconnect()157 void HdiLightConnection::Reconnect()
158 {
159 if (ConnectHdi() != ERR_OK) {
160 MISC_HILOGE("connect hdi failed");
161 }
162 }
163 } // namespace Sensors
164 } // namespace OHOS
165