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