1 /*
2 * Copyright (C) 2023 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 #include "napi_bluetooth_access_observer.h"
16
17 #include "bluetooth_log.h"
18 #include "bluetooth_utils.h"
19 #include "napi/native_api.h"
20 #include "napi/native_node_api.h"
21
22 #include <uv.h>
23
24 namespace OHOS {
25 namespace Bluetooth {
UvQueueWorkOnStateChanged(uv_work_t * work,BluetoothState & state)26 void NapiBluetoothAccessObserver::UvQueueWorkOnStateChanged(uv_work_t *work, BluetoothState &state)
27 {
28 HILOGI("start");
29
30 if (work == nullptr) {
31 HILOGE("work is null");
32 return;
33 }
34 auto callbackData = (AfterWorkCallbackData<NapiBluetoothAccessObserver,
35 decltype(&NapiBluetoothAccessObserver::UvQueueWorkOnStateChanged),
36 BluetoothState> *)work->data;
37 if (callbackData == nullptr) {
38 HILOGE("callbackData is null");
39 return;
40 }
41
42 napi_value result = 0;
43 napi_value callback = 0;
44 napi_value undefined = 0;
45 napi_value callResult = 0;
46
47 napi_get_undefined(callbackData->env, &undefined);
48 HILOGD("state is %{public}d", state);
49 napi_create_int32(callbackData->env, static_cast<int32_t>(state), &result);
50 napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
51 napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
52 }
53
OnStateChanged(const int transport,const int status)54 void NapiBluetoothAccessObserver::OnStateChanged(const int transport, const int status)
55 {
56 HILOGD("start");
57 BluetoothState state = BluetoothState::STATE_OFF;
58 if (!DealStateChange(transport, status, state)) {
59 return;
60 }
61 if (stateChangeCallback == nullptr) {
62 HILOGI("This callback is not registered by ability.");
63 return;
64 }
65 uv_loop_s *loop = nullptr;
66 napi_get_uv_event_loop(stateChangeCallback->env_, &loop);
67 if (loop == nullptr) {
68 HILOGE("loop instance is nullptr");
69 return;
70 }
71
72 auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothAccessObserver,
73 decltype(&NapiBluetoothAccessObserver::UvQueueWorkOnStateChanged),
74 BluetoothState>();
75 if (callbackData == nullptr) {
76 HILOGE("new callbackData failed");
77 return;
78 }
79
80 callbackData->object = this;
81 callbackData->function = &NapiBluetoothAccessObserver::UvQueueWorkOnStateChanged;
82 callbackData->env = stateChangeCallback->env_;
83 callbackData->callback = stateChangeCallback->callback_;
84 callbackData->data = state;
85
86 uv_work_t *work = new (std::nothrow) uv_work_t;
87 if (work == nullptr) {
88 HILOGE("new work failed");
89 delete callbackData;
90 callbackData = nullptr;
91 return;
92 }
93 work->data = static_cast<void *>(callbackData);
94 int ret = uv_queue_work(
95 loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
96 if (ret != 0) {
97 delete callbackData;
98 callbackData = nullptr;
99 delete work;
100 work = nullptr;
101 }
102 }
103
EnableBt()104 void NapiBluetoothAccessObserver::EnableBt()
105 {
106 HILOGI("start");
107 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
108 int ret = host->EnableBt();
109 if (ret != BT_NO_ERROR) {
110 HILOGE("failed");
111 }
112 SetCurrentAppOperate(false);
113 }
114
DisableBle()115 void NapiBluetoothAccessObserver::DisableBle()
116 {
117 HILOGI("start");
118 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
119 bool enabled = host->DisableBle();
120 if (!enabled) {
121 HILOGE("failed");
122 }
123 SetCurrentAppOperate(false);
124 }
125
DealStateChange(const int transport,const int status,BluetoothState & state)126 bool NapiBluetoothAccessObserver::DealStateChange(const int transport, const int status, BluetoothState &state)
127 {
128 HILOGD("transport is %{public}d, status is %{public}d", transport, status);
129 bool isCallback = true;
130 if (transport == BT_TRANSPORT_BREDR) {
131 GetBrStateByStauts(status, state, isCallback);
132 } else if (transport == BT_TRANSPORT_BLE) {
133 GetBleStateByStauts(status, state);
134 }
135 return isCallback;
136 }
137
GetBrStateByStauts(const int status,BluetoothState & state,bool & isCallback)138 void NapiBluetoothAccessObserver::GetBrStateByStauts(const int status, BluetoothState &state, bool &isCallback)
139 {
140 switch (status) {
141 case BTStateID::STATE_TURNING_ON:
142 HILOGD("STATE_TURNING_ON(1)");
143 state = BluetoothState::STATE_TURNING_ON;
144 break;
145 case BTStateID::STATE_TURN_ON:
146 HILOGD("STATE_ON(2)");
147 state = BluetoothState::STATE_ON;
148 break;
149 case BTStateID::STATE_TURNING_OFF:
150 HILOGD("STATE_TURNING_OFF(3)");
151 state = BluetoothState::STATE_TURNING_OFF;
152 break;
153 case BTStateID::STATE_TURN_OFF: {
154 HILOGD("STATE_OFF(0)");
155 isCallback = false;
156 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
157 if (host->IsBleEnabled() && GetCurrentAppOperate()) {
158 DisableBle();
159 }
160 break;
161 }
162 default:
163 break;
164 }
165 }
166
GetBleStateByStauts(const int status,BluetoothState & state)167 void NapiBluetoothAccessObserver::GetBleStateByStauts(const int status, BluetoothState &state)
168 {
169 switch (status) {
170 case BTStateID::STATE_TURNING_ON:
171 HILOGD("STATE_BLE_TURNING_ON(4)");
172 state = BluetoothState::STATE_BLE_TURNING_ON;
173 break;
174 case BTStateID::STATE_TURN_ON:
175 HILOGD("STATE_BLE_ON(5)");
176 state = BluetoothState::STATE_BLE_ON;
177 if (GetCurrentAppOperate()) {
178 EnableBt();
179 }
180 break;
181 case BTStateID::STATE_TURNING_OFF:
182 HILOGD("STATE_BLE_TURNING_OFF(6)");
183 state = BluetoothState::STATE_BLE_TURNING_OFF;
184 break;
185 case BTStateID::STATE_TURN_OFF:
186 HILOGD("STATE_OFF(0)");
187 state = BluetoothState::STATE_OFF;
188 break;
189 default:
190 break;
191 }
192 }
193 } // namespace Bluetooth
194 } // namespace OHOS
195