1 /*
2 * Copyright (C) 2021-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 #include "bluetooth_a2dp_snk.h"
16 #include "bluetooth_errorcode.h"
17 #include "napi_bluetooth_profile.h"
18 #include "napi_bluetooth_a2dp_snk.h"
19 #include "napi_bluetooth_event.h"
20 #include "napi_bluetooth_error.h"
21
22 namespace OHOS {
23 namespace Bluetooth {
24 using namespace std;
25
26 std::shared_ptr<NapiA2dpSinkObserver> NapiA2dpSink::observer_ = std::make_shared<NapiA2dpSinkObserver>();
27 bool NapiA2dpSink::isRegistered_ = false;
28
DefineA2dpSinkJSClass(napi_env env)29 void NapiA2dpSink::DefineA2dpSinkJSClass(napi_env env)
30 {
31 napi_value constructor;
32 napi_property_descriptor properties[] = {
33 DECLARE_NAPI_FUNCTION("on", On),
34 DECLARE_NAPI_FUNCTION("off", Off),
35 DECLARE_NAPI_FUNCTION("getConnectionDevices", GetConnectionDevices),
36 DECLARE_NAPI_FUNCTION("getDeviceState", GetDeviceState),
37 DECLARE_NAPI_FUNCTION("getPlayingState", getPlayingState),
38 DECLARE_NAPI_FUNCTION("connect", Connect),
39 DECLARE_NAPI_FUNCTION("disconnect", Disconnect),
40 };
41
42 napi_define_class(env, "A2dpSink", NAPI_AUTO_LENGTH, A2dpSinkConstructor, nullptr,
43 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
44 napi_value napiProfile;
45 napi_new_instance(env, constructor, 0, nullptr, &napiProfile);
46 NapiProfile::SetProfile(env, ProfileId::PROFILE_A2DP_SINK, napiProfile);
47 }
48
A2dpSinkConstructor(napi_env env, napi_callback_info info)49 napi_value NapiA2dpSink::A2dpSinkConstructor(napi_env env, napi_callback_info info)
50 {
51 napi_value thisVar = nullptr;
52 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
53 return thisVar;
54 }
55
On(napi_env env, napi_callback_info info)56 napi_value NapiA2dpSink::On(napi_env env, napi_callback_info info)
57 {
58 if (observer_) {
59 auto status = observer_->eventSubscribe_.Register(env, info);
60 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
61 }
62 if (!isRegistered_) {
63 A2dpSink *profile = A2dpSink::GetProfile();
64 profile->RegisterObserver(observer_);
65 isRegistered_ = true;
66 }
67 return NapiGetUndefinedRet(env);
68 }
69
Off(napi_env env, napi_callback_info info)70 napi_value NapiA2dpSink::Off(napi_env env, napi_callback_info info)
71 {
72 if (observer_) {
73 auto status = observer_->eventSubscribe_.Deregister(env, info);
74 NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
75 }
76 return NapiGetUndefinedRet(env);
77 }
78
GetConnectionDevices(napi_env env, napi_callback_info info)79 napi_value NapiA2dpSink::GetConnectionDevices(napi_env env, napi_callback_info info)
80 {
81 HILOGI("enter");
82 napi_value ret = nullptr;
83 napi_create_array(env, &ret);
84 A2dpSink *profile = A2dpSink::GetProfile();
85 vector<int> states;
86 states.push_back(1);
87 vector<BluetoothRemoteDevice> devices = profile->GetDevicesByStates(states);
88 vector<string> deviceVector;
89 for (auto &device: devices) {
90 deviceVector.push_back(device.GetDeviceAddr());
91 }
92 ConvertStringVectorToJS(env, ret, deviceVector);
93 return ret;
94 }
95
GetDeviceState(napi_env env, napi_callback_info info)96 napi_value NapiA2dpSink::GetDeviceState(napi_env env, napi_callback_info info)
97 {
98 HILOGI("enter");
99 size_t expectedArgsCount = ARGS_SIZE_ONE;
100 size_t argc = expectedArgsCount;
101 napi_value argv[ARGS_SIZE_ONE] = {0};
102 napi_value thisVar = nullptr;
103
104 napi_value ret = nullptr;
105 napi_get_undefined(env, &ret);
106
107 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
108 if (argc != expectedArgsCount) {
109 HILOGE("Requires 1 argument.");
110 return ret;
111 }
112 string deviceId;
113 if (!ParseString(env, deviceId, argv[PARAM0])) {
114 HILOGE("string expected.");
115 return ret;
116 }
117
118 A2dpSink *profile = A2dpSink::GetProfile();
119 BluetoothRemoteDevice device(deviceId, 1);
120 int state = profile->GetDeviceState(device);
121 napi_value result = nullptr;
122 int status = GetProfileConnectionState(state);
123 napi_create_int32(env, status, &result);
124 HILOGI("status: %{public}d", status);
125 return result;
126 }
127
Connect(napi_env env, napi_callback_info info)128 napi_value NapiA2dpSink::Connect(napi_env env, napi_callback_info info)
129 {
130 HILOGI("enter");
131 size_t expectedArgsCount = ARGS_SIZE_ONE;
132 size_t argc = expectedArgsCount;
133 napi_value argv[ARGS_SIZE_ONE] = {0};
134 napi_value thisVar = nullptr;
135
136 napi_value ret = nullptr;
137 napi_get_undefined(env, &ret);
138
139 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
140 if (argc != expectedArgsCount) {
141 HILOGE("Requires 1 argument.");
142 return ret;
143 }
144 string deviceId;
145 if (!ParseString(env, deviceId, argv[PARAM0])) {
146 HILOGE("string expected.");
147 return ret;
148 }
149
150 A2dpSink *profile = A2dpSink::GetProfile();
151 BluetoothRemoteDevice device(deviceId, 1);
152 bool res = profile->Connect(device);
153
154 napi_value result = nullptr;
155 napi_get_boolean(env, res, &result);
156 HILOGI("res: %{public}d", res);
157 return result;
158 }
159
Disconnect(napi_env env, napi_callback_info info)160 napi_value NapiA2dpSink::Disconnect(napi_env env, napi_callback_info info)
161 {
162 HILOGI("enter");
163 size_t expectedArgsCount = ARGS_SIZE_ONE;
164 size_t argc = expectedArgsCount;
165 napi_value argv[ARGS_SIZE_ONE] = {0};
166 napi_value thisVar = nullptr;
167
168 napi_value ret = nullptr;
169 napi_get_undefined(env, &ret);
170
171 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
172 if (argc != expectedArgsCount) {
173 HILOGE("Requires 1 argument.");
174 return ret;
175 }
176 string deviceId;
177 if (!ParseString(env, deviceId, argv[PARAM0])) {
178 HILOGE("string expected.");
179 return ret;
180 }
181
182 A2dpSink *profile = A2dpSink::GetProfile();
183 BluetoothRemoteDevice device(deviceId, 1);
184 bool res = profile->Disconnect(device);
185
186 napi_value result = nullptr;
187 napi_get_boolean(env, res, &result);
188 HILOGI("res: %{public}d", res);
189 return result;
190 }
191
getPlayingState(napi_env env, napi_callback_info info)192 napi_value NapiA2dpSink::getPlayingState(napi_env env, napi_callback_info info)
193 {
194 HILOGI("enter");
195 size_t expectedArgsCount = ARGS_SIZE_ONE;
196 size_t argc = expectedArgsCount;
197 napi_value argv[ARGS_SIZE_ONE] = {0};
198 napi_value thisVar = nullptr;
199
200 napi_value ret = nullptr;
201 napi_get_undefined(env, &ret);
202
203 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
204 if (argc != expectedArgsCount) {
205 HILOGE("Requires 1 argument.");
206 return ret;
207 }
208 string deviceId;
209 if (!ParseString(env, deviceId, argv[PARAM0])) {
210 HILOGE("string expected.");
211 return ret;
212 }
213
214 A2dpSink *profile = A2dpSink::GetProfile();
215 BluetoothRemoteDevice device(deviceId, 1);
216 int res = profile->GetPlayingState(device);
217
218 napi_value result = nullptr;
219 napi_create_int32(env, res, &result);
220 HILOGI("res: %{public}d", res);
221 return result;
222 }
223
224 } // namespace Bluetooth
225 } // namespace OHOS
226