• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_src.h"
16 #include "bluetooth_errorcode.h"
17 #include "napi_bluetooth_profile.h"
18 #include "napi_bluetooth_a2dp_src.h"
19 #include "napi_bluetooth_event.h"
20 #include "napi_bluetooth_error.h"
21 #include "napi_bluetooth_host.h"
22 #include "napi_bluetooth_utils.h"
23 
24 namespace OHOS {
25 namespace Bluetooth {
26 using namespace std;
27 
28 NapiA2dpSourceObserver NapiA2dpSource::observer_;
29 bool NapiA2dpSource::isRegistered_ = false;
30 
DefineA2dpSourceJSClass(napi_env env)31 void NapiA2dpSource::DefineA2dpSourceJSClass(napi_env env)
32 {
33     napi_value constructor;
34     napi_property_descriptor properties[] = {
35         DECLARE_NAPI_FUNCTION("on", On),
36         DECLARE_NAPI_FUNCTION("off", Off),
37         DECLARE_NAPI_FUNCTION("getConnectionDevices", GetConnectionDevices),
38         DECLARE_NAPI_FUNCTION("getDeviceState", GetDeviceState),
39         DECLARE_NAPI_FUNCTION("getPlayingState", GetPlayingState),
40         DECLARE_NAPI_FUNCTION("connect", Connect),
41         DECLARE_NAPI_FUNCTION("disconnect", Disconnect),
42     };
43 
44     napi_define_class(env, "A2dpSource", NAPI_AUTO_LENGTH, A2dpSourceConstructor, nullptr,
45         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
46 
47     napi_value napiProfile;
48     napi_new_instance(env, constructor, 0, nullptr, &napiProfile);
49     NapiProfile::SetProfile(env, ProfileId::PROFILE_A2DP_SOURCE, napiProfile);
50     HILOGI("finished");
51 }
52 
A2dpSourceConstructor(napi_env env,napi_callback_info info)53 napi_value NapiA2dpSource::A2dpSourceConstructor(napi_env env, napi_callback_info info)
54 {
55     napi_value thisVar = nullptr;
56     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
57     return thisVar;
58 }
59 
On(napi_env env,napi_callback_info info)60 napi_value NapiA2dpSource::On(napi_env env, napi_callback_info info)
61 {
62     HILOGI("enter");
63     std::unique_lock<std::shared_mutex> guard(NapiA2dpSourceObserver::g_a2dpSrcCallbackInfosMutex);
64 
65     napi_value ret = nullptr;
66     ret = NapiEvent::OnEvent(env, info, observer_.callbackInfos_);
67     if (!isRegistered_) {
68         A2dpSource *profile = A2dpSource::GetProfile();
69         profile->RegisterObserver(&observer_);
70         isRegistered_ = true;
71     }
72     HILOGI("napi A2dpSource is registered");
73     return ret;
74 }
75 
Off(napi_env env,napi_callback_info info)76 napi_value NapiA2dpSource::Off(napi_env env, napi_callback_info info)
77 {
78     HILOGI("enter");
79     std::unique_lock<std::shared_mutex> guard(NapiA2dpSourceObserver::g_a2dpSrcCallbackInfosMutex);
80 
81     napi_value ret = nullptr;
82     ret = NapiEvent::OffEvent(env, info, observer_.callbackInfos_);
83     HILOGI("Napi A2dpSource is unregistered");
84     return ret;
85 }
86 
GetConnectionDevices(napi_env env,napi_callback_info info)87 napi_value NapiA2dpSource::GetConnectionDevices(napi_env env, napi_callback_info info)
88 {
89     HILOGI("enter");
90     napi_value ret = nullptr;
91     napi_create_array(env, &ret);
92     A2dpSource *profile = A2dpSource::GetProfile();
93     vector<int> states;
94     states.push_back(1);
95     vector<BluetoothRemoteDevice> devices = profile->GetDevicesByStates(states);
96     vector<string> deviceVector;
97     for (auto &device: devices) {
98         deviceVector.push_back(device.GetDeviceAddr());
99     }
100     ConvertStringVectorToJS(env, ret, deviceVector);
101     return ret;
102 }
103 
GetDeviceState(napi_env env,napi_callback_info info)104 napi_value NapiA2dpSource::GetDeviceState(napi_env env, napi_callback_info info)
105 {
106     HILOGI("enter");
107 
108     size_t expectedArgsCount = ARGS_SIZE_ONE;
109     size_t argc = expectedArgsCount;
110     napi_value argv[ARGS_SIZE_ONE] = {0};
111     napi_value thisVar = nullptr;
112 
113     napi_value ret = nullptr;
114     napi_get_undefined(env, &ret);
115 
116     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
117     if (argc != expectedArgsCount) {
118         HILOGE("Requires 1 argument.");
119         return ret;
120     }
121     string deviceId;
122     if (!ParseString(env, deviceId, argv[PARAM0])) {
123         HILOGE("string expected.");
124         return ret;
125     }
126 
127     A2dpSource *profile = A2dpSource::GetProfile();
128     BluetoothRemoteDevice device(deviceId, 1);
129     int state = profile->GetDeviceState(device);
130     napi_value result = nullptr;
131     int status = GetProfileConnectionState(state);
132     napi_create_int32(env, status, &result);
133     HILOGI("status: %{public}d", status);
134     return result;
135 }
136 
GetPlayingState(napi_env env,napi_callback_info info)137 napi_value NapiA2dpSource::GetPlayingState(napi_env env, napi_callback_info info)
138 {
139     HILOGI("start");
140     int state = PlayingState::STATE_NOT_PLAYING;
141     napi_value ret = nullptr;
142     napi_create_int32(env, state, &ret);
143 
144     std::string remoteAddr {};
145     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
146     NAPI_BT_ASSERT_RETURN(env, checkRet, BT_ERR_INVALID_PARAM, ret);
147 
148     int transport = GetDeviceTransport(remoteAddr);
149     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
150     A2dpSource *profile = A2dpSource::GetProfile();
151     int32_t res = profile->GetPlayingState(remoteDevice, state);
152     HILOGI("res: %{public}d", res);
153     NAPI_BT_ASSERT_RETURN(env, (res == BT_SUCCESS), res, ret);
154 
155     return NapiGetInt32Ret(env, state);
156 }
157 
Connect(napi_env env,napi_callback_info info)158 napi_value NapiA2dpSource::Connect(napi_env env, napi_callback_info info)
159 {
160     HILOGI("start");
161     std::string remoteAddr {};
162     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
163     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
164 
165     int transport = GetDeviceTransport(remoteAddr);
166     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
167     A2dpSource *profile = A2dpSource::GetProfile();
168     int32_t ret = profile->Connect(remoteDevice);
169     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_SUCCESS, ret);
170 
171     return NapiGetBooleanTrue(env);
172 }
173 
Disconnect(napi_env env,napi_callback_info info)174 napi_value NapiA2dpSource::Disconnect(napi_env env, napi_callback_info info)
175 {
176     HILOGI("start");
177     std::string remoteAddr {};
178     bool checkRet = CheckDeivceIdParam(env, info, remoteAddr);
179     NAPI_BT_ASSERT_RETURN_FALSE(env, checkRet, BT_ERR_INVALID_PARAM);
180 
181     int transport = GetDeviceTransport(remoteAddr);
182     BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transport);
183     A2dpSource *profile = A2dpSource::GetProfile();
184     int32_t ret = profile->Disconnect(remoteDevice);
185     NAPI_BT_ASSERT_RETURN_FALSE(env, ret == BT_SUCCESS, ret);
186 
187     return NapiGetBooleanTrue(env);
188 }
189 } // namespace Bluetooth
190 } // namespace OHOS