mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Persist the original radio name, and restore it on app start if the radio name is our radio name.
PiperOrigin-RevId: 464148898
This commit is contained in:
committed by
Copybara-Service
parent
0d4964da7b
commit
778c77eacd
@@ -1,3 +1,25 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2022 Niels Lohmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
|
||||
@@ -141,8 +141,8 @@ bool BluetoothClassic::ModifyDeviceName(const std::string& device_name) {
|
||||
if (original_device_name_.empty()) {
|
||||
original_device_name_ = adapter_.GetName();
|
||||
}
|
||||
|
||||
return adapter_.SetName(device_name);
|
||||
return adapter_.SetName(device_name,
|
||||
/* persist= */ false);
|
||||
}
|
||||
|
||||
bool BluetoothClassic::ModifyScanMode(ScanMode scan_mode) {
|
||||
@@ -173,8 +173,8 @@ bool BluetoothClassic::RestoreScanMode() {
|
||||
}
|
||||
|
||||
bool BluetoothClassic::RestoreDeviceName() {
|
||||
if (original_device_name_.empty() ||
|
||||
!adapter_.SetName(original_device_name_)) {
|
||||
if (original_device_name_.empty() || !adapter_.SetName(original_device_name_,
|
||||
/* persis= */ true)) {
|
||||
NEARBY_LOGS(INFO) << "Failed to restore original Bluetooth device name to "
|
||||
<< original_device_name_;
|
||||
return false;
|
||||
@@ -264,8 +264,8 @@ bool BluetoothClassic::StartAcceptingConnections(
|
||||
return false;
|
||||
}
|
||||
|
||||
BluetoothServerSocket socket = medium_.ListenForService(
|
||||
service_id, GenerateUuidFromString(service_id));
|
||||
BluetoothServerSocket socket =
|
||||
medium_.ListenForService(service_id, GenerateUuidFromString(service_id));
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOGS(INFO) << "Failed to start accepting Bluetooth connections for "
|
||||
<< service_id;
|
||||
@@ -309,8 +309,7 @@ bool BluetoothClassic::IsAcceptingConnectionsLocked(
|
||||
return server_sockets_.find(service_id) != server_sockets_.end();
|
||||
}
|
||||
|
||||
bool BluetoothClassic::StopAcceptingConnections(
|
||||
const std::string& service_id) {
|
||||
bool BluetoothClassic::StopAcceptingConnections(const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (service_id.empty()) {
|
||||
@@ -396,9 +395,8 @@ BluetoothSocket BluetoothClassic::AttemptToConnect(
|
||||
return socket;
|
||||
}
|
||||
|
||||
socket = medium_.ConnectToService(bluetooth_device,
|
||||
GenerateUuidFromString(service_id),
|
||||
cancellation_flag);
|
||||
socket = medium_.ConnectToService(
|
||||
bluetooth_device, GenerateUuidFromString(service_id), cancellation_flag);
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOGS(INFO) << "Failed to Connect via BT [service=" << service_id
|
||||
<< "]";
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/file.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/pipe.h"
|
||||
|
||||
namespace location {
|
||||
@@ -46,6 +46,18 @@ TEST(PayloadTest, SupportsByteArrayType) {
|
||||
TEST(PayloadTest, SupportsFileType) {
|
||||
constexpr size_t kOffset = 99;
|
||||
const auto payload_id = Payload::GenerateId();
|
||||
|
||||
char test_file_data[100];
|
||||
memcpy(test_file_data,
|
||||
"012345678901234567890123456789012345678901234567890123456789012345678"
|
||||
"901234567890123456789012345678\0",
|
||||
100);
|
||||
|
||||
OutputFile outputFile(payload_id);
|
||||
ByteArray test_data(test_file_data, 100);
|
||||
outputFile.Write(test_data);
|
||||
outputFile.Close();
|
||||
|
||||
InputFile file(payload_id, 100);
|
||||
InputStream& stream = file.GetInputStream();
|
||||
|
||||
|
||||
@@ -163,7 +163,18 @@ class BluetoothAdapter final {
|
||||
std::string GetMacAddress() const { return impl_->GetMacAddress(); }
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
|
||||
bool SetName(absl::string_view name) { return impl_->SetName(name); }
|
||||
bool SetName(absl::string_view name) {
|
||||
// The name always persists resulting in not saving the current bluetooth
|
||||
// radio name.
|
||||
return impl_->SetName(name,
|
||||
/* persist= */ true);
|
||||
}
|
||||
|
||||
// If persist is set to true, we will not update the stored radio names.
|
||||
// If persist is set to false, we will update the stored radio names.
|
||||
bool SetName(absl::string_view name, bool persist) {
|
||||
return impl_->SetName(name, persist);
|
||||
}
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ constexpr absl::string_view kId = "AB12";
|
||||
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
|
||||
public:
|
||||
explicit BlePeripheralStub(absl::string_view mac_address) {
|
||||
mac_address_ = mac_address;
|
||||
mac_address_ = std::string(mac_address);
|
||||
}
|
||||
|
||||
std::string GetAddress() const override { return mac_address_; }
|
||||
|
||||
@@ -63,6 +63,7 @@ class BluetoothAdapter {
|
||||
virtual std::string GetName() const = 0;
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
|
||||
virtual bool SetName(absl::string_view name) = 0;
|
||||
virtual bool SetName(absl::string_view name, bool persist) = 0;
|
||||
|
||||
// Returns BT MAC address assigned to this adapter.
|
||||
virtual std::string GetMacAddress() const = 0;
|
||||
|
||||
@@ -129,6 +129,12 @@ std::string BluetoothAdapter::GetName() const {
|
||||
}
|
||||
|
||||
bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
return SetName(name,
|
||||
/* persist= */ true);
|
||||
}
|
||||
|
||||
bool BluetoothAdapter::SetName(absl::string_view name,
|
||||
bool persist /*unused*/) {
|
||||
BluetoothAdapter::ScanMode mode;
|
||||
bool enabled;
|
||||
{
|
||||
|
||||
@@ -120,7 +120,9 @@ class BluetoothAdapter : public api::BluetoothAdapter {
|
||||
std::string GetName() const override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
|
||||
bool SetName(absl::string_view name) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool SetName(absl::string_view) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool SetName(absl::string_view name, bool persist) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns BT MAC address assigned to this adapter.
|
||||
std::string GetMacAddress() const override { return mac_address_; }
|
||||
|
||||
@@ -74,7 +74,10 @@ class BluetoothAdapter : public api::BluetoothAdapter {
|
||||
ScanMode GetScanMode() const override { return mode_; }
|
||||
bool SetScanMode(ScanMode mode) override { return false; }
|
||||
std::string GetName() const override { return name_; }
|
||||
bool SetName(absl::string_view name) override {
|
||||
bool SetName(absl::string_view name) {
|
||||
return SetName(name, /* persist= */ true);
|
||||
}
|
||||
bool SetName(absl::string_view name, bool persist) override {
|
||||
name_ = std::string(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ class ImplementationPlatform {
|
||||
|
||||
static std::string GetDownloadPath(std::string& file_name);
|
||||
|
||||
static std::string GetAppDataPath(absl::string_view file_name);
|
||||
|
||||
static OSName GetCurrentOS();
|
||||
|
||||
// Atomics:
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -35,9 +36,11 @@ std::unique_ptr<IOFile> IOFile::CreateInputFile(
|
||||
|
||||
IOFile::IOFile(const absl::string_view file_path, size_t size)
|
||||
: file_(std::string(file_path.data(), file_path.size()),
|
||||
std::ios::binary | std::ios::in),
|
||||
std::ios::binary | std::ios::in | std::ios::ate),
|
||||
path_(file_path),
|
||||
total_size_(size) {}
|
||||
total_size_(file_.tellg()) {
|
||||
file_.seekg(0);
|
||||
}
|
||||
|
||||
std::unique_ptr<IOFile> IOFile::CreateOutputFile(const absl::string_view path) {
|
||||
return std::unique_ptr<IOFile>(new IOFile(path));
|
||||
|
||||
@@ -127,7 +127,7 @@ cc_library(
|
||||
"wifi_lan_socket.cc",
|
||||
"wifi_medium.cc",
|
||||
],
|
||||
copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated"],
|
||||
copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated -Ithird_party/nearby/internal/platform/implementation/windows/json"],
|
||||
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
|
||||
visibility = [
|
||||
"//location/nearby:__subpackages__",
|
||||
@@ -145,6 +145,7 @@ cc_library(
|
||||
"//internal/platform/implementation/shared:count_down_latch",
|
||||
"//internal/platform/implementation/shared:file",
|
||||
"//internal/platform/implementation/windows/generated:types",
|
||||
"//internal/platform/implementation/windows/json:types",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
|
||||
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
|
||||
|
||||
#include <windows.h> // These two headers must be defined
|
||||
#include <winioctl.h> // first and in this order
|
||||
#include <bthdef.h>
|
||||
#include <bthioctl.h>
|
||||
#include <cfgmgr32.h>
|
||||
@@ -25,11 +23,14 @@
|
||||
#include <setupapi.h>
|
||||
#include <stdio.h>
|
||||
#include <usbiodef.h>
|
||||
#include <windows.h> // These two headers must be defined
|
||||
#include <winioctl.h> // first and in this order
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.h"
|
||||
#include "internal/platform/implementation/windows/json/json.hpp"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
@@ -46,6 +47,28 @@ typedef std::basic_string<TCHAR> tstring;
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
struct LocalSettings {
|
||||
std::string original_radio_name;
|
||||
std::string nearby_radio_name;
|
||||
};
|
||||
|
||||
using json = ::nlohmann::json;
|
||||
|
||||
constexpr absl::string_view kLocalSettingsFileName = "settings_file.json";
|
||||
constexpr char kOriginalRadioName[] = "OriginalRadioName";
|
||||
constexpr char kNearbyRadioName[] = "NearbyRadioName";
|
||||
|
||||
void to_json(json &json_output, const LocalSettings &local_settings) {
|
||||
json_output = json{{kOriginalRadioName, local_settings.original_radio_name},
|
||||
{kNearbyRadioName, local_settings.nearby_radio_name}};
|
||||
}
|
||||
|
||||
void from_json(const json &json_input, LocalSettings &local_settings) {
|
||||
json_input.at(kOriginalRadioName).get_to(local_settings.original_radio_name);
|
||||
json_input.at(kNearbyRadioName).get_to(local_settings.nearby_radio_name);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
constexpr uint8_t kAndroidDiscoverableBluetoothNameMaxLength = 37; // bytes
|
||||
|
||||
@@ -144,6 +167,81 @@ bool BluetoothAdapter::SetScanMode(ScanMode scan_mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void BluetoothAdapter::RestoreRadioNameIfNecessary() {
|
||||
std::string nearby_radio_name;
|
||||
std::string current_radio_name = GetName();
|
||||
|
||||
std::string settings_path(kLocalSettingsFileName);
|
||||
|
||||
auto full_path =
|
||||
location::nearby::api::ImplementationPlatform::GetAppDataPath(
|
||||
settings_path);
|
||||
|
||||
auto settings_file =
|
||||
location::nearby::api::ImplementationPlatform::CreateInputFile(full_path,
|
||||
0);
|
||||
if (settings_file == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto total_size = settings_file->GetTotalSize();
|
||||
nearby::ExceptionOr<ByteArray> raw_local_settings;
|
||||
|
||||
raw_local_settings = settings_file->Read(total_size);
|
||||
settings_file->Close();
|
||||
|
||||
if (!raw_local_settings.ok()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto local_settings =
|
||||
json::parse(raw_local_settings.GetResult().data(), nullptr, false);
|
||||
|
||||
if (local_settings.is_discarded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalSettings settings = local_settings.get<LocalSettings>();
|
||||
|
||||
if (current_radio_name == settings.nearby_radio_name) {
|
||||
SetName(settings.original_radio_name,
|
||||
/* persist= */ true);
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothAdapter::StoreRadioNames(absl::string_view original_radio_name,
|
||||
absl::string_view nearby_radio_name) {
|
||||
if (original_radio_name == nullptr || original_radio_name.size() == 0) {
|
||||
return;
|
||||
}
|
||||
if (nearby_radio_name == nullptr || nearby_radio_name.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string settings_path(kLocalSettingsFileName);
|
||||
auto full_path =
|
||||
location::nearby::api::ImplementationPlatform::GetAppDataPath(
|
||||
settings_path);
|
||||
|
||||
auto settings_file =
|
||||
location::nearby::api::ImplementationPlatform::CreateOutputFile(
|
||||
full_path);
|
||||
|
||||
if (settings_file == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalSettings local_settings = {std::string(original_radio_name),
|
||||
std::string(nearby_radio_name)};
|
||||
|
||||
json encoded_local_settings = local_settings;
|
||||
|
||||
ByteArray data(encoded_local_settings.dump());
|
||||
|
||||
settings_file->Write(data);
|
||||
settings_file->Close();
|
||||
}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getName()
|
||||
// Returns an empty string on error
|
||||
std::string BluetoothAdapter::GetName() const {
|
||||
@@ -208,6 +306,14 @@ std::string BluetoothAdapter::GetName() const {
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
|
||||
bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
return SetName(name,
|
||||
/* persist= */ true);
|
||||
}
|
||||
|
||||
bool BluetoothAdapter::SetName(absl::string_view name, bool persist) {
|
||||
if (!persist) {
|
||||
StoreRadioNames(GetName(), name);
|
||||
}
|
||||
if (name.size() > 248 * sizeof(char)) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to set name for bluetooth adapter because "
|
||||
@@ -228,9 +334,9 @@ bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
device_name_ = std::nullopt;
|
||||
|
||||
if (registry_bluetooth_adapter_name_ == name) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< __func__
|
||||
<< ": Tried to set name for bluetooth adapter to the same name again.";
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Tried to set name for bluetooth adapter to the "
|
||||
"same name again.";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -302,8 +408,9 @@ bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
// lpMultiByteStr.
|
||||
NULL, // // Pointer to the character to use if a character cannot be
|
||||
// represented in the specified code page.
|
||||
&defaultCharUsed); // // Pointer to a flag that indicates if the function
|
||||
// has used a default character in the conversion.
|
||||
&defaultCharUsed); // // Pointer to a flag that indicates if the
|
||||
// function has used a default character in the
|
||||
// conversion.
|
||||
|
||||
if (conversionResult == 0) {
|
||||
process_error();
|
||||
@@ -338,16 +445,16 @@ bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
// Creates or opens a file or I/O device.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
|
||||
hDevice = CreateFileA(
|
||||
file_name
|
||||
.c_str(), // The name of the file or device to be created or opened.
|
||||
GENERIC_WRITE, // The requested access to the file or device.
|
||||
0, // The requested sharing mode of the file or device.
|
||||
NULL, // A pointer to a SECURITY_ATTRIBUTES structure.
|
||||
file_name.c_str(), // The name of the file or device to be created or
|
||||
// opened.
|
||||
GENERIC_WRITE, // The requested access to the file or device.
|
||||
0, // The requested sharing mode of the file or device.
|
||||
NULL, // A pointer to a SECURITY_ATTRIBUTES structure.
|
||||
OPEN_EXISTING, // An action to take on a file or device that exists or
|
||||
// does not exist.
|
||||
0, // The file or device attributes and flags.
|
||||
NULL); // A valid handle to a template file with the GENERIC_READ access
|
||||
// right. This parameter can be NULL.
|
||||
NULL); // A valid handle to a template file with the GENERIC_READ
|
||||
// access right. This parameter can be NULL.
|
||||
|
||||
if (hDevice == INVALID_HANDLE_VALUE) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Failed to open device. Error code: "
|
||||
@@ -374,8 +481,8 @@ bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
HKEY_LOCAL_MACHINE, // A handle to an open registry key.
|
||||
local_name_key.c_str(), // The name of the registry subkey to be opened.
|
||||
0L, // Specifies the option to apply when opening the key.
|
||||
KEY_SET_VALUE, // A mask that specifies the desired access rights to the
|
||||
// key to be opened.
|
||||
KEY_SET_VALUE, // A mask that specifies the desired access rights to
|
||||
// the key to be opened.
|
||||
&hKey); // A pointer to a variable that receives a handle to the opened
|
||||
// key.
|
||||
|
||||
@@ -391,7 +498,8 @@ bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexa
|
||||
status = RegSetValueExA(
|
||||
hKey, // A handle to an open registry key
|
||||
BLUETOOTH_RADIO_REGISTRY_NAME_KEY, // The name of the value to be set.
|
||||
BLUETOOTH_RADIO_REGISTRY_NAME_KEY, // The name of the value to be
|
||||
// set.
|
||||
0, // This parameter is reserved and must be zero.
|
||||
REG_BINARY, // The type of data pointed to by the lpData parameter.
|
||||
(LPBYTE)std::string(name).c_str(), // The data to be stored.
|
||||
@@ -436,8 +544,8 @@ bool BluetoothAdapter::SetName(absl::string_view name) {
|
||||
NULL, // A pointer to the output buffer that is to receive the data
|
||||
// returned by the operation.
|
||||
0, // The size of the output buffer, in bytes.
|
||||
&bytes, // A pointer to a variable that receives the size of the data
|
||||
// stored in the output buffer, in bytes.
|
||||
&bytes, // A pointer to a variable that receives the size of the
|
||||
// data stored in the output buffer, in bytes.
|
||||
NULL)) { // A pointer to an OVERLAPPED structure.
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
@@ -520,7 +628,8 @@ char *BluetoothAdapter::GetGenericBluetoothAdapterInstanceID(void) const {
|
||||
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
|
||||
|
||||
// The SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA structure
|
||||
// that specifies a device information element in a device information set.
|
||||
// that specifies a device information element in a device information
|
||||
// set.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdienumdeviceinfo
|
||||
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData)) break;
|
||||
|
||||
@@ -532,8 +641,8 @@ char *BluetoothAdapter::GetGenericBluetoothAdapterInstanceID(void) const {
|
||||
|
||||
if (r != CR_SUCCESS) continue;
|
||||
|
||||
// With Windows, a Bluetooth radio can be packaged as an external dongle or
|
||||
// embedded inside a computer but it must be connected to one of the
|
||||
// With Windows, a Bluetooth radio can be packaged as an external dongle
|
||||
// or embedded inside a computer but it must be connected to one of the
|
||||
// computer's USB ports.
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/bluetooth/bluetooth-host-radio-support
|
||||
if (strncmp("USB", deviceInstanceID, 3) == 0) {
|
||||
|
||||
@@ -75,6 +75,7 @@ class BluetoothAdapter : public api::BluetoothAdapter {
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
|
||||
bool SetName(absl::string_view name) override;
|
||||
bool SetName(absl::string_view name, bool persist) override;
|
||||
|
||||
// Returns BT MAC address assigned to this adapter.
|
||||
std::string GetMacAddress() const override;
|
||||
@@ -94,9 +95,13 @@ class BluetoothAdapter : public api::BluetoothAdapter {
|
||||
// Returns true if the Bluetooth hardware supports Bluetooth 5.0 Extended
|
||||
// Advertising
|
||||
bool IsExtendedAdvertisingSupported() const;
|
||||
void RestoreRadioNameIfNecessary();
|
||||
|
||||
private:
|
||||
void process_error();
|
||||
void StoreRadioNames(absl::string_view original_radio_name,
|
||||
absl::string_view nearby_radio_name);
|
||||
|
||||
WindowsBluetoothAdapter windows_bluetooth_adapter_;
|
||||
std::string registry_bluetooth_adapter_name_;
|
||||
|
||||
|
||||
@@ -26,6 +26,68 @@ namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
|
||||
constexpr absl::string_view kName = "Test Radio Name";
|
||||
constexpr absl::string_view kLongName =
|
||||
"12345678901234567890123456789012345678";
|
||||
constexpr absl::string_view kSpecialCharName = "~!@#$%^&*()_+<>:\"-}[{]";
|
||||
|
||||
TEST(BluetoothAdapter, DISABLED_SetNameSucceeds) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
auto original_name = bluetooth_adapter.GetName();
|
||||
bluetooth_adapter.SetName(kName,
|
||||
/* persist= */ false);
|
||||
|
||||
bluetooth_adapter.RestoreRadioNameIfNecessary();
|
||||
|
||||
EXPECT_EQ(bluetooth_adapter.GetName(), original_name);
|
||||
}
|
||||
|
||||
TEST(BluetoothAdapter, DISABLED_SetNameWithTooManyChars) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
auto original_name = bluetooth_adapter.GetName();
|
||||
bluetooth_adapter.SetName(kLongName,
|
||||
/* persist= */ false);
|
||||
|
||||
auto result = bluetooth_adapter.GetName();
|
||||
bluetooth_adapter.RestoreRadioNameIfNecessary();
|
||||
|
||||
EXPECT_EQ(result, kLongName);
|
||||
EXPECT_EQ(bluetooth_adapter.GetName(), original_name);
|
||||
}
|
||||
|
||||
TEST(BluetoothAdapter, DISABLED_SetNameWithSpecialCharsSucceeds) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
auto original_name = bluetooth_adapter.GetName();
|
||||
bluetooth_adapter.SetName(kSpecialCharName,
|
||||
/* persist= */ false);
|
||||
|
||||
auto result = bluetooth_adapter.GetName();
|
||||
bluetooth_adapter.RestoreRadioNameIfNecessary();
|
||||
|
||||
EXPECT_EQ(result, kSpecialCharName);
|
||||
EXPECT_EQ(bluetooth_adapter.GetName(), original_name);
|
||||
}
|
||||
|
||||
TEST(BluetoothAdapter, DISABLED_SetNameWithEmptyStringSetsOriginalName) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
auto original_name = bluetooth_adapter.GetName();
|
||||
|
||||
bluetooth_adapter.SetName("",
|
||||
/* persist= */ false);
|
||||
|
||||
EXPECT_EQ(bluetooth_adapter.GetName(), original_name);
|
||||
}
|
||||
|
||||
TEST(BluetoothAdapter, DISABLED_SetNameWithNullPtrSetsOriginalName) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
auto original_name = bluetooth_adapter.GetName();
|
||||
|
||||
bluetooth_adapter.SetName(nullptr,
|
||||
/* persist= */ false);
|
||||
|
||||
EXPECT_EQ(bluetooth_adapter.GetName(), original_name);
|
||||
}
|
||||
|
||||
TEST(BluetoothAdapter, DISABLED_SetStatus) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
EXPECT_TRUE(
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <codecvt>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <regex> // NOLINT
|
||||
@@ -50,6 +51,7 @@ BluetoothClassicMedium::BluetoothClassicMedium(
|
||||
api::BluetoothAdapter& bluetoothAdapter)
|
||||
: bluetooth_adapter_(dynamic_cast<BluetoothAdapter&>(bluetoothAdapter)) {
|
||||
InitializeDeviceWatcher();
|
||||
bluetooth_adapter_.RestoreRadioNameIfNecessary();
|
||||
|
||||
bluetooth_adapter_.SetOnScanModeChanged(std::bind(
|
||||
&BluetoothClassicMedium::OnScanModeChanged, this, std::placeholders::_1));
|
||||
|
||||
@@ -33,6 +33,7 @@ cc_library(
|
||||
"setupapi.lib",
|
||||
"dnsapi.lib",
|
||||
"wlanapi.lib",
|
||||
"shlwapi.lib",
|
||||
],
|
||||
textual_hdrs = glob(["**/*.h"]),
|
||||
visibility = [
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "types",
|
||||
textual_hdrs = glob(["**/*.hpp"]),
|
||||
visibility = [
|
||||
"//location/nearby/cpp/sharing/implementation/internal:__subpackages__",
|
||||
"//connections/windows:__subpackages__",
|
||||
"//internal/platform/implementation/windows:__subpackages__",
|
||||
],
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,9 +14,14 @@
|
||||
|
||||
#include "internal/platform/implementation/platform.h"
|
||||
|
||||
#include <PathCch.h>
|
||||
#include <knownfolders.h>
|
||||
#include <psapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
#include <windows.h>
|
||||
#include <winver.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
@@ -154,6 +159,7 @@ std::string CreateOutputFileWithRename(absl::string_view path) {
|
||||
// While we successfully open the file, keep incrementing the count.
|
||||
while (!(file.rdstate() & std::ifstream::failbit)) {
|
||||
file.close();
|
||||
#undef StrCat
|
||||
target = absl::StrCat(folder, file_name1, " (", ++count, ")", file_name2);
|
||||
file.clear();
|
||||
file.open(target, std::fstream::binary | std::fstream::in);
|
||||
@@ -165,6 +171,45 @@ std::string CreateOutputFileWithRename(absl::string_view path) {
|
||||
return target;
|
||||
}
|
||||
|
||||
std::string GetApplicationName(DWORD pid) {
|
||||
HANDLE handle =
|
||||
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
|
||||
pid); // Modify pid to the pid of your application
|
||||
if (!handle) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string szProcessName("", MAX_PATH);
|
||||
DWORD len = MAX_PATH;
|
||||
|
||||
if (NULL != handle) {
|
||||
GetModuleFileNameExA(handle, nullptr, szProcessName.data(), len);
|
||||
}
|
||||
|
||||
szProcessName.resize(szProcessName.find_first_of('\0') + 1);
|
||||
|
||||
auto just_the_file_name_and_ext = szProcessName.substr(
|
||||
szProcessName.find_last_of('\\') + 1,
|
||||
szProcessName.length() - szProcessName.find_last_of('\\') + 1);
|
||||
|
||||
return just_the_file_name_and_ext.substr(
|
||||
0, just_the_file_name_and_ext.find_last_of('.'));
|
||||
}
|
||||
|
||||
bool FolderExists(const std::string& folder_name) {
|
||||
DWORD ftyp = GetFileAttributesA(folder_name.c_str());
|
||||
|
||||
if (ftyp == INVALID_FILE_ATTRIBUTES) {
|
||||
return false; // something is wrong with your path!
|
||||
}
|
||||
|
||||
if (ftyp & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
return true;
|
||||
} // this is a directory!
|
||||
|
||||
return false; // this is not a directory!
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string ImplementationPlatform::GetDownloadPath(std::string& parent_folder,
|
||||
@@ -178,6 +223,44 @@ std::string ImplementationPlatform::GetDownloadPath(std::string& file_name) {
|
||||
return GetDownloadPathInternal(fake_parent_path, file_name);
|
||||
}
|
||||
|
||||
std::string ImplementationPlatform::GetAppDataPath(
|
||||
absl::string_view file_name) {
|
||||
PWSTR basePath;
|
||||
|
||||
// Retrieves the full path of a known folder identified by the folder's
|
||||
// KNOWNFOLDERID.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath
|
||||
SHGetKnownFolderPath(
|
||||
FOLDERID_ProgramData, // rfid: A reference to the KNOWNFOLDERID that
|
||||
// identifies the folder.
|
||||
0, // dwFlags: Flags that specify special retrieval options.
|
||||
NULL, // hToken: An access token that represents a particular user.
|
||||
&basePath); // ppszPath: When this method returns, contains the address
|
||||
// of a pointer to a null-terminated Unicode string that
|
||||
// specifies the path of the known folder. The calling
|
||||
// process is responsible for freeing this resource once it
|
||||
// is no longer needed by calling CoTaskMemFree, whether
|
||||
// SHGetKnownFolderPath succeeds or not.
|
||||
size_t bufferSize;
|
||||
wcstombs_s(&bufferSize, NULL, 0, basePath, 0);
|
||||
std::string fullpathUTF8(bufferSize - 1, '\0');
|
||||
wcstombs_s(&bufferSize, fullpathUTF8.data(), bufferSize, basePath, _TRUNCATE);
|
||||
CoTaskMemFree(basePath);
|
||||
|
||||
// Get the application image name
|
||||
auto app_name = GetApplicationName(GetCurrentProcessId());
|
||||
|
||||
// Check if our folder exists
|
||||
std::replace(fullpathUTF8.begin(), fullpathUTF8.end(), '\\', '/');
|
||||
|
||||
std::stringstream path("");
|
||||
|
||||
path << fullpathUTF8.c_str() << "/" << app_name.c_str() << "/"
|
||||
<< file_name.data();
|
||||
|
||||
return path.str();
|
||||
}
|
||||
|
||||
OSName ImplementationPlatform::GetCurrentOS() { return OSName::kWindows; }
|
||||
|
||||
std::unique_ptr<AtomicBoolean> ImplementationPlatform::CreateAtomicBoolean(
|
||||
@@ -229,6 +312,19 @@ std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
|
||||
|
||||
std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
|
||||
absl::string_view file_path) {
|
||||
std::string path(file_path);
|
||||
|
||||
std::string folder_path = path.substr(0, path.find_last_of('/'));
|
||||
// Verifies that a path is a valid directory.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisdirectorya
|
||||
if (!PathIsDirectoryA(folder_path.data())) {
|
||||
// This function creates a file system folder whose fully qualified path is
|
||||
// given by pszPath. If one or more of the intermediate folders do not
|
||||
// exist, they are created as well.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shcreatedirectoryexa
|
||||
int result = SHCreateDirectoryExA(0, folder_path.data(), nullptr);
|
||||
}
|
||||
|
||||
return shared::IOFile::CreateOutputFile(file_path);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user