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 "bluetooth_dialog.h"
17
18 #include <algorithm>
19 #include <string>
20
21 #include "bluetooth_ability_connection.h"
22 #include "bool_wrapper.h"
23 #include "double_wrapper.h"
24 #include "foundation/ability/ability_runtime/interfaces/inner_api/extension_manager/include/extension_manager_client.h"
25 #include "foundation/ability/ability_runtime/interfaces/kits/native/ability/ability_runtime/ability_connect_callback.h"
26 #include "int_wrapper.h"
27 #include "ipc_skeleton.h"
28 #include "log.h"
29 #include "raw_address.h"
30 #include "string_wrapper.h"
31 #include "want_params_wrapper.h"
32
33 #include "base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter/hitrace_meter.h"
34
35 namespace OHOS {
36 namespace bluetooth {
37 namespace {
38 constexpr int32_t DEFAULT_VALUE = -1;
39 constexpr const char* CALLING_NAME = "com.ohos.settings";
40 constexpr const char* UI_TYPE_KEY = "ability.want.params.uiExtensionType";
41 constexpr const char* UI_TYPE_VAL = "sysdialog/common";
42 constexpr const char* PARAM_DEVICE_ID = "deviceid";
43 constexpr const char* PARAM_DEVICE_NAME = "device";
44
45 const std::map<DialogType, std::string> ABILITY_NAME_MAP = {
46 { PBAP_AUTH_DIALOG, "BluetoothPbapPeSeDialog" },
47 { MAP_AUTH_DIALOG, "BluetoothMapAuthDialog" },
48 { AUTO_PLAY_AUTH_DIALOG, "BluetoothAutoPlayAuthDialog" },
49 };
50
51 std::queue<DialogInfo> g_dialogQueue;
52 std::mutex g_queueMutex;
53 } // namespace
54
RequestAuthDialog(DialogInfo & dialog)55 bool BluetoothDialog::RequestAuthDialog(DialogInfo& dialog)
56 {
57 HILOGI("device: request dialog, type: %{public}d", dialog.type);
58 std::lock_guard<std::mutex> lock(g_queueMutex);
59 if (g_dialogQueue.empty()) {
60 DisplayDialog(dialog);
61 }
62 g_dialogQueue.push(dialog);
63 return true;
64 }
65
DisplayDialog(DialogInfo & dialog)66 bool BluetoothDialog::DisplayDialog(DialogInfo& dialog)
67 {
68 HILOGI("start display dialog, device:, type: %{public}d", dialog.type);
69 auto it = ABILITY_NAME_MAP.find(dialog.type);
70 if (it == ABILITY_NAME_MAP.end()) {
71 HILOGE("dialog ability name not exist.");
72 return false;
73 }
74 std::string abilityName = it->second;
75
76 std::string connectStr = BuildStartCommand(dialog.address);
77 if (!DialogConnectExtension(connectStr, CALLING_NAME, abilityName)) {
78 HILOGE("failed to connect dialog.");
79 return false;
80 }
81
82 HILOGI("success display dialog");
83 if (dialog.timer != nullptr) {
84 HILOGI("start timer");
85 dialog.timer->Start(dialog.timeOutMs);
86 } else {
87 HILOGI("refuse play dialog not need timer");
88 }
89 return true;
90 }
91
DismissCurAndShowNext()92 bool BluetoothDialog::DismissCurAndShowNext()
93 {
94 std::lock_guard<std::mutex> lock(g_queueMutex);
95 if (g_dialogQueue.empty()) {
96 return false;
97 }
98
99 g_dialogQueue.pop();
100
101 if (g_dialogQueue.empty()) {
102 HILOGI("g_dialogQueue is empty, not continue");
103 return false;
104 }
105
106 return DisplayDialog(g_dialogQueue.front());
107 }
108
BuildStartCommand(const std::string & address)109 std::string BluetoothDialog::BuildStartCommand(const std::string& address)
110 {
111 Json::Value root;
112 Json::FastWriter writer;
113
114 RawAddress rawAddr(address);
115 std::string deviceName =
116 "RemoteDeviceProperties::GetInstance()->GetDeviceName(rawAddr)";
117
118 root[UI_TYPE_KEY] = UI_TYPE_VAL;
119 root[PARAM_DEVICE_ID] = address;
120 if (!deviceName.empty()) {
121 root[PARAM_DEVICE_NAME] = deviceName;
122 } else {
123 root[PARAM_DEVICE_NAME] = address;
124 }
125
126 std::string cmdData = writer.write(root);
127 return cmdData;
128 }
129
DialogConnectExtensionAbility(const AAFwk::Want & want,const std::string commandStr,const std::string bundleName,const std::string abilityName)130 bool BluetoothDialog::DialogConnectExtensionAbility(
131 const AAFwk::Want& want, const std::string commandStr, const std::string bundleName, const std::string abilityName)
132 {
133 sptr<BluetoothAbilityConnection> connection_ = sptr<BluetoothAbilityConnection>(
134 new (std::nothrow) BluetoothAbilityConnection(commandStr, bundleName, abilityName));
135 if (connection_ == nullptr) {
136 HILOGE("connection_ is nullptr.");
137 return false;
138 }
139 HILOGI("calling pid is : %{public}d, calling uid is: %{public}d, fullTokenId:xxx",
140 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
141 std::string identity = IPCSkeleton::ResetCallingIdentity();
142 auto ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(
143 want, connection_, nullptr, DEFAULT_VALUE);
144 HILOGI("ret is:%{public}d.", ret);
145 IPCSkeleton::SetCallingIdentity(identity);
146 if (ret != ERR_OK) {
147 HILOGE("ret isn't ERR_OK");
148 return false;
149 }
150 return true;
151 }
152
DialogConnectExtension(const std::string commandStr,const std::string bundleName,const std::string abilityName)153 bool BluetoothDialog::DialogConnectExtension(
154 const std::string commandStr, const std::string bundleName, const std::string abilityName)
155 {
156 AAFwk::Want want;
157 std::string sceneboardName = "com.ohos.systemui";
158 std::string abilityNames = "com.ohos.systemui.dialog";
159 want.SetElementName(sceneboardName, abilityNames);
160 bool ret = DialogConnectExtensionAbility(want, commandStr, bundleName, abilityName);
161 if (!ret) {
162 HILOGE("ConnectExtensionAbility failed.");
163 return false;
164 }
165 HILOGI("ConnectExtensionAbility succeeded.");
166 return true;
167 }
168 } // namespace bluetooth
169 } // namespace OHOS
170