1 /*
2  * Copyright (c) 2024 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 "infrared_emitter_controller.h"
17 
18 #include <dlfcn.h>
19 #include <memory>
20 #include <mutex>
21 
22 #include "mmi_log.h"
23 
24 #undef MMI_LOG_DOMAIN
25 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
26 #undef MMI_LOG_TAG
27 #define MMI_LOG_TAG "InfraredEmitterController"
28 
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 const std::string IR_WRAPPER_PATH { "libconsumer_ir_service_1.0.z.so" };
33 std::mutex mutex_;
34 }
35 using namespace OHOS::HDI::V1_0;
36 InfraredEmitterController *InfraredEmitterController::instance_ = new (std::nothrow) InfraredEmitterController();
InfraredEmitterController()37 InfraredEmitterController::InfraredEmitterController() {}
38 
~InfraredEmitterController()39 InfraredEmitterController::~InfraredEmitterController()
40 {
41     CALL_DEBUG_ENTER;
42     std::lock_guard<std::mutex> guard(mutex_);
43     irInterface_ = nullptr;
44     if (soIrHandle_ != nullptr) {
45         dlclose(soIrHandle_);
46         soIrHandle_ = nullptr;
47     }
48 }
49 
GetInstance()50 InfraredEmitterController *InfraredEmitterController::GetInstance()
51 {
52     std::lock_guard<std::mutex> guard(mutex_);
53     return instance_;
54 }
55 
InitInfraredEmitter()56 void InfraredEmitterController::InitInfraredEmitter()
57 {
58     CALL_DEBUG_ENTER;
59     if (irInterface_ != nullptr) {
60         return;
61     }
62     if (soIrHandle_ == nullptr) {
63         soIrHandle_ = dlopen(IR_WRAPPER_PATH.c_str(), RTLD_NOW);
64         if (soIrHandle_ == nullptr) {
65             MMI_HILOGE("Loaded %{public}s failed:%{public}s", IR_WRAPPER_PATH.c_str(), dlerror());
66             return;
67         }
68     }
69     typedef ConsumerIr* (*funCreate_ptr) (void);
70     funCreate_ptr fnCreate = nullptr;
71     fnCreate = (funCreate_ptr)dlsym(soIrHandle_, "ConsumerIrImplGetInstance");
72     const char *dlsymError = dlerror();
73     if (dlsymError != nullptr) {
74         MMI_HILOGE("Loaded ConsumerIrImplGetInstance failed:%{public}s", dlsymError);
75         dlclose(soIrHandle_);
76         soIrHandle_ = nullptr;
77         return;
78     }
79     if (fnCreate == nullptr) {
80         MMI_HILOGE("Loaded ConsumerIrImplGetInstance is null");
81         dlclose(soIrHandle_);
82         soIrHandle_ = nullptr;
83         return;
84     }
85     MMI_HILOGI("Infrared emitter call ConsumerIr:fnCreate begin");
86     irInterface_ = (ConsumerIr *)fnCreate();
87     if (irInterface_ == nullptr) {
88         MMI_HILOGE("Infrared emitter init fail irInterface_ is nullptr");
89         dlclose(soIrHandle_);
90         soIrHandle_ = nullptr;
91         return;
92     }
93 }
94 
Transmit(int64_t carrierFreq, const std::vector<int64_t> pattern)95 bool InfraredEmitterController::Transmit(int64_t carrierFreq, const std::vector<int64_t> pattern)
96 {
97     CALL_DEBUG_ENTER;
98     std::lock_guard<std::mutex> guard(mutex_);
99     InitInfraredEmitter();
100     CHKPF(irInterface_);
101     int32_t tempCarrierFreq = carrierFreq;
102     std::vector<int32_t> tempPattern;
103     std::string context = "infraredFrequency:" + std::to_string(tempCarrierFreq) + ";";
104     for (size_t i = 0; i < pattern.size(); i++) {
105         int32_t per = pattern[i];
106         context = context + "index:" + std::to_string(i) + ": pattern:" + std::to_string(per) + ";";
107         tempPattern.push_back(per);
108     }
109     MMI_HILOGI("irInterface_->Transmit params:%{public}s", context.c_str());
110     bool outRet = false;
111     int32_t ret = irInterface_->Transmit(tempCarrierFreq, tempPattern, outRet);
112     MMI_HILOGI("irInterface_->Transmit ret:%{public}d", ret);
113     if (ret < 0) {
114         MMI_HILOGE("Infrared emitter transmit failed:%{public}d", ret);
115         return false;
116     }
117     if (!outRet) {
118         MMI_HILOGE("Infrared emitter transmit out false");
119         return false;
120     }
121     return true;
122 }
123 
GetFrequencies(std::vector<InfraredFrequencyInfo> &frequencyInfo)124 bool InfraredEmitterController::GetFrequencies(std::vector<InfraredFrequencyInfo> &frequencyInfo)
125 {
126     CALL_DEBUG_ENTER;
127     std::lock_guard<std::mutex> guard(mutex_);
128     InitInfraredEmitter();
129     if (!irInterface_) {
130         MMI_HILOGE("Infrared emitter not init");
131         return false;
132     }
133     bool outRet = false;
134     std::vector<ConsumerIrFreqRange> outRange;
135     MMI_HILOGI("irInterface_->GetCarrierFreqs");
136     int32_t ret = irInterface_->GetCarrierFreqs(outRet, outRange);
137     MMI_HILOGI("irInterface_->GetCarrierFreqs ret:%{public}d", ret);
138     if (ret < 0) {
139         MMI_HILOGE("Infrared emitter GetCarrierFreqs failed:%{public}d", ret);
140         return false;
141     }
142     if (!outRet) {
143         MMI_HILOGE("Infrared emitter GetCarrierFreqs out false");
144         return false;
145     }
146     std::string context = "size:" + std::to_string(outRange.size()) + ";";
147     for (size_t i = 0; i < outRange.size(); i++) {
148         InfraredFrequencyInfo item;
149         context = context + "index:" + std::to_string(i) + ": per.max:" + std::to_string(outRange[i].max) +
150                   ": per.min:" + std::to_string(outRange[i].min) + ";;";
151         item.max_ = outRange[i].max;
152         item.min_ = outRange[i].min;
153         frequencyInfo.push_back(item);
154     }
155     MMI_HILOGI("Data from hdf:%{public}s", context.c_str());
156     return true;
157 }
158 } // namespace MMI
159 } // namespace OHOS
160 
161