• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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