removed everything except concurrency primitives

This commit is contained in:
kidfromjupiter
2026-01-16 04:22:18 +00:00
parent 334543c48b
commit ae82c80cf5
70 changed files with 13 additions and 7282 deletions
-6
View File
@@ -10,12 +10,6 @@ bazel_dep(name = "protobuf", version = "32.0", repo_name = "com_google_protobuf"
bazel_dep(name = "googletest", version = "1.17.0", repo_name = "com_google_googletest")
bazel_dep(name = "boringssl", version = "0.0.0-20240126-22d349c")
#bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
#git_override(
# module_name = "hedron_compile_commands",
# remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git",
# commit = "02d15621b528efd877f5d5657c4b738523a0eb17",
# )
git_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
+2 -1
View File
@@ -74,8 +74,9 @@
"https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0",
"https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000",
"https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
"https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.1/MODULE.bazel": "a1c8bb07b5b91d971727c635f449d05623ac9608f6fe4f5f04254ea12f08e349",
"https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.1/source.json": "93f82a5ae985eb935c539bfee95e04767187818189241ac956f3ccadbdb8fb02",
"https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74",
"https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9",
"https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
"https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+3 -156
View File
@@ -1,17 +1,3 @@
# Copyright 2023 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(
@@ -21,100 +7,27 @@ cc_library(
"atomic_reference.h",
"atomic_uint32.h",
"condition_variable.h",
"device_info.h",
"executor.h",
"future.h",
"mutex.h",
"preferences_manager.h",
"preferences_repository.h",
"scheduled_executor.h",
"submittable_executor.h",
"timer.h",
"file.h",
"thread_pool.h",
#"log_message.h",
"utils.h",
"http_loader.h"
],
srcs = [
"device_info.cc",
#"log_message.cc",
"timer.cc",
],
copts = ["-lrt", "-lcurl"],
copts = ["-lrt"],
visibility = ["//visibility:public"],
deps = [
":comm",
"//internal/platform/implementation:types",
"@com_google_absl//absl/strings",
"@sdbus_cpp//:libsystemd",
"@sdbus_cpp//:sdbus_cpp",
# "@sdbus_cpp//:sdbus_cpp",
],
)
cc_library(
name = "comm",
hdrs = [
"dbus.h",
"stream.h",
],
deps = [
":crypto",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:types",
"//internal/platform/implementation/linux/generated:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
"@sdbus_cpp//:libsystemd",
"@sdbus_cpp//:sdbus_cpp",
],
visibility = ["//visibility:private", '//internal/platform/implementation/linux:__subpackages__'],
)
cc_library(
name = "crypto",
srcs = [
"crypto.cc",
],
visibility = ["//visibility:public"],
deps = [
"//internal/platform:base",
"//internal/platform/implementation:types",
"@boringssl//:crypto",
"@com_google_absl//absl/strings",
])
cc_library(
name = "linux",
srcs = [
"dbus.cc",
"executor.cc",
"platform.cc",
"preferences_manager.cc",
"preferences_repository.cc",
"scheduled_executor.cc",
"stream.cc",
"submittable_executor.cc",
"system_clock.cc",
"thread_pool.cc",
"utils.cc",
"file.cc",
"http_loader.cc"
],
linkopts = ["-lcurl"],
visibility = [
"//internal/platform/implementation/linux:__subpackages__",
"//connections:__subpackages__",
@@ -124,8 +37,6 @@ cc_library(
"//third_party/nearby/sharing:__subpackages__",
],
deps = [
":comm",
":crypto", # build_cleaner: keep
":types",
"//internal/flags:nearby_flags",
"//internal/platform:base",
@@ -139,7 +50,6 @@ cc_library(
"//internal/platform/implementation:types",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/shared:file",
"//internal/platform/implementation/linux/generated:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
@@ -154,70 +64,7 @@ cc_library(
"@com_google_absl//absl/types:optional",
"@nlohmann_json//:json",
"@sdbus_cpp//:libsystemd",
"@sdbus_cpp//:sdbus_cpp",
# "@sdbus_cpp//:sdbus_cpp",
],
)
cc_library(
name = "test_utils",
srcs = [
"test_utils.cc",
],
hdrs = [
"test_data.h",
"test_utils.h",
],
visibility = [
"//visibility:private",
"//internal/platform/implementation/linux:__subpackages__"
],
deps = [
"//internal/platform:base",
"@nlohmann_json//:json",
":types",
],
)
cc_test(
name = "impl_test",
size = "small",
srcs = [
"atomic_boolean_test.cc",
"atomic_reference_test.cc",
"mutex_test.cc",
"utils_test.cc",
# "bluetooth_adapter_test.cc",
# "crypto_test.cc",
# "device_info_test.cc",
# "executor_test.cc",
# "file_path_test.cc",
# "http_loader_test.cc",
# "preferences_manager_test.cc",
# "preferences_repository_test.cc",
# "scheduled_executor_test.cc",
# "submittable_executor_test.cc",
# "thread_pool_test.cc",
# "timer_test.cc",
],
tags = ["notap"],
deps = [
":comm",
":crypto",
":test_utils",
":types",
":linux",
"//internal/platform:base",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"//internal/platform/implementation/shared:count_down_latch",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@com_google_googletest//:gtest_main",
"@nlohmann_json//:json",
],
)
@@ -1,17 +1,3 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_ATOMIC_BOOLEAN_H_
#define PLATFORM_IMPL_LINUX_ATOMIC_BOOLEAN_H_
@@ -1,17 +1,3 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_ATOMIC_REFERENCE_H_
#define PLATFORM_IMPL_LINUX_ATOMIC_REFERENCE_H_
@@ -1,17 +1,3 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_ATOMIC_UINT32_H_
#define PLATFORM_IMPL_LINUX_ATOMIC_UINT32_H_
@@ -1,17 +1,3 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_CONDITION_VARIABLE_H_
#define PLATFORM_IMPL_LINUX_CONDITION_VARIABLE_H_
@@ -1,64 +0,0 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_CREDENTIAL_STORAGE_H_
#define PLATFORM_IMPL_LINUX_CREDENTIAL_STORAGE_H_
#include <memory>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/IProxy.h>
#include <sdbus-c++/sdbus-c++.h>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/credential_storage.h"
namespace nearby {
namespace linux {
class CredentialStorage : public api::CredentialStorage {
using LocalCredential = ::nearby::internal::LocalCredential;
using SharedCredential = ::nearby::internal::SharedCredential;
using PublicCredentialType = ::nearby::presence::PublicCredentialType;
using SaveCredentialsResultCallback =
::nearby::presence::SaveCredentialsResultCallback;
using CredentialSelector = ::nearby::presence::CredentialSelector;
using GetLocalCredentialsResultCallback =
::nearby::presence::GetLocalCredentialsResultCallback;
using GetPublicCredentialsResultCallback =
::nearby::presence::GetPublicCredentialsResultCallback;
CredentialStorage(sdbus::IConnection &connection);
~CredentialStorage() override = default;
void SaveCredentials(absl::string_view manager_app_id,
absl::string_view account_name,
const std::vector<LocalCredential> &Local_credentials,
const std::vector<SharedCredential> &Shared_credentials,
PublicCredentialType public_credential_type,
SaveCredentialsResultCallback callback) override;
void UpdateLocalCredential(absl::string_view manager_app_id,
absl::string_view account_name,
nearby::internal::LocalCredential credential,
SaveCredentialsResultCallback callback) override;
void GetPublicCredentials(
const CredentialSelector &credential_selector,
PublicCredentialType public_credential_type,
GetPublicCredentialsResultCallback callback) override;
private:
std::unique_ptr<sdbus::IProxy> proxy;
};
} // namespace linux
} // namespace nearby
#endif
@@ -1,54 +0,0 @@
// Copyright 2020 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.
#include "internal/platform/implementation/crypto.h"
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include <openssl/evp.h>
// Function implementations for platform/implementation/crypto.h.
namespace nearby {
// Initialize global crypto state.
void Crypto::Init() {}
static ByteArray Hash(absl::string_view input, const EVP_MD* algo) {
unsigned int md_out_size = EVP_MAX_MD_SIZE;
uint8_t digest_buffer[EVP_MAX_MD_SIZE];
if (input.empty()) return {};
if (!EVP_Digest(input.data(), input.size(), digest_buffer, &md_out_size, algo,
nullptr))
return {};
return ByteArray{reinterpret_cast<char*>(digest_buffer), md_out_size};
}
// Return MD5 hash of input.
ByteArray Crypto::Md5(absl::string_view input) {
return Hash(input, EVP_md5());
}
// Return SHA256 hash of input.
ByteArray Crypto::Sha256(absl::string_view input) {
return Hash(input, EVP_sha256());
}
} // namespace nearby
@@ -1,47 +0,0 @@
// Copyright 2023 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.
#include <cassert>
#include <cstdlib>
#include <memory>
#include <sdbus-c++/IConnection.h>
#include "absl/base/call_once.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/dbus.h"
namespace nearby {
namespace linux {
namespace {
static absl::Mutex global_system_bus_mutex;
static std::weak_ptr<sdbus::IConnection> global_system_bus_connection
ABSL_GUARDED_BY(global_system_bus_mutex);
} // namespace
std::shared_ptr<sdbus::IConnection> getSystemBusConnection() {
absl::MutexLock lock(&global_system_bus_mutex);
auto bus = global_system_bus_connection.lock();
if (bus == nullptr) {
bus =
std::shared_ptr<sdbus::IConnection>(sdbus::createSystemBusConnection());
bus->enterEventLoopAsync();
global_system_bus_connection = bus;
}
return bus;
}
} // namespace linux
} // namespace nearby
@@ -1,63 +0,0 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_DBUS_H_
#define PLATFORM_IMPL_LINUX_DBUS_H_
#include <sdbus-c++/AdaptorInterfaces.h>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/StandardInterfaces.h>
#include "internal/platform/logging.h"
#define DBUS_LOG_METHOD_CALL_ERROR(p, m, e) \
do { \
LOG(ERROR) << __func__ << ": Got error '" << (e).getName() \
<< "' with message '" << (e).getMessage() \
<< "' while calling " << (m) << " on object " \
<< (p)->getObjectPath(); \
} while (false)
#define DBUS_LOG_PROPERTY_GET_ERROR(p, prop, e) \
do { \
LOG(ERROR) << __func__ << ": Got error '" << (e).getName() \
<< "' with message '" << (e).getMessage() \
<< "' while getting property " << (prop) \
<< " on object " << (p)->getObjectPath(); \
} while (false)
#define DBUS_LOG_PROPERTY_SET_ERROR(p, prop, e) \
do { \
LOG(ERROR) << __func__ << ": Got error '" << (e).getName() \
<< "' with message '" << (e).getMessage() \
<< "' while setting property " << (prop) \
<< " on object " << (p)->getObjectPath(); \
} while (false)
namespace nearby {
namespace linux {
extern std::shared_ptr<sdbus::IConnection> getSystemBusConnection();
class RootObjectManager final
: public sdbus::AdaptorInterfaces<sdbus::ObjectManager_adaptor,
sdbus::Properties_adaptor> {
public:
explicit RootObjectManager(sdbus::IConnection &system_bus, sdbus::ObjectPath path)
: AdaptorInterfaces(system_bus, path) {
registerAdaptor();
}
~RootObjectManager() { unregisterAdaptor(); }
};
} // namespace linux
} // namespace nearby
#endif
@@ -1,164 +0,0 @@
// Copyright 2023 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.
#include <pwd.h>
#include <sys/types.h>
#include <cstdlib>
#include <cstring>
#include <optional>
#include <string>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/IProxy.h>
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/implementation/linux/device_info.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
void CurrentUserSession::RegisterScreenLockedListener(
absl::string_view listener_name,
std::function<void(api::DeviceInfo::ScreenStatus)> callback) {
absl::MutexLock l(&screen_lock_listeners_mutex_);
screen_lock_listeners_[listener_name] = std::move(callback);
}
void CurrentUserSession::UnregisterScreenLockedListener(
absl::string_view listener_name) {
absl::MutexLock l(&screen_lock_listeners_mutex_);
screen_lock_listeners_.erase(listener_name);
}
void CurrentUserSession::onLock() {
absl::ReaderMutexLock l(&screen_lock_listeners_mutex_);
for (auto &[_, callback] : screen_lock_listeners_) {
callback(api::DeviceInfo::ScreenStatus::kLocked);
}
}
void CurrentUserSession::onUnlock() {
absl::ReaderMutexLock l(&screen_lock_listeners_mutex_);
for (auto &[_, callback] : screen_lock_listeners_) {
callback(api::DeviceInfo::ScreenStatus::kUnlocked);
}
}
DeviceInfo::DeviceInfo(std::shared_ptr<sdbus::IConnection> system_bus)
: system_bus_(std::move(system_bus)),
current_user_session_(std::make_unique<CurrentUserSession>(*system_bus_)),
login_manager_(std::make_unique<LoginManager>(*system_bus_)) {}
std::optional<std::string> DeviceInfo::GetOsDeviceName() const {
Hostnamed hostnamed(*system_bus_);
try {
return hostnamed.Hostname();
} catch (const sdbus::Error &e) {
DBUS_LOG_PROPERTY_GET_ERROR(&hostnamed, "GetHostNameFqdn", e);
return std::nullopt;
}
}
api::DeviceInfo::DeviceType DeviceInfo::GetDeviceType() const {
Hostnamed hostnamed(*system_bus_);
try {
std::string chasis = hostnamed.Chassis();
api::DeviceInfo::DeviceType device = api::DeviceInfo::DeviceType::kUnknown;
if (chasis == "phone" || chasis == "handset") {
device = api::DeviceInfo::DeviceType::kPhone;
} else if (chasis == "laptop" || chasis == "desktop") {
device = api::DeviceInfo::DeviceType::kLaptop;
} else if (chasis == "tablet") {
device = api::DeviceInfo::DeviceType::kTablet;
}
return device;
} catch (const sdbus::Error &e) {
DBUS_LOG_PROPERTY_GET_ERROR(&hostnamed, "Chasis", e);
return api::DeviceInfo::DeviceType::kUnknown;
}
}
std::optional<FilePath> DeviceInfo::GetDownloadPath() const {
char *dir = getenv("XDG_DOWNLOAD_DIR");
return FilePath(std::string(dir));
}
std::optional<FilePath> DeviceInfo::GetLocalAppDataPath() const {
char *dir = getenv("XDG_CONFIG_HOME");
if (dir == nullptr) {
return FilePath("/tmp");
}
return FilePath(std::string((std::filesystem::path(std::string(dir)) / "Google Nearby")));
}
std::optional<FilePath> DeviceInfo::GetTemporaryPath() const {
char *dir = getenv("XDG_RUNTIME_PATH");
if (dir == nullptr) {
return FilePath("/tmp");
}
return FilePath(std::string(std::filesystem::path(std::string(dir)) / "Google Nearby"));
}
std::optional<FilePath> DeviceInfo::GetLogPath() const {
char *dir = getenv("XDG_STATE_HOME");
if (dir == nullptr) {
return FilePath("/tmp");
}
return FilePath(std::string(std::filesystem::path(std::string(dir)) / "Google Nearby" / "logs"));
}
std::optional<FilePath> DeviceInfo::GetCrashDumpPath() const {
char *dir = getenv("XDG_STATE_HOME");
if (dir == nullptr) {
return FilePath("/tmp");
}
return FilePath(std::string(std::filesystem::path(std::string(dir)) / "Google Nearby" / "crashes"));
}
bool DeviceInfo::IsScreenLocked() const {
try {
return current_user_session_->LockedHint();
} catch (const sdbus::Error &e) {
DBUS_LOG_PROPERTY_GET_ERROR(current_user_session_, "LockedHint", e);
return false;
}
}
bool DeviceInfo::PreventSleep() {
try {
inhibit_fd_ = login_manager_->Inhibit("sleep", "Google Nearby",
"Google Nearby", "block");
return true;
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(login_manager_, "Inhibit", e);
return false;
}
}
bool DeviceInfo::AllowSleep() {
if (!inhibit_fd_.has_value()) {
LOG(ERROR) << __func__
<< "No inhibit lock is acquired at the moment";
return false;
}
inhibit_fd_.reset();
return true;
}
} // namespace linux
} // namespace nearby
@@ -1,163 +0,0 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_DEVICE_INFO_H_
#define PLATFORM_IMPL_LINUX_DEVICE_INFO_H_
#include <optional>
#include <string>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/IProxy.h>
#include <sdbus-c++/ProxyInterfaces.h>
#include <sdbus-c++/Types.h>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/linux/generated/dbus/hostname/hostname_client.h"
#include "internal/platform/implementation/linux/generated/dbus/login/login_manager_client.h"
#include "internal/platform/implementation/linux/generated/dbus/login/login_session_client.h"
namespace nearby {
namespace linux {
class CurrentUserSession final
: public sdbus::ProxyInterfaces<org::freedesktop::login1::Session_proxy> {
public:
CurrentUserSession(const CurrentUserSession &) = delete;
CurrentUserSession(CurrentUserSession &&) = delete;
CurrentUserSession &operator=(const CurrentUserSession &) = delete;
CurrentUserSession &operator=(CurrentUserSession &&) = delete;
~CurrentUserSession() { unregisterProxy(); }
explicit CurrentUserSession(sdbus::IConnection &system_bus)
: ProxyInterfaces(system_bus, "org.freedesktop.login1",
"/org/freedesktop/login1/session/auto") {
registerProxy();
}
void RegisterScreenLockedListener(
absl::string_view listener_name,
std::function<void(api::DeviceInfo::ScreenStatus)> callback)
ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_);
void UnregisterScreenLockedListener(absl::string_view listener_name)
ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_);
protected:
void onPauseDevice(const uint32_t &major, const uint32_t &minor,
const std::string &type) override {}
void onResumeDevice(const uint32_t &major, const uint32_t &minor,
const sdbus::UnixFd &fd) override {}
void onLock() override ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_);
void onUnlock() override ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_);
private:
absl::Mutex screen_lock_listeners_mutex_;
absl::flat_hash_map<std::string,
std::function<void(api::DeviceInfo::ScreenStatus)>>
screen_lock_listeners_ ABSL_GUARDED_BY(screen_lock_listeners_mutex_);
};
class Hostnamed
: public sdbus::ProxyInterfaces<org::freedesktop::hostname1_proxy> {
public:
Hostnamed(const Hostnamed &) = delete;
Hostnamed(Hostnamed &&) = delete;
Hostnamed &operator=(const Hostnamed &) = delete;
Hostnamed &operator=(Hostnamed &&) = delete;
explicit Hostnamed(sdbus::IConnection &system_bus)
: ProxyInterfaces(system_bus, "org.freedesktop.hostname1",
"/org/freedesktop/hostname1") {
registerProxy();
}
~Hostnamed() { unregisterProxy(); }
};
class LoginManager final
: public sdbus::ProxyInterfaces<org::freedesktop::login1::Manager_proxy> {
public:
LoginManager(const LoginManager &) = delete;
LoginManager(LoginManager &&) = delete;
LoginManager &operator=(const LoginManager &) = delete;
LoginManager &operator=(LoginManager &&) = delete;
explicit LoginManager(sdbus::IConnection &system_bus)
: ProxyInterfaces(system_bus, "org.freedesktop.login1",
"/org/freedesktop/login1") {
registerProxy();
}
~LoginManager() { unregisterProxy(); }
protected:
void onSessionNew(const std::string &session_id,
const sdbus::ObjectPath &object_path) override {}
void onSessionRemoved(const std::string &session_id,
const sdbus::ObjectPath &object_path) override {}
void onUserNew(const uint32_t &uid,
const sdbus::ObjectPath &object_path) override {}
void onUserRemoved(const uint32_t &uid,
const sdbus::ObjectPath &object_path) override {}
void onSeatNew(const std::string &seat_id,
const sdbus::ObjectPath &object_path) override {}
void onSeatRemoved(const std::string &seat_id,
const sdbus::ObjectPath &object_path) override {}
void onPrepareForShutdown(const bool &start) override {}
void onPrepareForSleep(const bool &start) override {}
};
class DeviceInfo final : public api::DeviceInfo {
public:
explicit DeviceInfo(std::shared_ptr<sdbus::IConnection> system_bus);
std::optional<std::string> GetOsDeviceName() const override;
api::DeviceInfo::DeviceType GetDeviceType() const override;
api::DeviceInfo::OsType GetOsType() const override {
return api::DeviceInfo::OsType::kWindows; // Or ChromeOS?
}
std::optional<FilePath> GetDownloadPath() const override;
std::optional<FilePath> GetLocalAppDataPath() const override;
std::optional<FilePath> GetCommonAppDataPath() const override {
return std::nullopt;
};
std::optional<FilePath> GetTemporaryPath() const override;
std::optional<FilePath> GetLogPath() const override;
std::optional<FilePath> GetCrashDumpPath() const override;
bool IsScreenLocked() const override;
void RegisterScreenLockedListener(
absl::string_view listener_name,
std::function<void(api::DeviceInfo::ScreenStatus)> callback) override {
current_user_session_->RegisterScreenLockedListener(listener_name,
std::move(callback));
}
void UnregisterScreenLockedListener(
absl::string_view listener_name) override {
current_user_session_->UnregisterScreenLockedListener(listener_name);
}
bool PreventSleep() override;
bool AllowSleep() override;
private:
std::shared_ptr<sdbus::IConnection> system_bus_;
std::unique_ptr<CurrentUserSession> current_user_session_;
std::unique_ptr<LoginManager> login_manager_;
std::optional<sdbus::UnixFd> inhibit_fd_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_DEVICE_INFO_H_
@@ -1,52 +0,0 @@
// Copyright 2020 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.
#include "internal/platform/implementation/linux/executor.h"
#include <cassert>
#include "internal/platform/implementation/linux/thread_pool.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
Executor::Executor(size_t max_concurrency)
: thread_pool_(std::make_unique<ThreadPool>(max_concurrency)) {
assert(max_concurrency >= 1);
assert(thread_pool_ != nullptr);
}
void Executor::Execute(Runnable &&runnable) {
if (shut_down_) {
LOG(INFO) << "Warning: " << __func__
<< ": Attempt to execute on a shut down pool.";
return;
}
if (runnable == nullptr) {
LOG(ERROR) << __func__ << ": Runnable was null.";
return;
}
thread_pool_->Run(std::move(runnable));
}
void Executor::Shutdown() {
shut_down_ = true;
thread_pool_->ShutDown();
thread_pool_ = nullptr;
}
} // namespace linux
} // namespace nearby
@@ -1,48 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_EXECUTOR_H_
#define PLATFORM_IMPL_LINUX_EXECUTOR_H_
#include <atomic>
#include <memory>
#include "internal/platform/implementation/executor.h"
#include "internal/platform/implementation/linux/thread_pool.h"
namespace nearby {
namespace linux {
// This abstract class is the superclass of all classes representing an
// Executor.
class Executor : public api::Executor {
public:
Executor(size_t max_concurrency = 1);
// Before returning from destructor, executor must wait for all pending
// jobs to finish.
~Executor() override = default;
void Execute(Runnable&& runnable) override;
void Shutdown() override;
private:
std::unique_ptr<linux::ThreadPool> thread_pool_ = nullptr;
std::atomic<bool> shut_down_ = false;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_EXECUTOR_H_
@@ -1,135 +0,0 @@
// Copyright 2020 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.
#include "internal/platform/implementation/linux/file.h"
#include <algorithm>
#include <chrono>
#include <codecvt>
#include <cstddef>
#include <filesystem>
#include <ios>
#include <locale>
#include <memory>
#include <string>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/linux/utils.h"
namespace nearby {
namespace linux {
// InputFile
std::unique_ptr<IOFile> IOFile::CreateInputFile(
const absl::string_view file_path, size_t size) {
return absl::WrapUnique(new IOFile(file_path, size));
}
IOFile::IOFile(const absl::string_view file_path, size_t size)
: path_(file_path) {
file_.open(std::filesystem::path(path_),
std::ios::binary | std::ios::in | std::ios::ate);
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));
}
IOFile::IOFile(const absl::string_view file_path)
: file_(), path_(file_path), total_size_(0) {
file_.open(std::filesystem::path(path_),
std::ios::binary | std::ios::out);
}
ExceptionOr<ByteArray> IOFile::Read(std::int64_t size) {
if (!file_.is_open()) {
return ExceptionOr<ByteArray>{Exception::kIo};
}
if (file_.peek() == EOF) {
return ExceptionOr<ByteArray>{ByteArray{}};
}
if (!file_.good()) {
return ExceptionOr<ByteArray>{Exception::kIo};
}
ByteArray bytes(size);
std::unique_ptr<char[]> read_bytes{new char[size]};
file_.read(read_bytes.get(), static_cast<ptrdiff_t>(size));
auto num_bytes_read = file_.gcount();
if (num_bytes_read == 0) {
return ExceptionOr<ByteArray>{Exception::kIo};
}
return ExceptionOr<ByteArray>(ByteArray(read_bytes.get(), num_bytes_read));
}
Exception IOFile::Close() {
if (file_.is_open()) {
file_.close();
}
return {Exception::kSuccess};
}
absl::Time IOFile::GetLastModifiedTime() const {
std::filesystem::path file_path(path_);
if (!std::filesystem::exists(file_path)) {
return absl::InfinitePast();
}
auto ftime = std::filesystem::last_write_time(file_path);
auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
ftime - std::filesystem::file_time_type::clock::now() +
std::chrono::system_clock::now());
return absl::FromChrono(sctp);
}
void IOFile::SetLastModifiedTime(absl::Time last_modified_time) {
std::filesystem::path file_path(path_);
if (!std::filesystem::exists(file_path)) {
return;
}
auto chrono_time = absl::ToChronoTime(last_modified_time);
auto ftime = std::filesystem::file_time_type::clock::now() +
(chrono_time - std::chrono::system_clock::now());
std::filesystem::last_write_time(file_path, ftime);
}
Exception IOFile::Write(const ByteArray& data) {
if (!file_.is_open()) {
return {Exception::kIo};
}
if (!file_.good()) {
return {Exception::kIo};
}
file_.write(data.data(), data.size());
file_.flush();
return {file_.good() ? Exception::kSuccess : Exception::kIo};
}
Exception IOFile::Flush() {
file_.flush();
return {file_.good() ? Exception::kSuccess : Exception::kIo};
}
} // namespace linux
} // namespace nearby
@@ -1,63 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_FILE_H_
#define PLATFORM_IMPL_LINUX_FILE_H_
#include <cstdint>
#include <fstream>
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/input_file.h"
#include "internal/platform/implementation/output_file.h"
namespace nearby {
namespace linux {
class IOFile final : public api::InputFile, public api::OutputFile {
public:
static std::unique_ptr<IOFile> CreateInputFile(
const absl::string_view file_path, size_t size);
static std::unique_ptr<IOFile> CreateOutputFile(const absl::string_view path);
ExceptionOr<ByteArray> Read(std::int64_t size) override;
std::string GetFilePath() const override { return path_; }
std::int64_t GetTotalSize() const override { return total_size_; }
absl::Time GetLastModifiedTime() const override;
Exception Close() override;
Exception Write(const ByteArray& data) override;
Exception Flush() override;
void SetLastModifiedTime(absl::Time last_modified_time) override;
private:
explicit IOFile(const absl::string_view file_path, size_t size);
explicit IOFile(const absl::string_view file_path);
std::fstream file_;
std::string path_;
std::int64_t total_size_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_FILE_H_
@@ -1,17 +1,3 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_FUTURE_H_
#define PLATFORM_IMPL_LINUX_FUTURE_H_
@@ -1,20 +0,0 @@
# Copyright 2023 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(["**/*.h"]),
visibility = ["//visibility:public"],
)
@@ -1,198 +0,0 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__hostname_client_glue_h__proxy__H__
#define __sdbuscpp__hostname_client_glue_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
class hostname1_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.hostname1";
protected:
hostname1_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
}
~hostname1_proxy() = default;
public:
void SetHostname(const std::string& hostname, const bool& interactive)
{
proxy_.callMethod("SetHostname").onInterface(INTERFACE_NAME).withArguments(hostname, interactive);
}
void SetStaticHostname(const std::string& hostname, const bool& interactive)
{
proxy_.callMethod("SetStaticHostname").onInterface(INTERFACE_NAME).withArguments(hostname, interactive);
}
void SetPrettyHostname(const std::string& hostname, const bool& interactive)
{
proxy_.callMethod("SetPrettyHostname").onInterface(INTERFACE_NAME).withArguments(hostname, interactive);
}
void SetIconName(const std::string& icon, const bool& interactive)
{
proxy_.callMethod("SetIconName").onInterface(INTERFACE_NAME).withArguments(icon, interactive);
}
void SetChassis(const std::string& chassis, const bool& interactive)
{
proxy_.callMethod("SetChassis").onInterface(INTERFACE_NAME).withArguments(chassis, interactive);
}
void SetDeployment(const std::string& deployment, const bool& interactive)
{
proxy_.callMethod("SetDeployment").onInterface(INTERFACE_NAME).withArguments(deployment, interactive);
}
void SetLocation(const std::string& location, const bool& interactive)
{
proxy_.callMethod("SetLocation").onInterface(INTERFACE_NAME).withArguments(location, interactive);
}
std::vector<uint8_t> GetProductUUID(const bool& interactive)
{
std::vector<uint8_t> result;
proxy_.callMethod("GetProductUUID").onInterface(INTERFACE_NAME).withArguments(interactive).storeResultsTo(result);
return result;
}
std::string GetHardwareSerial()
{
std::string result;
proxy_.callMethod("GetHardwareSerial").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string Describe()
{
std::string result;
proxy_.callMethod("Describe").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
public:
std::string Hostname()
{
return proxy_.getProperty("Hostname").onInterface(INTERFACE_NAME);
}
std::string StaticHostname()
{
return proxy_.getProperty("StaticHostname").onInterface(INTERFACE_NAME);
}
std::string PrettyHostname()
{
return proxy_.getProperty("PrettyHostname").onInterface(INTERFACE_NAME);
}
std::string DefaultHostname()
{
return proxy_.getProperty("DefaultHostname").onInterface(INTERFACE_NAME);
}
std::string HostnameSource()
{
return proxy_.getProperty("HostnameSource").onInterface(INTERFACE_NAME);
}
std::string IconName()
{
return proxy_.getProperty("IconName").onInterface(INTERFACE_NAME);
}
std::string Chassis()
{
return proxy_.getProperty("Chassis").onInterface(INTERFACE_NAME);
}
std::string Deployment()
{
return proxy_.getProperty("Deployment").onInterface(INTERFACE_NAME);
}
std::string Location()
{
return proxy_.getProperty("Location").onInterface(INTERFACE_NAME);
}
std::string KernelName()
{
return proxy_.getProperty("KernelName").onInterface(INTERFACE_NAME);
}
std::string KernelRelease()
{
return proxy_.getProperty("KernelRelease").onInterface(INTERFACE_NAME);
}
std::string KernelVersion()
{
return proxy_.getProperty("KernelVersion").onInterface(INTERFACE_NAME);
}
std::string OperatingSystemPrettyName()
{
return proxy_.getProperty("OperatingSystemPrettyName").onInterface(INTERFACE_NAME);
}
std::string OperatingSystemCPEName()
{
return proxy_.getProperty("OperatingSystemCPEName").onInterface(INTERFACE_NAME);
}
uint64_t OperatingSystemSupportEnd()
{
return proxy_.getProperty("OperatingSystemSupportEnd").onInterface(INTERFACE_NAME);
}
std::string HomeURL()
{
return proxy_.getProperty("HomeURL").onInterface(INTERFACE_NAME);
}
std::string HardwareVendor()
{
return proxy_.getProperty("HardwareVendor").onInterface(INTERFACE_NAME);
}
std::string HardwareModel()
{
return proxy_.getProperty("HardwareModel").onInterface(INTERFACE_NAME);
}
std::string FirmwareVersion()
{
return proxy_.getProperty("FirmwareVersion").onInterface(INTERFACE_NAME);
}
std::string FirmwareVendor()
{
return proxy_.getProperty("FirmwareVendor").onInterface(INTERFACE_NAME);
}
uint64_t FirmwareDate()
{
return proxy_.getProperty("FirmwareDate").onInterface(INTERFACE_NAME);
}
private:
sdbus::IProxy& proxy_;
};
}} // namespaces
#endif
@@ -1,86 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.hostname1">
<property name="Hostname" type="s" access="read">
</property>
<property name="StaticHostname" type="s" access="read">
</property>
<property name="PrettyHostname" type="s" access="read">
</property>
<property name="DefaultHostname" type="s" access="read">
</property>
<property name="HostnameSource" type="s" access="read">
</property>
<property name="IconName" type="s" access="read">
</property>
<property name="Chassis" type="s" access="read">
</property>
<property name="Deployment" type="s" access="read">
</property>
<property name="Location" type="s" access="read">
</property>
<property name="KernelName" type="s" access="read">
</property>
<property name="KernelRelease" type="s" access="read">
</property>
<property name="KernelVersion" type="s" access="read">
</property>
<property name="OperatingSystemPrettyName" type="s" access="read">
</property>
<property name="OperatingSystemCPEName" type="s" access="read">
</property>
<property name="OperatingSystemSupportEnd" type="t" access="read">
</property>
<property name="HomeURL" type="s" access="read">
</property>
<property name="HardwareVendor" type="s" access="read">
</property>
<property name="HardwareModel" type="s" access="read">
</property>
<property name="FirmwareVersion" type="s" access="read">
</property>
<property name="FirmwareVendor" type="s" access="read">
</property>
<property name="FirmwareDate" type="t" access="read">
</property>
<method name="SetHostname">
<arg type="s" name="hostname" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SetStaticHostname">
<arg type="s" name="hostname" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SetPrettyHostname">
<arg type="s" name="hostname" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SetIconName">
<arg type="s" name="icon" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SetChassis">
<arg type="s" name="chassis" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SetDeployment">
<arg type="s" name="deployment" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SetLocation">
<arg type="s" name="location" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="GetProductUUID">
<arg type="b" name="interactive" direction="in"/>
<arg type="ay" name="uuid" direction="out"/>
</method>
<method name="GetHardwareSerial">
<arg type="s" name="serial" direction="out"/>
</method>
<method name="Describe">
<arg type="s" name="json" direction="out"/>
</method>
</interface>
</node>
@@ -1,631 +0,0 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__login_manager_client_glue_h__proxy__H__
#define __sdbuscpp__login_manager_client_glue_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
namespace login1 {
class Manager_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.login1.Manager";
protected:
Manager_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("SessionNew").onInterface(INTERFACE_NAME).call([this](const std::string& session_id, const sdbus::ObjectPath& object_path){ this->onSessionNew(session_id, object_path); });
proxy_.uponSignal("SessionRemoved").onInterface(INTERFACE_NAME).call([this](const std::string& session_id, const sdbus::ObjectPath& object_path){ this->onSessionRemoved(session_id, object_path); });
proxy_.uponSignal("UserNew").onInterface(INTERFACE_NAME).call([this](const uint32_t& uid, const sdbus::ObjectPath& object_path){ this->onUserNew(uid, object_path); });
proxy_.uponSignal("UserRemoved").onInterface(INTERFACE_NAME).call([this](const uint32_t& uid, const sdbus::ObjectPath& object_path){ this->onUserRemoved(uid, object_path); });
proxy_.uponSignal("SeatNew").onInterface(INTERFACE_NAME).call([this](const std::string& seat_id, const sdbus::ObjectPath& object_path){ this->onSeatNew(seat_id, object_path); });
proxy_.uponSignal("SeatRemoved").onInterface(INTERFACE_NAME).call([this](const std::string& seat_id, const sdbus::ObjectPath& object_path){ this->onSeatRemoved(seat_id, object_path); });
proxy_.uponSignal("PrepareForShutdown").onInterface(INTERFACE_NAME).call([this](const bool& start){ this->onPrepareForShutdown(start); });
proxy_.uponSignal("PrepareForSleep").onInterface(INTERFACE_NAME).call([this](const bool& start){ this->onPrepareForSleep(start); });
}
~Manager_proxy() = default;
virtual void onSessionNew(const std::string& session_id, const sdbus::ObjectPath& object_path) = 0;
virtual void onSessionRemoved(const std::string& session_id, const sdbus::ObjectPath& object_path) = 0;
virtual void onUserNew(const uint32_t& uid, const sdbus::ObjectPath& object_path) = 0;
virtual void onUserRemoved(const uint32_t& uid, const sdbus::ObjectPath& object_path) = 0;
virtual void onSeatNew(const std::string& seat_id, const sdbus::ObjectPath& object_path) = 0;
virtual void onSeatRemoved(const std::string& seat_id, const sdbus::ObjectPath& object_path) = 0;
virtual void onPrepareForShutdown(const bool& start) = 0;
virtual void onPrepareForSleep(const bool& start) = 0;
public:
sdbus::ObjectPath GetSession(const std::string& session_id)
{
sdbus::ObjectPath result;
proxy_.callMethod("GetSession").onInterface(INTERFACE_NAME).withArguments(session_id).storeResultsTo(result);
return result;
}
sdbus::ObjectPath GetSessionByPID(const uint32_t& pid)
{
sdbus::ObjectPath result;
proxy_.callMethod("GetSessionByPID").onInterface(INTERFACE_NAME).withArguments(pid).storeResultsTo(result);
return result;
}
sdbus::ObjectPath GetUser(const uint32_t& uid)
{
sdbus::ObjectPath result;
proxy_.callMethod("GetUser").onInterface(INTERFACE_NAME).withArguments(uid).storeResultsTo(result);
return result;
}
sdbus::ObjectPath GetUserByPID(const uint32_t& pid)
{
sdbus::ObjectPath result;
proxy_.callMethod("GetUserByPID").onInterface(INTERFACE_NAME).withArguments(pid).storeResultsTo(result);
return result;
}
sdbus::ObjectPath GetSeat(const std::string& seat_id)
{
sdbus::ObjectPath result;
proxy_.callMethod("GetSeat").onInterface(INTERFACE_NAME).withArguments(seat_id).storeResultsTo(result);
return result;
}
std::vector<sdbus::Struct<std::string, uint32_t, std::string, std::string, sdbus::ObjectPath>> ListSessions()
{
std::vector<sdbus::Struct<std::string, uint32_t, std::string, std::string, sdbus::ObjectPath>> result;
proxy_.callMethod("ListSessions").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::vector<sdbus::Struct<uint32_t, std::string, sdbus::ObjectPath>> ListUsers()
{
std::vector<sdbus::Struct<uint32_t, std::string, sdbus::ObjectPath>> result;
proxy_.callMethod("ListUsers").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::vector<sdbus::Struct<std::string, sdbus::ObjectPath>> ListSeats()
{
std::vector<sdbus::Struct<std::string, sdbus::ObjectPath>> result;
proxy_.callMethod("ListSeats").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::vector<sdbus::Struct<std::string, std::string, std::string, std::string, uint32_t, uint32_t>> ListInhibitors()
{
std::vector<sdbus::Struct<std::string, std::string, std::string, std::string, uint32_t, uint32_t>> result;
proxy_.callMethod("ListInhibitors").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::tuple<std::string, sdbus::ObjectPath, std::string, sdbus::UnixFd, uint32_t, std::string, uint32_t, bool> CreateSession(const uint32_t& uid, const uint32_t& pid, const std::string& service, const std::string& type, const std::string& class_, const std::string& desktop, const std::string& seat_id, const uint32_t& vtnr, const std::string& tty, const std::string& display, const bool& remote, const std::string& remote_user, const std::string& remote_host, const std::vector<sdbus::Struct<std::string, sdbus::Variant>>& properties)
{
std::tuple<std::string, sdbus::ObjectPath, std::string, sdbus::UnixFd, uint32_t, std::string, uint32_t, bool> result;
proxy_.callMethod("CreateSession").onInterface(INTERFACE_NAME).withArguments(uid, pid, service, type, class_, desktop, seat_id, vtnr, tty, display, remote, remote_user, remote_host, properties).storeResultsTo(result);
return result;
}
void ReleaseSession(const std::string& session_id)
{
proxy_.callMethod("ReleaseSession").onInterface(INTERFACE_NAME).withArguments(session_id);
}
void ActivateSession(const std::string& session_id)
{
proxy_.callMethod("ActivateSession").onInterface(INTERFACE_NAME).withArguments(session_id);
}
void ActivateSessionOnSeat(const std::string& session_id, const std::string& seat_id)
{
proxy_.callMethod("ActivateSessionOnSeat").onInterface(INTERFACE_NAME).withArguments(session_id, seat_id);
}
void LockSession(const std::string& session_id)
{
proxy_.callMethod("LockSession").onInterface(INTERFACE_NAME).withArguments(session_id);
}
void UnlockSession(const std::string& session_id)
{
proxy_.callMethod("UnlockSession").onInterface(INTERFACE_NAME).withArguments(session_id);
}
void LockSessions()
{
proxy_.callMethod("LockSessions").onInterface(INTERFACE_NAME);
}
void UnlockSessions()
{
proxy_.callMethod("UnlockSessions").onInterface(INTERFACE_NAME);
}
void KillSession(const std::string& session_id, const std::string& who, const int32_t& signal_number)
{
proxy_.callMethod("KillSession").onInterface(INTERFACE_NAME).withArguments(session_id, who, signal_number);
}
void KillUser(const uint32_t& uid, const int32_t& signal_number)
{
proxy_.callMethod("KillUser").onInterface(INTERFACE_NAME).withArguments(uid, signal_number);
}
void TerminateSession(const std::string& session_id)
{
proxy_.callMethod("TerminateSession").onInterface(INTERFACE_NAME).withArguments(session_id);
}
void TerminateUser(const uint32_t& uid)
{
proxy_.callMethod("TerminateUser").onInterface(INTERFACE_NAME).withArguments(uid);
}
void TerminateSeat(const std::string& seat_id)
{
proxy_.callMethod("TerminateSeat").onInterface(INTERFACE_NAME).withArguments(seat_id);
}
void SetUserLinger(const uint32_t& uid, const bool& enable, const bool& interactive)
{
proxy_.callMethod("SetUserLinger").onInterface(INTERFACE_NAME).withArguments(uid, enable, interactive);
}
void AttachDevice(const std::string& seat_id, const std::string& sysfs_path, const bool& interactive)
{
proxy_.callMethod("AttachDevice").onInterface(INTERFACE_NAME).withArguments(seat_id, sysfs_path, interactive);
}
void FlushDevices(const bool& interactive)
{
proxy_.callMethod("FlushDevices").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void PowerOff(const bool& interactive)
{
proxy_.callMethod("PowerOff").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void PowerOffWithFlags(const uint64_t& flags)
{
proxy_.callMethod("PowerOffWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
void Reboot(const bool& interactive)
{
proxy_.callMethod("Reboot").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void RebootWithFlags(const uint64_t& flags)
{
proxy_.callMethod("RebootWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
void Halt(const bool& interactive)
{
proxy_.callMethod("Halt").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void HaltWithFlags(const uint64_t& flags)
{
proxy_.callMethod("HaltWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
void Suspend(const bool& interactive)
{
proxy_.callMethod("Suspend").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void SuspendWithFlags(const uint64_t& flags)
{
proxy_.callMethod("SuspendWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
void Hibernate(const bool& interactive)
{
proxy_.callMethod("Hibernate").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void HibernateWithFlags(const uint64_t& flags)
{
proxy_.callMethod("HibernateWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
void HybridSleep(const bool& interactive)
{
proxy_.callMethod("HybridSleep").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void HybridSleepWithFlags(const uint64_t& flags)
{
proxy_.callMethod("HybridSleepWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
void SuspendThenHibernate(const bool& interactive)
{
proxy_.callMethod("SuspendThenHibernate").onInterface(INTERFACE_NAME).withArguments(interactive);
}
void SuspendThenHibernateWithFlags(const uint64_t& flags)
{
proxy_.callMethod("SuspendThenHibernateWithFlags").onInterface(INTERFACE_NAME).withArguments(flags);
}
std::string CanPowerOff()
{
std::string result;
proxy_.callMethod("CanPowerOff").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string CanReboot()
{
std::string result;
proxy_.callMethod("CanReboot").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string CanHalt()
{
std::string result;
proxy_.callMethod("CanHalt").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string CanSuspend()
{
std::string result;
proxy_.callMethod("CanSuspend").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string CanHibernate()
{
std::string result;
proxy_.callMethod("CanHibernate").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string CanHybridSleep()
{
std::string result;
proxy_.callMethod("CanHybridSleep").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string CanSuspendThenHibernate()
{
std::string result;
proxy_.callMethod("CanSuspendThenHibernate").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void ScheduleShutdown(const std::string& type, const uint64_t& usec)
{
proxy_.callMethod("ScheduleShutdown").onInterface(INTERFACE_NAME).withArguments(type, usec);
}
bool CancelScheduledShutdown()
{
bool result;
proxy_.callMethod("CancelScheduledShutdown").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
sdbus::UnixFd Inhibit(const std::string& what, const std::string& who, const std::string& why, const std::string& mode)
{
sdbus::UnixFd result;
proxy_.callMethod("Inhibit").onInterface(INTERFACE_NAME).withArguments(what, who, why, mode).storeResultsTo(result);
return result;
}
std::string CanRebootParameter()
{
std::string result;
proxy_.callMethod("CanRebootParameter").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void SetRebootParameter(const std::string& parameter)
{
proxy_.callMethod("SetRebootParameter").onInterface(INTERFACE_NAME).withArguments(parameter);
}
std::string CanRebootToFirmwareSetup()
{
std::string result;
proxy_.callMethod("CanRebootToFirmwareSetup").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void SetRebootToFirmwareSetup(const bool& enable)
{
proxy_.callMethod("SetRebootToFirmwareSetup").onInterface(INTERFACE_NAME).withArguments(enable);
}
std::string CanRebootToBootLoaderMenu()
{
std::string result;
proxy_.callMethod("CanRebootToBootLoaderMenu").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void SetRebootToBootLoaderMenu(const uint64_t& timeout)
{
proxy_.callMethod("SetRebootToBootLoaderMenu").onInterface(INTERFACE_NAME).withArguments(timeout);
}
std::string CanRebootToBootLoaderEntry()
{
std::string result;
proxy_.callMethod("CanRebootToBootLoaderEntry").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void SetRebootToBootLoaderEntry(const std::string& boot_loader_entry)
{
proxy_.callMethod("SetRebootToBootLoaderEntry").onInterface(INTERFACE_NAME).withArguments(boot_loader_entry);
}
void SetWallMessage(const std::string& wall_message, const bool& enable)
{
proxy_.callMethod("SetWallMessage").onInterface(INTERFACE_NAME).withArguments(wall_message, enable);
}
public:
bool EnableWallMessages()
{
return proxy_.getProperty("EnableWallMessages").onInterface(INTERFACE_NAME);
}
void EnableWallMessages(const bool& value)
{
proxy_.setProperty("EnableWallMessages").onInterface(INTERFACE_NAME).toValue(value);
}
std::string WallMessage()
{
return proxy_.getProperty("WallMessage").onInterface(INTERFACE_NAME);
}
void WallMessage(const std::string& value)
{
proxy_.setProperty("WallMessage").onInterface(INTERFACE_NAME).toValue(value);
}
uint32_t NAutoVTs()
{
return proxy_.getProperty("NAutoVTs").onInterface(INTERFACE_NAME);
}
std::vector<std::string> KillOnlyUsers()
{
return proxy_.getProperty("KillOnlyUsers").onInterface(INTERFACE_NAME);
}
std::vector<std::string> KillExcludeUsers()
{
return proxy_.getProperty("KillExcludeUsers").onInterface(INTERFACE_NAME);
}
bool KillUserProcesses()
{
return proxy_.getProperty("KillUserProcesses").onInterface(INTERFACE_NAME);
}
std::string RebootParameter()
{
return proxy_.getProperty("RebootParameter").onInterface(INTERFACE_NAME);
}
bool RebootToFirmwareSetup()
{
return proxy_.getProperty("RebootToFirmwareSetup").onInterface(INTERFACE_NAME);
}
uint64_t RebootToBootLoaderMenu()
{
return proxy_.getProperty("RebootToBootLoaderMenu").onInterface(INTERFACE_NAME);
}
std::string RebootToBootLoaderEntry()
{
return proxy_.getProperty("RebootToBootLoaderEntry").onInterface(INTERFACE_NAME);
}
std::vector<std::string> BootLoaderEntries()
{
return proxy_.getProperty("BootLoaderEntries").onInterface(INTERFACE_NAME);
}
bool IdleHint()
{
return proxy_.getProperty("IdleHint").onInterface(INTERFACE_NAME);
}
uint64_t IdleSinceHint()
{
return proxy_.getProperty("IdleSinceHint").onInterface(INTERFACE_NAME);
}
uint64_t IdleSinceHintMonotonic()
{
return proxy_.getProperty("IdleSinceHintMonotonic").onInterface(INTERFACE_NAME);
}
std::string BlockInhibited()
{
return proxy_.getProperty("BlockInhibited").onInterface(INTERFACE_NAME);
}
std::string DelayInhibited()
{
return proxy_.getProperty("DelayInhibited").onInterface(INTERFACE_NAME);
}
uint64_t InhibitDelayMaxUSec()
{
return proxy_.getProperty("InhibitDelayMaxUSec").onInterface(INTERFACE_NAME);
}
uint64_t UserStopDelayUSec()
{
return proxy_.getProperty("UserStopDelayUSec").onInterface(INTERFACE_NAME);
}
std::string HandlePowerKey()
{
return proxy_.getProperty("HandlePowerKey").onInterface(INTERFACE_NAME);
}
std::string HandlePowerKeyLongPress()
{
return proxy_.getProperty("HandlePowerKeyLongPress").onInterface(INTERFACE_NAME);
}
std::string HandleRebootKey()
{
return proxy_.getProperty("HandleRebootKey").onInterface(INTERFACE_NAME);
}
std::string HandleRebootKeyLongPress()
{
return proxy_.getProperty("HandleRebootKeyLongPress").onInterface(INTERFACE_NAME);
}
std::string HandleSuspendKey()
{
return proxy_.getProperty("HandleSuspendKey").onInterface(INTERFACE_NAME);
}
std::string HandleSuspendKeyLongPress()
{
return proxy_.getProperty("HandleSuspendKeyLongPress").onInterface(INTERFACE_NAME);
}
std::string HandleHibernateKey()
{
return proxy_.getProperty("HandleHibernateKey").onInterface(INTERFACE_NAME);
}
std::string HandleHibernateKeyLongPress()
{
return proxy_.getProperty("HandleHibernateKeyLongPress").onInterface(INTERFACE_NAME);
}
std::string HandleLidSwitch()
{
return proxy_.getProperty("HandleLidSwitch").onInterface(INTERFACE_NAME);
}
std::string HandleLidSwitchExternalPower()
{
return proxy_.getProperty("HandleLidSwitchExternalPower").onInterface(INTERFACE_NAME);
}
std::string HandleLidSwitchDocked()
{
return proxy_.getProperty("HandleLidSwitchDocked").onInterface(INTERFACE_NAME);
}
uint64_t HoldoffTimeoutUSec()
{
return proxy_.getProperty("HoldoffTimeoutUSec").onInterface(INTERFACE_NAME);
}
std::string IdleAction()
{
return proxy_.getProperty("IdleAction").onInterface(INTERFACE_NAME);
}
uint64_t IdleActionUSec()
{
return proxy_.getProperty("IdleActionUSec").onInterface(INTERFACE_NAME);
}
bool PreparingForShutdown()
{
return proxy_.getProperty("PreparingForShutdown").onInterface(INTERFACE_NAME);
}
bool PreparingForSleep()
{
return proxy_.getProperty("PreparingForSleep").onInterface(INTERFACE_NAME);
}
sdbus::Struct<std::string, uint64_t> ScheduledShutdown()
{
return proxy_.getProperty("ScheduledShutdown").onInterface(INTERFACE_NAME);
}
bool Docked()
{
return proxy_.getProperty("Docked").onInterface(INTERFACE_NAME);
}
bool LidClosed()
{
return proxy_.getProperty("LidClosed").onInterface(INTERFACE_NAME);
}
bool OnExternalPower()
{
return proxy_.getProperty("OnExternalPower").onInterface(INTERFACE_NAME);
}
bool RemoveIPC()
{
return proxy_.getProperty("RemoveIPC").onInterface(INTERFACE_NAME);
}
uint64_t RuntimeDirectorySize()
{
return proxy_.getProperty("RuntimeDirectorySize").onInterface(INTERFACE_NAME);
}
uint64_t RuntimeDirectoryInodesMax()
{
return proxy_.getProperty("RuntimeDirectoryInodesMax").onInterface(INTERFACE_NAME);
}
uint64_t InhibitorsMax()
{
return proxy_.getProperty("InhibitorsMax").onInterface(INTERFACE_NAME);
}
uint64_t NCurrentInhibitors()
{
return proxy_.getProperty("NCurrentInhibitors").onInterface(INTERFACE_NAME);
}
uint64_t SessionsMax()
{
return proxy_.getProperty("SessionsMax").onInterface(INTERFACE_NAME);
}
uint64_t NCurrentSessions()
{
return proxy_.getProperty("NCurrentSessions").onInterface(INTERFACE_NAME);
}
uint64_t StopIdleSessionUSec()
{
return proxy_.getProperty("StopIdleSessionUSec").onInterface(INTERFACE_NAME);
}
private:
sdbus::IProxy& proxy_;
};
}}} // namespaces
#endif
@@ -1,254 +0,0 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__login_session_client_glue_h__proxy__H__
#define __sdbuscpp__login_session_client_glue_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
namespace login1 {
class Session_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.login1.Session";
protected:
Session_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("PauseDevice").onInterface(INTERFACE_NAME).call([this](const uint32_t& major, const uint32_t& minor, const std::string& type){ this->onPauseDevice(major, minor, type); });
proxy_.uponSignal("ResumeDevice").onInterface(INTERFACE_NAME).call([this](const uint32_t& major, const uint32_t& minor, const sdbus::UnixFd& fd){ this->onResumeDevice(major, minor, fd); });
proxy_.uponSignal("Lock").onInterface(INTERFACE_NAME).call([this](){ this->onLock(); });
proxy_.uponSignal("Unlock").onInterface(INTERFACE_NAME).call([this](){ this->onUnlock(); });
}
~Session_proxy() = default;
virtual void onPauseDevice(const uint32_t& major, const uint32_t& minor, const std::string& type) = 0;
virtual void onResumeDevice(const uint32_t& major, const uint32_t& minor, const sdbus::UnixFd& fd) = 0;
virtual void onLock() = 0;
virtual void onUnlock() = 0;
public:
void Terminate()
{
proxy_.callMethod("Terminate").onInterface(INTERFACE_NAME);
}
void Activate()
{
proxy_.callMethod("Activate").onInterface(INTERFACE_NAME);
}
void Lock()
{
proxy_.callMethod("Lock").onInterface(INTERFACE_NAME);
}
void Unlock()
{
proxy_.callMethod("Unlock").onInterface(INTERFACE_NAME);
}
void SetIdleHint(const bool& idle)
{
proxy_.callMethod("SetIdleHint").onInterface(INTERFACE_NAME).withArguments(idle);
}
void SetLockedHint(const bool& locked)
{
proxy_.callMethod("SetLockedHint").onInterface(INTERFACE_NAME).withArguments(locked);
}
void Kill(const std::string& who, const int32_t& signal_number)
{
proxy_.callMethod("Kill").onInterface(INTERFACE_NAME).withArguments(who, signal_number);
}
void TakeControl(const bool& force)
{
proxy_.callMethod("TakeControl").onInterface(INTERFACE_NAME).withArguments(force);
}
void ReleaseControl()
{
proxy_.callMethod("ReleaseControl").onInterface(INTERFACE_NAME);
}
void SetType(const std::string& type)
{
proxy_.callMethod("SetType").onInterface(INTERFACE_NAME).withArguments(type);
}
void SetDisplay(const std::string& display)
{
proxy_.callMethod("SetDisplay").onInterface(INTERFACE_NAME).withArguments(display);
}
void SetTTY(const sdbus::UnixFd& tty_fd)
{
proxy_.callMethod("SetTTY").onInterface(INTERFACE_NAME).withArguments(tty_fd);
}
std::tuple<sdbus::UnixFd, bool> TakeDevice(const uint32_t& major, const uint32_t& minor)
{
std::tuple<sdbus::UnixFd, bool> result;
proxy_.callMethod("TakeDevice").onInterface(INTERFACE_NAME).withArguments(major, minor).storeResultsTo(result);
return result;
}
void ReleaseDevice(const uint32_t& major, const uint32_t& minor)
{
proxy_.callMethod("ReleaseDevice").onInterface(INTERFACE_NAME).withArguments(major, minor);
}
void PauseDeviceComplete(const uint32_t& major, const uint32_t& minor)
{
proxy_.callMethod("PauseDeviceComplete").onInterface(INTERFACE_NAME).withArguments(major, minor);
}
void SetBrightness(const std::string& subsystem, const std::string& name, const uint32_t& brightness)
{
proxy_.callMethod("SetBrightness").onInterface(INTERFACE_NAME).withArguments(subsystem, name, brightness);
}
public:
std::string Id()
{
return proxy_.getProperty("Id").onInterface(INTERFACE_NAME);
}
sdbus::Struct<uint32_t, sdbus::ObjectPath> User()
{
return proxy_.getProperty("User").onInterface(INTERFACE_NAME);
}
std::string Name()
{
return proxy_.getProperty("Name").onInterface(INTERFACE_NAME);
}
uint64_t Timestamp()
{
return proxy_.getProperty("Timestamp").onInterface(INTERFACE_NAME);
}
uint64_t TimestampMonotonic()
{
return proxy_.getProperty("TimestampMonotonic").onInterface(INTERFACE_NAME);
}
uint32_t VTNr()
{
return proxy_.getProperty("VTNr").onInterface(INTERFACE_NAME);
}
sdbus::Struct<std::string, sdbus::ObjectPath> Seat()
{
return proxy_.getProperty("Seat").onInterface(INTERFACE_NAME);
}
std::string TTY()
{
return proxy_.getProperty("TTY").onInterface(INTERFACE_NAME);
}
std::string Display()
{
return proxy_.getProperty("Display").onInterface(INTERFACE_NAME);
}
bool Remote()
{
return proxy_.getProperty("Remote").onInterface(INTERFACE_NAME);
}
std::string RemoteHost()
{
return proxy_.getProperty("RemoteHost").onInterface(INTERFACE_NAME);
}
std::string RemoteUser()
{
return proxy_.getProperty("RemoteUser").onInterface(INTERFACE_NAME);
}
std::string Service()
{
return proxy_.getProperty("Service").onInterface(INTERFACE_NAME);
}
std::string Desktop()
{
return proxy_.getProperty("Desktop").onInterface(INTERFACE_NAME);
}
std::string Scope()
{
return proxy_.getProperty("Scope").onInterface(INTERFACE_NAME);
}
uint32_t Leader()
{
return proxy_.getProperty("Leader").onInterface(INTERFACE_NAME);
}
uint32_t Audit()
{
return proxy_.getProperty("Audit").onInterface(INTERFACE_NAME);
}
std::string Type()
{
return proxy_.getProperty("Type").onInterface(INTERFACE_NAME);
}
std::string Class()
{
return proxy_.getProperty("Class").onInterface(INTERFACE_NAME);
}
bool Active()
{
return proxy_.getProperty("Active").onInterface(INTERFACE_NAME);
}
std::string State()
{
return proxy_.getProperty("State").onInterface(INTERFACE_NAME);
}
bool IdleHint()
{
return proxy_.getProperty("IdleHint").onInterface(INTERFACE_NAME);
}
uint64_t IdleSinceHint()
{
return proxy_.getProperty("IdleSinceHint").onInterface(INTERFACE_NAME);
}
uint64_t IdleSinceHintMonotonic()
{
return proxy_.getProperty("IdleSinceHintMonotonic").onInterface(INTERFACE_NAME);
}
bool LockedHint()
{
return proxy_.getProperty("LockedHint").onInterface(INTERFACE_NAME);
}
private:
sdbus::IProxy& proxy_;
};
}}} // namespaces
#endif
@@ -1,388 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Manager">
<property name="EnableWallMessages" type="b" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</property>
<property name="WallMessage" type="s" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</property>
<property name="NAutoVTs" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="KillOnlyUsers" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="KillExcludeUsers" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="KillUserProcesses" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="RebootParameter" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="RebootToFirmwareSetup" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="RebootToBootLoaderMenu" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="RebootToBootLoaderEntry" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="BootLoaderEntries" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="IdleHint" type="b" access="read">
</property>
<property name="IdleSinceHint" type="t" access="read">
</property>
<property name="IdleSinceHintMonotonic" type="t" access="read">
</property>
<property name="BlockInhibited" type="s" access="read">
</property>
<property name="DelayInhibited" type="s" access="read">
</property>
<property name="InhibitDelayMaxUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="UserStopDelayUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandlePowerKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandlePowerKeyLongPress" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleRebootKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleRebootKeyLongPress" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleSuspendKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleSuspendKeyLongPress" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleHibernateKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleHibernateKeyLongPress" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleLidSwitch" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleLidSwitchExternalPower" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleLidSwitchDocked" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HoldoffTimeoutUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="IdleAction" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="IdleActionUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="PreparingForShutdown" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="PreparingForSleep" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="ScheduledShutdown" type="(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="Docked" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="LidClosed" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="OnExternalPower" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="RemoveIPC" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="RuntimeDirectorySize" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="RuntimeDirectoryInodesMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="InhibitorsMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="NCurrentInhibitors" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="SessionsMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="NCurrentSessions" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="StopIdleSessionUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<method name="GetSession">
<arg type="s" name="session_id" direction="in"/>
<arg type="o" name="object_path" direction="out"/>
</method>
<method name="GetSessionByPID">
<arg type="u" name="pid" direction="in"/>
<arg type="o" name="object_path" direction="out"/>
</method>
<method name="GetUser">
<arg type="u" name="uid" direction="in"/>
<arg type="o" name="object_path" direction="out"/>
</method>
<method name="GetUserByPID">
<arg type="u" name="pid" direction="in"/>
<arg type="o" name="object_path" direction="out"/>
</method>
<method name="GetSeat">
<arg type="s" name="seat_id" direction="in"/>
<arg type="o" name="object_path" direction="out"/>
</method>
<method name="ListSessions">
<arg type="a(susso)" name="sessions" direction="out"/>
</method>
<method name="ListUsers">
<arg type="a(uso)" name="users" direction="out"/>
</method>
<method name="ListSeats">
<arg type="a(so)" name="seats" direction="out"/>
</method>
<method name="ListInhibitors">
<arg type="a(ssssuu)" name="inhibitors" direction="out"/>
</method>
<method name="CreateSession">
<arg type="u" name="uid" direction="in"/>
<arg type="u" name="pid" direction="in"/>
<arg type="s" name="service" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="class" direction="in"/>
<arg type="s" name="desktop" direction="in"/>
<arg type="s" name="seat_id" direction="in"/>
<arg type="u" name="vtnr" direction="in"/>
<arg type="s" name="tty" direction="in"/>
<arg type="s" name="display" direction="in"/>
<arg type="b" name="remote" direction="in"/>
<arg type="s" name="remote_user" direction="in"/>
<arg type="s" name="remote_host" direction="in"/>
<arg type="a(sv)" name="properties" direction="in"/>
<arg type="s" name="session_id" direction="out"/>
<arg type="o" name="object_path" direction="out"/>
<arg type="s" name="runtime_path" direction="out"/>
<arg type="h" name="fifo_fd" direction="out"/>
<arg type="u" name="uid" direction="out"/>
<arg type="s" name="seat_id" direction="out"/>
<arg type="u" name="vtnr" direction="out"/>
<arg type="b" name="existing" direction="out"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="ReleaseSession">
<arg type="s" name="session_id" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="ActivateSession">
<arg type="s" name="session_id" direction="in"/>
</method>
<method name="ActivateSessionOnSeat">
<arg type="s" name="session_id" direction="in"/>
<arg type="s" name="seat_id" direction="in"/>
</method>
<method name="LockSession">
<arg type="s" name="session_id" direction="in"/>
</method>
<method name="UnlockSession">
<arg type="s" name="session_id" direction="in"/>
</method>
<method name="LockSessions">
</method>
<method name="UnlockSessions">
</method>
<method name="KillSession">
<arg type="s" name="session_id" direction="in"/>
<arg type="s" name="who" direction="in"/>
<arg type="i" name="signal_number" direction="in"/>
</method>
<method name="KillUser">
<arg type="u" name="uid" direction="in"/>
<arg type="i" name="signal_number" direction="in"/>
</method>
<method name="TerminateSession">
<arg type="s" name="session_id" direction="in"/>
</method>
<method name="TerminateUser">
<arg type="u" name="uid" direction="in"/>
</method>
<method name="TerminateSeat">
<arg type="s" name="seat_id" direction="in"/>
</method>
<method name="SetUserLinger">
<arg type="u" name="uid" direction="in"/>
<arg type="b" name="enable" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="AttachDevice">
<arg type="s" name="seat_id" direction="in"/>
<arg type="s" name="sysfs_path" direction="in"/>
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="FlushDevices">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="PowerOff">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="PowerOffWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="Reboot">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="RebootWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="Halt">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="HaltWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="Suspend">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SuspendWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="Hibernate">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="HibernateWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="HybridSleep">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="HybridSleepWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="SuspendThenHibernate">
<arg type="b" name="interactive" direction="in"/>
</method>
<method name="SuspendThenHibernateWithFlags">
<arg type="t" name="flags" direction="in"/>
</method>
<method name="CanPowerOff">
<arg type="s" name="result" direction="out"/>
</method>
<method name="CanReboot">
<arg type="s" name="result" direction="out"/>
</method>
<method name="CanHalt">
<arg type="s" name="result" direction="out"/>
</method>
<method name="CanSuspend">
<arg type="s" name="result" direction="out"/>
</method>
<method name="CanHibernate">
<arg type="s" name="result" direction="out"/>
</method>
<method name="CanHybridSleep">
<arg type="s" name="result" direction="out"/>
</method>
<method name="CanSuspendThenHibernate">
<arg type="s" name="result" direction="out"/>
</method>
<method name="ScheduleShutdown">
<arg type="s" name="type" direction="in"/>
<arg type="t" name="usec" direction="in"/>
</method>
<method name="CancelScheduledShutdown">
<arg type="b" name="cancelled" direction="out"/>
</method>
<method name="Inhibit">
<arg type="s" name="what" direction="in"/>
<arg type="s" name="who" direction="in"/>
<arg type="s" name="why" direction="in"/>
<arg type="s" name="mode" direction="in"/>
<arg type="h" name="pipe_fd" direction="out"/>
</method>
<method name="CanRebootParameter">
<arg type="s" name="result" direction="out"/>
</method>
<method name="SetRebootParameter">
<arg type="s" name="parameter" direction="in"/>
</method>
<method name="CanRebootToFirmwareSetup">
<arg type="s" name="result" direction="out"/>
</method>
<method name="SetRebootToFirmwareSetup">
<arg type="b" name="enable" direction="in"/>
</method>
<method name="CanRebootToBootLoaderMenu">
<arg type="s" name="result" direction="out"/>
</method>
<method name="SetRebootToBootLoaderMenu">
<arg type="t" name="timeout" direction="in"/>
</method>
<method name="CanRebootToBootLoaderEntry">
<arg type="s" name="result" direction="out"/>
</method>
<method name="SetRebootToBootLoaderEntry">
<arg type="s" name="boot_loader_entry" direction="in"/>
</method>
<method name="SetWallMessage">
<arg type="s" name="wall_message" direction="in"/>
<arg type="b" name="enable" direction="in"/>
</method>
<signal name="SessionNew">
<arg type="s" name="session_id"/>
<arg type="o" name="object_path"/>
</signal>
<signal name="SessionRemoved">
<arg type="s" name="session_id"/>
<arg type="o" name="object_path"/>
</signal>
<signal name="UserNew">
<arg type="u" name="uid"/>
<arg type="o" name="object_path"/>
</signal>
<signal name="UserRemoved">
<arg type="u" name="uid"/>
<arg type="o" name="object_path"/>
</signal>
<signal name="SeatNew">
<arg type="s" name="seat_id"/>
<arg type="o" name="object_path"/>
</signal>
<signal name="SeatRemoved">
<arg type="s" name="seat_id"/>
<arg type="o" name="object_path"/>
</signal>
<signal name="PrepareForShutdown">
<arg type="b" name="start"/>
</signal>
<signal name="PrepareForSleep">
<arg type="b" name="start"/>
</signal>
</interface>
<node name="seat"/>
<node name="session"/>
<node name="user"/>
</node>
@@ -1,121 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Session">
<property name="Id" type="s" access="read">
</property>
<property name="User" type="(uo)" access="read">
</property>
<property name="Name" type="s" access="read">
</property>
<property name="Timestamp" type="t" access="read">
</property>
<property name="TimestampMonotonic" type="t" access="read">
</property>
<property name="VTNr" type="u" access="read">
</property>
<property name="Seat" type="(so)" access="read">
</property>
<property name="TTY" type="s" access="read">
</property>
<property name="Display" type="s" access="read">
</property>
<property name="Remote" type="b" access="read">
</property>
<property name="RemoteHost" type="s" access="read">
</property>
<property name="RemoteUser" type="s" access="read">
</property>
<property name="Service" type="s" access="read">
</property>
<property name="Desktop" type="s" access="read">
</property>
<property name="Scope" type="s" access="read">
</property>
<property name="Leader" type="u" access="read">
</property>
<property name="Audit" type="u" access="read">
</property>
<property name="Type" type="s" access="read">
</property>
<property name="Class" type="s" access="read">
</property>
<property name="Active" type="b" access="read">
</property>
<property name="State" type="s" access="read">
</property>
<property name="IdleHint" type="b" access="read">
</property>
<property name="IdleSinceHint" type="t" access="read">
</property>
<property name="IdleSinceHintMonotonic" type="t" access="read">
</property>
<property name="LockedHint" type="b" access="read">
</property>
<method name="Terminate">
</method>
<method name="Activate">
</method>
<method name="Lock">
</method>
<method name="Unlock">
</method>
<method name="SetIdleHint">
<arg type="b" name="idle" direction="in"/>
</method>
<method name="SetLockedHint">
<arg type="b" name="locked" direction="in"/>
</method>
<method name="Kill">
<arg type="s" name="who" direction="in"/>
<arg type="i" name="signal_number" direction="in"/>
</method>
<method name="TakeControl">
<arg type="b" name="force" direction="in"/>
</method>
<method name="ReleaseControl">
</method>
<method name="SetType">
<arg type="s" name="type" direction="in"/>
</method>
<method name="SetDisplay">
<arg type="s" name="display" direction="in"/>
</method>
<method name="SetTTY">
<arg type="h" name="tty_fd" direction="in"/>
</method>
<method name="TakeDevice">
<arg type="u" name="major" direction="in"/>
<arg type="u" name="minor" direction="in"/>
<arg type="h" name="fd" direction="out"/>
<arg type="b" name="inactive" direction="out"/>
</method>
<method name="ReleaseDevice">
<arg type="u" name="major" direction="in"/>
<arg type="u" name="minor" direction="in"/>
</method>
<method name="PauseDeviceComplete">
<arg type="u" name="major" direction="in"/>
<arg type="u" name="minor" direction="in"/>
</method>
<method name="SetBrightness">
<arg type="s" name="subsystem" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="u" name="brightness" direction="in"/>
</method>
<signal name="PauseDevice">
<arg type="u" name="major"/>
<arg type="u" name="minor"/>
<arg type="s" name="type"/>
</signal>
<signal name="ResumeDevice">
<arg type="u" name="major"/>
<arg type="u" name="minor"/>
<arg type="h" name="fd"/>
</signal>
<signal name="Lock">
</signal>
<signal name="Unlock">
</signal>
</interface>
</node>
@@ -1,573 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/linux/http_loader.h"
#include <iostream>
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
namespace {
constexpr int32_t kSchemaMaximumLength = 10;
constexpr int32_t kHostNameMaximumLength = 256;
using ::nearby::api::WebResponse;
} // namespace
HttpLoader::HttpLoader(const nearby::api::WebRequest &request)
: request_(request),
header_data_(open_memstream(&header_strings_, &header_sizeloc_)),
our_header_data_(nullptr),
response_data_(open_memstream(&response_strings_, &response_sizeloc_)),
curl_(curl_easy_init()) {}
HttpLoader::~HttpLoader() { DisconnectWebServer(); }
absl::StatusOr<WebResponse> HttpLoader::GetResponse() {
absl::Status status;
status = ParseUrl();
if (!status.ok()) {
return status;
}
status = ConnectWebServer();
if (!status.ok()) {
return status;
}
// Sends request to web server.
status = SendRequest();
if (!status.ok()) {
return status;
}
// Processes response from web server
absl::StatusOr<WebResponse> result = ProcessResponse();
if (!result.ok()) {
return result;
}
DisconnectWebServer();
return result;
}
absl::StatusOr<int> HttpLoader::QueryStatusCode(CURL *file_handle) {
long status_code;
absl::Status status;
status = QueryResponseInfo(file_handle, CURLINFO_RESPONSE_CODE, &status_code);
if (!status.ok()) {
return status;
}
if (status_code < 0) {
return absl::InternalError("Invalid status code.");
}
return status_code;
}
absl::StatusOr<std::string> HttpLoader::QueryStatusText(CURL *request_handle) {
absl::StatusOr<int> status;
std::string status_text;
status = QueryStatusCode(request_handle);
if (!status.ok()) {
return status.status();
}
switch (status.value()) {
case 100:
return "Continue";
case 101:
return "Switching Protocols";
case 102:
return "Processing";
case 103:
return "Early Hints";
case 200:
return "OK";
case 201:
return "Created";
case 202:
return "Accepted";
case 203:
return "Non-Authoritative Information";
case 204:
return "No Content";
case 205:
return "Reset Content";
case 206:
return "Partial Content";
case 207:
return "Multi-Status";
case 208:
return "Already Reported";
case 226:
return "IM Used";
case 300:
return "Multiple Choices";
case 301:
return "Moved Permanently";
case 302:
return "Found";
case 303:
return "See Other";
case 304:
return "Not Modified";
case 305:
return "Use Proxy";
case 307:
return "Temporary Redirect";
case 308:
return "Permanent Redirect";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 402:
return "Payment Required";
case 403:
return "Forbidden";
case 404:
return "Not Found";
case 405:
return "Method Not Allowed";
case 406:
return "Not Acceptable";
case 407:
return "Proxy Authentication Required";
case 408:
return "Request Timeout";
case 409:
return "Conflict";
case 410:
return "Gone";
case 411:
return "Lenth Required";
case 412:
return "Precondition Failed";
case 413:
return "Payload Too Large";
case 414:
return "URI Too Long";
case 415:
return "Unsupported Media Type";
case 416:
return "Range Not Satisfiable";
case 417:
return "Expectation Failed";
case 418:
return "I'm a teapot!";
case 421:
return "Misdirected Request";
case 422:
return "Unprocessable Content";
case 423:
return "Locked";
case 424:
return "Failed Dependency";
case 425:
return "Too Early";
case 426:
return "Upgrade Required";
case 428:
return "Precondition Required";
case 429:
return "Too Many Requests";
case 431:
return "Request Header Fields Too Large";
case 451:
return "Unavailable For Legal Reasons";
case 500:
return "Internal Server Error";
case 501:
return "Not Implemented";
case 502:
return "Bad Gateway";
case 503:
return "Service Unavailable";
case 504:
return "Gateway Timeout";
case 505:
return "HTTP Version Not Supported";
case 506:
return "Variant Also Negotiates";
case 507:
return "Insufficient Storage";
case 508:
return "Loop Detected";
case 509:
return "Network Authentication Required";
default:
return absl::InternalError("Invalid status code.");
}
}
absl::StatusOr<std::multimap<std::string, std::string>>
HttpLoader::QueryResponseHeaders(CURL *request_handle) {
absl::Status status;
long header_size;
status = QueryResponseInfo(curl_, CURLINFO_HEADER_SIZE, &header_size);
if (!status.ok()) {
return status;
}
std::string headers_string(header_strings_, header_size);
std::multimap<std::string, std::string> headers;
// Parse headers in response
size_t start = 0;
size_t pos = 0;
while ((pos = headers_string.find("\r\n", start)) != std::string::npos) {
std::string header = headers_string.substr(start, pos - start);
// Get key and value in header
size_t split_pos = 0;
if ((split_pos = header.find(": ")) != std::string::npos) {
std::string key = header.substr(0, split_pos);
std::string value = header.substr(split_pos + 2);
headers.emplace(key, value);
}
start = pos + 2;
}
return headers;
}
const nearby::api::WebRequest &HttpLoader::GetRequest() { return request_; }
size_t HttpLoader::CurlReadCallback(char *buffer, size_t size, size_t nitems,
void *userdata) {
size_t write_size_max = size * nitems;
size_t write_amount = 0;
for (const auto &str :
reinterpret_cast<HttpLoader *>(userdata)->GetRequest().body) {
if (write_amount == write_size_max) {
break;
}
*(buffer + write_amount) = str;
write_amount++;
}
return write_amount;
}
// This function uses the CURL getinfo function to grab info. Each info_level
// has a different type it can return. It would not be feasable to determine the
// type and return it. IT IS UP TO THE CALLER OF THE FUNCTION TO USE THE void*
// CORRECTLY.
absl::Status HttpLoader::QueryResponseInfo(CURL *request_handle,
CURLINFO info_level, void *info) {
CURLcode query_result = curl_easy_getinfo(request_handle, info_level, &info);
if (query_result == CURLE_OK) {
return absl::OkStatus();
}
return absl::InvalidArgumentError(
"Failed to query HTTP information: " +
std::string(curl_easy_strerror(query_result)));
}
absl::Status HttpLoader::ParseUrl() {
CURLU *url_components = curl_url();
char *schema;
char *host_name;
char *path;
CURLUcode ret = curl_url_set(url_components, CURLUPART_URL,
request_.url.c_str(), CURLU_NON_SUPPORT_SCHEME);
if (ret) {
curl_url_cleanup(url_components);
curl_free(schema);
curl_free(host_name);
curl_free(path);
url_components = nullptr;
schema = nullptr;
host_name = nullptr;
path = nullptr;
return absl::InvalidArgumentError("Invalid URL format: " +
std::string(curl_url_strerror(ret)));
}
ret = curl_url_get(url_components, CURLUPART_SCHEME, &schema,
CURLU_URLDECODE | CURLU_URLENCODE | CURLU_DEFAULT_PORT |
CURLU_DEFAULT_SCHEME);
if (ret) {
curl_url_cleanup(url_components);
curl_free(schema);
curl_free(host_name);
curl_free(path);
url_components = nullptr;
schema = nullptr;
host_name = nullptr;
path = nullptr;
return absl::InvalidArgumentError("Could not parse URL schema: " +
std::string(curl_url_strerror(ret)));
}
ret = curl_url_get(url_components, CURLUPART_PATH, &path,
CURLU_URLDECODE | CURLU_URLENCODE | CURLU_DEFAULT_PORT |
CURLU_DEFAULT_SCHEME);
if (ret) {
curl_url_cleanup(url_components);
curl_free(schema);
curl_free(host_name);
curl_free(path);
url_components = nullptr;
schema = nullptr;
host_name = nullptr;
path = nullptr;
return absl::InvalidArgumentError("Could not parse URL path: " +
std::string(curl_url_strerror(ret)));
}
if (!(schema_ == "http" || schema_ == "https")) {
curl_url_cleanup(url_components);
curl_free(schema);
curl_free(host_name);
curl_free(path);
url_components = nullptr;
schema = nullptr;
host_name = nullptr;
path = nullptr;
return absl::InvalidArgumentError("URL supports HTTP and HTTPS only.");
}
host_ = host_name;
schema_ = schema;
path_ = path;
if (schema_ == "https") {
is_secure_ = true;
}
curl_url_cleanup(url_components);
curl_free(schema);
curl_free(host_name);
curl_free(path);
url_components = nullptr;
schema = nullptr;
host_name = nullptr;
path = nullptr;
return absl::OkStatus();
}
absl::Status HttpLoader::ConnectWebServer() {
std::vector<CURLcode> option_return_codes;
if (curl_) {
curl_ = curl_easy_init();
header_data_ = open_memstream(&header_strings_, &header_sizeloc_);
response_data_ = open_memstream(&response_strings_, &response_sizeloc_);
}
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_NOPROGRESS, 1L));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_URL, request_.url.c_str()));
option_return_codes.push_back(curl_easy_setopt(curl_, CURLOPT_PORT, port_));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_AUTOREFERER, 1L));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_FOLLOWLOCATION, 1L));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_USERAGENT, "Mozilla/5.0"));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_HEADERDATA, header_data_));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_WRITEDATA, response_data_));
// Prepare headers
std::string request_headers;
for (const auto &header : request_.headers) {
struct curl_slist *list = curl_slist_append(
our_header_data_,
std::string(header.first + ": " + header.second).c_str());
if (list) {
our_header_data_ = list;
}
}
if (!request_headers.empty()) {
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, our_header_data_));
}
if (request_.method == "GET") {
option_return_codes.push_back(curl_easy_setopt(curl_, CURLOPT_HTTPGET, 1L));
} else if (request_.method == "POST") {
option_return_codes.push_back(curl_easy_setopt(
curl_, CURLOPT_POSTFIELDSIZE, static_cast<long>(request_.body.size())));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, request_.body.c_str()));
} else if (request_.method == "PUT") {
option_return_codes.push_back(curl_easy_setopt(curl_, CURLOPT_UPLOAD, 1L));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_READFUNCTION, CurlReadCallback));
option_return_codes.push_back(
curl_easy_setopt(curl_, CURLOPT_READDATA, this));
option_return_codes.push_back(curl_easy_setopt(
curl_,
(request_.body.size() < std::numeric_limits<long>::max()
? CURLOPT_INFILESIZE
: CURLOPT_INFILESIZE_LARGE),
request_.body.size()));
} else {
LOG(ERROR) << "Failed to open internet with error "
<< "Invalid request method: " << request_.method << ".";
return absl::FailedPreconditionError(
"Failed to open internet: Invalid request method.");
}
for (const auto &ret : option_return_codes) {
if (ret) {
LOG(ERROR) << "Failed to open internet with error "
<< curl_easy_strerror(ret) << ".";
return absl::FailedPreconditionError(
absl::StrCat(curl_easy_strerror(ret)));
}
}
return absl::OkStatus();
}
absl::Status HttpLoader::SendRequest() {
CURLcode ret = curl_easy_perform(curl_);
if (ret != CURLE_OK) {
LOG(ERROR)
<< "Failed to send request to remote web server with error "
<< curl_easy_strerror(ret) << ".";
return absl::FailedPreconditionError(absl::StrCat(curl_easy_strerror(ret)));
}
return absl::OkStatus();
}
absl::StatusOr<WebResponse> HttpLoader::ProcessResponse() {
absl::Status status;
WebResponse web_response;
auto status_code = QueryStatusCode(curl_);
if (!status_code.ok()) {
return absl::InternalError("Failed to read HTTP status");
}
web_response.status_code = status_code.value();
auto status_text = QueryStatusText(curl_);
if (!status_text.ok()) {
return absl::InternalError("Failed to read HTTP status");
}
web_response.status_text = status_text.value();
auto headers = QueryResponseHeaders(curl_);
if (!headers.ok()) {
headers.status();
}
web_response.headers = *headers;
curl_off_t download_size;
CURLcode ret =
curl_easy_getinfo(curl_, CURLINFO_SIZE_DOWNLOAD_T, &download_size);
if (ret) {
if (download_size != 0) {
// Append data to response
web_response.body.assign(response_strings_, download_size);
} else {
LOG(ERROR)
<< "Failed to read response from remote web server with error "
<< curl_easy_strerror(ret) << ".";
return absl::FailedPreconditionError(
absl::StrCat(curl_easy_strerror(ret)));
}
}
status = HTTPCodeToStatus(web_response.status_code, web_response.status_text);
if (!status.ok()) {
return status;
}
return web_response;
}
void HttpLoader::DisconnectWebServer() {
fclose(header_data_);
header_data_ = nullptr;
delete header_strings_;
header_strings_ = nullptr;
curl_easy_cleanup(curl_);
curl_ = nullptr;
curl_slist_free_all(our_header_data_);
our_header_data_ = nullptr;
fclose(response_data_);
response_data_ = nullptr;
delete response_strings_;
response_strings_ = nullptr;
}
absl::Status HttpLoader::HTTPCodeToStatus(int status_code,
absl::string_view status_message) {
switch (status_code) {
case 400:
return absl::InvalidArgumentError(status_message);
case 401:
return absl::UnauthenticatedError(status_message);
case 403:
return absl::PermissionDeniedError(status_message);
case 404:
return absl::NotFoundError(status_message);
case 409:
return absl::AbortedError(status_message);
case 416:
return absl::OutOfRangeError(status_message);
case 429:
return absl::ResourceExhaustedError(status_message);
case 499:
return absl::CancelledError(status_message);
case 504:
return absl::DeadlineExceededError(status_message);
case 501:
return absl::UnimplementedError(status_message);
case 503:
return absl::UnavailableError(status_message);
default:
break;
}
if (status_code >= 200 && status_code < 300) {
return absl::OkStatus();
} else if (status_code >= 400 && status_code < 500) {
return absl::FailedPreconditionError(status_message);
} else if (status_code >= 500 && status_code < 600) {
return absl::InternalError(status_message);
}
return absl::UnknownError(status_message);
}
} // namespace linux
} // namespace nearby
@@ -1,91 +0,0 @@
// 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.
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_LINUX_HTTP_LOADER_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_LINUX_HTTP_LOADER_H_
#include <curl/curl.h>
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/http_loader.h"
namespace nearby {
namespace linux {
// HttpLoader is used to get HTTP response from remote server.
//
// HttpLoader gets HTTP request information from caller, and calling Windows
// WinInet APIs to get HTTP response. The platform handles HTTP/HTTPS sessions.
class HttpLoader {
public:
explicit HttpLoader(const nearby::api::WebRequest &request);
~HttpLoader();
absl::StatusOr<nearby::api::WebResponse> GetResponse();
const nearby::api::WebRequest &GetRequest();
private:
// Defines the buffer size. It is used to init a buffer for receiving HTTP
// response. The unit is byte.
static constexpr int kReceiveBufferSize = 8 * 1024;
static size_t CurlReadCallback(char *buffer, size_t size, size_t nitems,
void *userdata);
absl::Status ConnectWebServer();
absl::Status SendRequest();
absl::StatusOr<nearby::api::WebResponse> ProcessResponse();
void DisconnectWebServer();
absl::StatusOr<int> QueryStatusCode(CURL *file_handle);
absl::StatusOr<std::string> QueryStatusText(CURL *request_handle);
absl::StatusOr<std::multimap<std::string, std::string>> QueryResponseHeaders(
CURL *request_handle);
absl::Status QueryResponseInfo(CURL *request_handle, CURLINFO info_level,
void *info);
absl::Status ParseUrl();
// Converts HTTP status code to absl Status.
//
// @param status_code HTTP status code, such 200, 404 etc.
// @param status_message short description of the status code.
// @return converted absl status.
absl::Status HTTPCodeToStatus(int status_code,
absl::string_view status_message);
nearby::api::WebRequest request_;
std::string host_;
std::string path_;
std::string schema_;
bool is_secure_ = false;
int port_ = 80;
FILE *header_data_;
char *header_strings_;
size_t header_sizeloc_;
struct curl_slist *our_header_data_;
FILE *response_data_;
char *response_strings_;
size_t response_sizeloc_;
CURL *curl_;
};
} // namespace linux
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_LINUX_HTTP_LOADER_H_
@@ -1,48 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_INPUT_FILE_H_
#define PLATFORM_IMPL_LINUX_INPUT_FILE_H_
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/input_file.h"
namespace nearby {
namespace linux {
// An InputFile represents a readable file on the system.
class InputFile : public api::InputFile {
public:
// TODO(b/184975123): replace with real implementation.
~InputFile() override = default;
// TODO(b/184975123): replace with real implementation.
std::string GetFilePath() const override { return "Un-implemented"; }
// TODO(b/184975123): replace with real implementation.
std::int64_t GetTotalSize() const override { return 0; }
// throws Exception::kIo
// TODO(b/184975123): replace with real implementation.
ExceptionOr<ByteArray> Read(std::int64_t size) override {
return ExceptionOr<ByteArray>(Exception::kFailed);
}
// throws Exception::kIo
// TODO(b/184975123): replace with real implementation.
Exception Close() override { return Exception{}; }
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_INPUT_FILE_H_
@@ -1,83 +0,0 @@
// Copyright 2023 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.
#include <sys/syslog.h>
#include <cassert>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <memory>
#define SD_JOURNAL_SUPPRESS_LOCATION true
#include <systemd/sd-journal.h>
#include "absl/base/call_once.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/implementation/linux/log_message.h"
namespace nearby {
namespace linux {
std::atomic<api::LogMessage::Severity> min_log_severity_ =
api::LogMessage::Severity::kInfo;
inline google::LogSeverity ConvertSeverity(api::LogMessage::Severity severity) {
switch (severity) {
case api::LogMessage::Severity::kWarning:
return google::GLOG_WARNING;
case api::LogMessage::Severity::kError:
return google::GLOG_ERROR;
case api::LogMessage::Severity::kFatal:
return google::GLOG_FATAL;
case api::LogMessage::Severity::kVerbose:
case api::LogMessage::Severity::kInfo:
default:
return google::GLOG_INFO;
}
}
LogMessage::LogMessage(const char *file, int line, Severity severity)
: log_streamer_(file, line, ConvertSeverity(severity)) {}
void LogMessage::Print(const char *format, ...) {
char *buf = nullptr;
va_list ap;
va_start(ap, format);
auto ret = vasprintf(&buf, format, ap);
if (ret > 0) {
log_streamer_.stream() << std::string(buf, ret);
}
if (buf != nullptr) free(buf);
va_end(ap);
}
std::ostream &LogMessage::Stream() { return log_streamer_.stream(); }
} // namespace linux
namespace api {
void LogMessage::SetMinLogSeverity(Severity severity) {
linux::min_log_severity_ = severity;
}
bool LogMessage::ShouldCreateLogMessage(Severity severity) {
return severity >= linux::min_log_severity_;
}
} // namespace api
} // namespace nearby
@@ -1,45 +0,0 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_LOG_MESSAGE_H_
#define PLATFORM_IMPL_LINUX_LOG_MESSAGE_H_
#include <sdbus-c++/AdaptorInterfaces.h>
#include <sdbus-c++/IConnection.h>
#include <atomic>
#include "glog/logging.h"
#include "internal/platform/implementation/log_message.h"
namespace nearby {
namespace linux {
// See documentation in
// cpp/platform/api/log_message.h
class LogMessage : public api::LogMessage {
public:
LogMessage(const char *file, int line, Severity severity);
~LogMessage() override{};
void Print(const char *format, ...) override;
std::ostream &Stream() override;
private:
google::LogMessage log_streamer_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_LOG_MESSAGE_H_
@@ -1,17 +1,3 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_MUTEX_H_
#define PLATFORM_IMPL_LINUX_MUTEX_H_
@@ -1,45 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_OUTPUT_FILE_H_
#define PLATFORM_IMPL_LINUX_OUTPUT_FILE_H_
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/output_file.h"
namespace nearby {
namespace linux {
// An OutputFile represents a writable file on the system.
class OutputFile : public api::OutputFile {
public:
// TODO(b/184975123): replace with real implementation.
~OutputFile() override = default;
// throws Exception::kIo
// TODO(b/184975123): replace with real implementation.
Exception Write(const ByteArray& data) override { return Exception{}; }
// throws Exception::kIo
// TODO(b/184975123): replace with real implementation.
Exception Flush() override { return Exception{}; }
// throws Exception::kIo
// TODO(b/184975123): replace with real implementation.
Exception Close() override { return Exception{}; }
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_OUTPUT_FILE_H_
@@ -1,26 +1,10 @@
// Copyright 2023 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.
#include <filesystem>
#include <memory>
#include <string>
#include <curl/curl.h>
#include <sdbus-c++/Error.h>
#include <sdbus-c++/Types.h>
#include "device_info.h"
#include "internal/platform/implementation/atomic_boolean.h"
#include "internal/platform/implementation/atomic_reference.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
@@ -29,16 +13,8 @@
#include "internal/platform/implementation/input_file.h"
#include "internal/platform/implementation/linux/atomic_boolean.h"
#include "internal/platform/implementation/linux/atomic_uint32.h"
//#include "internal/platform/implementation/linux/ble_v2_medium.h"
#include "internal/platform/implementation/linux/condition_variable.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/implementation/linux/mutex.h"
#include "internal/platform/implementation/linux/preferences_manager.h"
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/linux/timer.h"
// #include "internal/platform/implementation/linux/wifi_direct.h"
// #include "internal/platform/implementation/linux/wifi_hotspot.h"
// #include "internal/platform/implementation/linux/wifi_medium.h"
#include "internal/platform/implementation/platform.h"
#include "absl/strings/str_cat.h"
@@ -49,8 +25,7 @@
#include "internal/platform/implementation/wifi_hotspot.h"
#include "internal/platform/implementation/wifi_lan.h"
#include "internal/platform/payload_id.h"
#include "scheduled_executor.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace api {
std::string ImplementationPlatform::GetCustomSavePath(
@@ -189,18 +164,18 @@ std::unique_ptr<api::LogMessage> ImplementationPlatform::CreateLogMessage(
std::unique_ptr<api::SubmittableExecutor>
ImplementationPlatform::CreateSingleThreadExecutor() {
return std::make_unique<linux::SubmittableExecutor>();
return nullptr;
}
std::unique_ptr<api::SubmittableExecutor>
ImplementationPlatform::CreateMultiThreadExecutor(
std::int32_t max_concurrency) {
return std::make_unique<linux::SubmittableExecutor>(max_concurrency);
return nullptr;
}
std::unique_ptr<ScheduledExecutor>
ImplementationPlatform::CreateScheduledExecutor() {
return std::make_unique<linux::ScheduledExecutor>();
return nullptr;
}
std::unique_ptr<api::BluetoothAdapter>
@@ -244,11 +219,11 @@ ImplementationPlatform::CreateWifiDirectMedium() {
}
std::unique_ptr<api::Timer> ImplementationPlatform::CreateTimer() {
return std::make_unique<linux::Timer>();
return nullptr;
}
std::unique_ptr<api::DeviceInfo> ImplementationPlatform::CreateDeviceInfo() {
return std::make_unique<linux::DeviceInfo>(linux::getSystemBusConnection());
return nullptr;
}
std::unique_ptr<AwdlMedium> ImplementationPlatform::CreateAwdlMedium() {
@@ -257,77 +232,13 @@ std::unique_ptr<api::DeviceInfo> ImplementationPlatform::CreateDeviceInfo() {
absl::StatusOr<api::WebResponse> ImplementationPlatform::SendRequest(
const WebRequest &request) {
if (request.body.size() >= (8 * 1024 * 1024)) {
return absl::Status(absl::StatusCode::kResourceExhausted,
"request body too large");
}
CURL *handle = curl_easy_init();
char errbuf[CURL_ERROR_SIZE];
errbuf[0] = '\0';
curl_easy_setopt(handle, CURLOPT_URL, request.url.c_str());
curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf);
if (request.method == "GET")
curl_easy_setopt(handle, CURLOPT_HTTPGET, 1L);
else if (request.method == "POST")
curl_easy_setopt(handle, CURLOPT_POST, 1L);
else
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, request.method.c_str());
curl_easy_setopt(handle, CURLOPT_UPLOAD, request.body.c_str());
struct curl_slist *headers_slist = nullptr;
for (auto &[key, value] : request.headers) {
auto hdr = absl::StrCat(key, ": ", value);
auto temp = curl_slist_append(headers_slist, hdr.c_str());
if (temp == nullptr) {
if (headers_slist != nullptr) {
curl_slist_free_all(headers_slist);
}
return absl::Status(absl::StatusCode::kResourceExhausted,
"failed to append header to slist");
}
}
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers_slist);
api::WebResponse response;
if (curl_easy_perform(handle) != CURLE_OK) {
LOG(ERROR) << __func__
<< ": Error performing HTTP request: " << errbuf;
return absl::Status(absl::StatusCode::kUnknown, errbuf);
}
struct curl_header *prev = nullptr;
struct curl_header *h;
h = curl_easy_nextheader(handle, CURLH_HEADER, 0, prev);
while (h != nullptr) {
response.headers.emplace(h->name, h->value);
}
auto writefn = [](char *ptr, size_t size, size_t nmemb, void *userdata) {
std::string *body = static_cast<std::string *>(userdata);
body->append(ptr, size * nmemb);
};
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writefn);
curl_easy_setopt(handle, CURLOPT_WRITEDATA,
static_cast<void *>(&response.body));
long status;
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status);
response.status_code = status;
return response;
return absl::UnimplementedError("SendRequest not implemented");
}
#ifndef NEARBY_CHROMIUM
std::unique_ptr<nearby::api::PreferencesManager>
ImplementationPlatform::CreatePreferencesManager(absl::string_view path) {
return std::make_unique<linux::PreferencesManager>(path);
return nullptr;
}
#endif
@@ -1,285 +0,0 @@
// Copyright 2021-2023 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.
#include <filesystem> // NOLINT(build/c++17)
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/linux/preferences_manager.h"
#include "absl/strings/str_cat.h"
#include "internal/platform/implementation/linux/preferences_repository.h"
#include "internal/platform/logging.h"
#include "internal/platform/implementation/platform.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
namespace nearby {
namespace linux {
namespace {
using json = ::nlohmann::json;
} // namespace
PreferencesManager::PreferencesManager(absl::string_view file_path)
: api::PreferencesManager() {
std::optional<FilePath> path =
nearby::api::ImplementationPlatform::CreateDeviceInfo()
->GetLocalAppDataPath();
if (!path.has_value()) {
path = FilePath("/tmp");
}
std::filesystem::path full_path = std::filesystem::path(path->ToString()) / std::string(file_path);
preferences_repository_ =
std::make_unique<PreferencesRepository>(full_path.string());
value_ = preferences_repository_->LoadPreferences();
}
bool PreferencesManager::Set(absl::string_view key, const json& value) {
absl::MutexLock lock(&mutex_);
return SetValue(key, value);
}
bool PreferencesManager::SetBoolean(absl::string_view key, bool value) {
absl::MutexLock lock(&mutex_);
return SetValue(key, value);
}
bool PreferencesManager::SetInteger(absl::string_view key, int value) {
absl::MutexLock lock(&mutex_);
return SetValue(key, value);
}
bool PreferencesManager::SetInt64(absl::string_view key, int64_t value) {
absl::MutexLock lock(&mutex_);
return SetValue(key, value);
}
bool PreferencesManager::SetString(absl::string_view key,
absl::string_view value) {
absl::MutexLock lock(&mutex_);
return SetValue(key, absl::StrCat(value));
}
bool PreferencesManager::SetBooleanArray(absl::string_view key,
absl::Span<const bool> value) {
absl::MutexLock lock(&mutex_);
return SetArrayValue(key, value);
}
bool PreferencesManager::SetIntegerArray(absl::string_view key,
absl::Span<const int> value) {
absl::MutexLock lock(&mutex_);
return SetArrayValue(key, value);
}
bool PreferencesManager::SetInt64Array(absl::string_view key,
absl::Span<const int64_t> value) {
absl::MutexLock lock(&mutex_);
return SetArrayValue(key, value);
}
bool PreferencesManager::SetStringArray(absl::string_view key,
absl::Span<const std::string> value) {
absl::MutexLock lock(&mutex_);
return SetArrayValue(key, value);
}
bool PreferencesManager::SetTime(absl::string_view key, absl::Time value) {
// Save time as nanos
absl::MutexLock lock(&mutex_);
int64_t tt = absl::ToUnixNanos(value);
if (value_[absl::StrCat(key)] == tt) {
return false;
}
value_[absl::StrCat(key)] = tt;
return Commit();
}
// Get JSON value.
json PreferencesManager::Get(absl::string_view key,
const json& default_value) const {
absl::MutexLock lock(&mutex_);
return GetValue(key, default_value);
}
bool PreferencesManager::GetBoolean(absl::string_view key,
bool default_value) const {
absl::MutexLock lock(&mutex_);
return GetValue(key, default_value);
}
int PreferencesManager::GetInteger(absl::string_view key,
int default_value) const {
absl::MutexLock lock(&mutex_);
return GetValue(key, default_value);
}
int64_t PreferencesManager::GetInt64(absl::string_view key,
int64_t default_value) const {
absl::MutexLock lock(&mutex_);
return GetValue(key, default_value);
}
std::string PreferencesManager::GetString(
absl::string_view key, const std::string& default_value) const {
absl::MutexLock lock(&mutex_);
return GetValue(key, default_value);
}
std::vector<bool> PreferencesManager::GetBooleanArray(
absl::string_view key, absl::Span<const bool> default_value) const {
absl::MutexLock lock(&mutex_);
return GetArrayValue(key, default_value);
}
std::vector<int> PreferencesManager::GetIntegerArray(
absl::string_view key, absl::Span<const int> default_value) const {
absl::MutexLock lock(&mutex_);
return GetArrayValue(key, default_value);
}
std::vector<int64_t> PreferencesManager::GetInt64Array(
absl::string_view key, absl::Span<const int64_t> default_value) const {
absl::MutexLock lock(&mutex_);
return GetArrayValue(key, default_value);
}
std::vector<std::string> PreferencesManager::GetStringArray(
absl::string_view key, absl::Span<const std::string> default_value) const {
absl::MutexLock lock(&mutex_);
return GetArrayValue(key, default_value);
}
absl::Time PreferencesManager::GetTime(absl::string_view key,
absl::Time default_value) const {
absl::MutexLock lock(&mutex_);
auto result = value_.find(absl::StrCat(key));
if (result == value_.end()) {
return default_value;
}
return absl::FromUnixNanos(result->get<int64_t>());
}
// Removes preferences
void PreferencesManager::Remove(absl::string_view key) {
absl::MutexLock lock(&mutex_);
value_.erase(absl::StrCat(key));
}
// Private methods
// Writes data to storage.
bool PreferencesManager::Commit() {
if (!preferences_repository_->SavePreferences(value_)) {
LOG(ERROR) << "Failed to save preference." << std::endl;
return false;
}
return true;
}
bool PreferencesManager::SetValue(absl::string_view key, const json& value) {
if (!value_.is_object()) {
LOG(ERROR) << "Preferences is no longer an object! value_="
<< value_.dump(4);
value_ = json::object();
}
if (value_[absl::StrCat(key)] == value) {
return false;
}
value_[absl::StrCat(key)] = value;
return Commit();
}
template <typename T>
T PreferencesManager::GetValue(absl::string_view key,
const T& default_value) const {
if (!value_.is_object()) {
LOG(ERROR) << "Preferences is no longer an object! value_="
<< value_.dump(4);
return default_value;
}
auto it = value_.find(absl::StrCat(key));
if (it == value_.end()) {
return default_value;
}
return it->get<T>();
}
template <typename T>
bool PreferencesManager::SetArrayValue(absl::string_view key,
absl::Span<const T> value) {
if (!value_.is_object()) {
LOG(ERROR) << "Preferences is no longer an object! value_="
<< value_.dump(4);
value_ = json::object();
}
json array_value = json::array();
for (const T& item_value : value) {
array_value.push_back(item_value);
}
if (value_[absl::StrCat(key)] == array_value) {
return false;
}
value_[absl::StrCat(key)] = array_value;
return Commit();
}
template <typename T>
std::vector<T> PreferencesManager::GetArrayValue(
absl::string_view key, absl::Span<const T> default_value) const {
std::vector<T> result;
if (!value_.is_object()) {
LOG(ERROR) << "Preferences is no longer an object! value_="
<< value_.dump(4);
for (const T& value : default_value) {
result.push_back(value);
}
return result;
}
auto array_value = value_.find(absl::StrCat(key));
if (array_value == value_.end() || !array_value->is_array()) {
for (const T& value : default_value) {
result.push_back(value);
}
return result;
}
auto it = array_value->begin();
while (it != array_value->end()) {
result.push_back(it->get<T>());
++it;
}
return result;
}
} // namespace linux
} // namespace nearby
@@ -1,141 +0,0 @@
// Copyright 2021-2023 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.
#ifndef PLATFORM_IMPLEMENTATION_LINUX_PREFERENCES_MANAGER_H_
#define PLATFORM_IMPLEMENTATION_LINUX_PREFERENCES_MANAGER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "internal/platform/implementation/linux/preferences_repository.h"
#include "internal/platform/implementation/preferences_manager.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
namespace nearby {
namespace linux {
// Sets and gets preference settings from the application.
// Preferences are persistent storage for application settings, it is key/value
// based settings. Application components can observe the interested preference
// change by the observer.
class PreferencesManager : public api::PreferencesManager {
public:
explicit PreferencesManager(absl::string_view path);
// Sets values
bool Set(absl::string_view key, const nlohmann::json& value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetBoolean(absl::string_view key, bool value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetInteger(absl::string_view key, int value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetInt64(absl::string_view key, int64_t value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetString(absl::string_view key, absl::string_view value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetBooleanArray(absl::string_view key,
absl::Span<const bool> value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetIntegerArray(absl::string_view key,
absl::Span<const int> value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetInt64Array(absl::string_view key,
absl::Span<const int64_t> value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetStringArray(absl::string_view key,
absl::Span<const std::string> value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetTime(absl::string_view key, absl::Time value) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Gets values
nlohmann::json Get(absl::string_view key,
const nlohmann::json& default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
bool GetBoolean(absl::string_view key, bool default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
int GetInteger(absl::string_view key, int default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
int64_t GetInt64(absl::string_view key, int64_t default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
std::string GetString(absl::string_view key,
const std::string& default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
std::vector<bool> GetBooleanArray(absl::string_view key,
absl::Span<const bool> default_value)
const override ABSL_LOCKS_EXCLUDED(mutex_);
std::vector<int> GetIntegerArray(
absl::string_view key, absl::Span<const int> default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
std::vector<int64_t> GetInt64Array(absl::string_view key,
absl::Span<const int64_t> default_value)
const override ABSL_LOCKS_EXCLUDED(mutex_);
std::vector<std::string> GetStringArray(
absl::string_view key,
absl::Span<const std::string> default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
absl::Time GetTime(absl::string_view key,
absl::Time default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
// Removes preferences
void Remove(absl::string_view key) override ABSL_LOCKS_EXCLUDED(mutex_);
private:
// Writes data to storage.
bool Commit() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool SetValue(absl::string_view key, const nlohmann::json& value)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
template <typename T>
T GetValue(absl::string_view key, const T& default_value) const
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
template <typename T>
bool SetArrayValue(absl::string_view key, absl::Span<const T> value)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
template <typename T>
std::vector<T> GetArrayValue(absl::string_view key,
absl::Span<const T> default_value) const
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
nlohmann::json value_ ABSL_GUARDED_BY(mutex_);
std::unique_ptr<PreferencesRepository> preferences_repository_
ABSL_GUARDED_BY(mutex_);
mutable absl::Mutex mutex_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPLEMENTATION_LINUX_PREFERENCES_MANAGER_H_
@@ -1,152 +0,0 @@
// Copyright 2023 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.
#include <exception>
#include <filesystem> // NOLINT(build/c++17)
#include <fstream>
#include <optional>
#include "internal/platform/implementation/linux/preferences_repository.h"
#include "internal/platform/logging.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
namespace nearby {
namespace linux {
namespace {
using json = ::nlohmann::json;
constexpr char kPreferencesFileName[] = "preferences.json";
constexpr char kPreferencesBackupFileName[] = "preferences_bak.json";
} // namespace
json PreferencesRepository::LoadPreferences() {
absl::MutexLock lock(&mutex_);
std::optional<json> preferences = AttemptLoad();
if (preferences.has_value()) {
// The top level root should be an object, if it's not then something went
// wrong or the file was corrupted.
if (!preferences.value().is_object()) {
LOG(ERROR) << "Preferences loaded was not a valid object: "
<< preferences.value().dump(4);
return json::object();
}
return preferences.value();
}
LOG(ERROR) << "Could not load preferences file, trying backup.";
// In the future we should switch to using a transaction log or another
// stable method which doesn't pose a risk of losing settings
preferences = RestoreFromBackup();
if (preferences.has_value()) {
LOG(ERROR) << "Successfully recovered from backup.";
return preferences.value();
}
LOG(ERROR) << "Failed to load preferences file from back up.";
return json::object();
}
bool PreferencesRepository::SavePreferences(json preferences) {
absl::MutexLock lock(&mutex_);
try {
std::filesystem::path path = path_;
if (!std::filesystem::exists(path) &&
!std::filesystem::create_directories(path)) {
LOG(ERROR) << "Failed to create preferences path.";
return false;
}
std::filesystem::path full_name = path / kPreferencesFileName;
std::filesystem::path full_name_backup = path / kPreferencesBackupFileName;
// Create a backup without moving the bytes on disk
if (std::filesystem::exists(full_name)) {
LOG(INFO) << "Making backup of preferences file.";
std::filesystem::rename(full_name, full_name_backup);
}
std::ofstream preferences_file(full_name.c_str());
preferences_file << preferences;
preferences_file.close();
// Make sure the file wasn't saved in a corrupted state
if (!AttemptLoad().has_value()) {
LOG(ERROR) << "Preferences saved to disk in corrupted state. "
"Restoring from backup.";
if (!RestoreFromBackup().has_value()) {
LOG(ERROR) << "Failed to restore preferences file.";
return false;
}
}
} catch (const std::exception& e) {
LOG(ERROR) << "Failed to save preferences file: " << e.what();
return false;
}
return true;
}
std::optional<json> PreferencesRepository::AttemptLoad() {
std::filesystem::path path = path_;
std::filesystem::path full_name = path / kPreferencesFileName;
if (!std::filesystem::exists(path) || !std::filesystem::exists(full_name)) {
return std::nullopt;
}
try {
std::ifstream preferences_file(full_name.c_str());
if (!preferences_file.good()) {
return std::nullopt;
}
json preferences = json::parse(preferences_file, nullptr, false);
preferences_file.close();
if (preferences.is_discarded()) {
LOG(ERROR) << "Preferences file corrupted.";
return std::nullopt;
}
return preferences;
} catch (const std::exception& e) {
LOG(ERROR) << "Exception while loading preferences: " << e.what();
return std::nullopt;
}
}
std::optional<json> PreferencesRepository::RestoreFromBackup() {
std::filesystem::path path = path_;
std::filesystem::path full_name = path / kPreferencesFileName;
std::filesystem::path full_name_backup = path / kPreferencesBackupFileName;
if (!std::filesystem::exists(full_name_backup)) {
LOG(WARNING)
<< "Backup requested but no backup preferences file found.";
return std::nullopt;
}
std::filesystem::rename(full_name_backup, full_name);
LOG(INFO) << "Attempting load from backup preferences.";
return AttemptLoad();
}
} // namespace linux
} // namespace nearby
@@ -1,48 +0,0 @@
// Copyright 2021 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.
#ifndef PLATFORM_IMPLEMENTATION_LINUX_PREFERENCES_REPOSITORY_H_
#define PLATFORM_IMPLEMENTATION_LINUX_PREFERENCES_REPOSITORY_H_
#include <optional>
#include <string>
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
namespace nearby {
namespace linux {
class PreferencesRepository {
public:
explicit PreferencesRepository(absl::string_view path) : path_(path) {}
nlohmann::json LoadPreferences() ABSL_LOCKS_EXCLUDED(&mutex_);
bool SavePreferences(nlohmann::json preferences) ABSL_LOCKS_EXCLUDED(&mutex_);
std::optional<nlohmann::json> AttemptLoad();
std::optional<nlohmann::json> RestoreFromBackup();
private:
absl::Mutex mutex_;
const std::string path_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPLEMENTATION_LINUX_PREFERENCES_REPOSITORY_H_
@@ -1,84 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/linux/scheduled_executor.h"
#include <algorithm>
#include <memory>
#include <utility>
#include "absl/time/time.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
ScheduledExecutor::ScheduledExecutor()
: executor_(std::make_unique<nearby::linux::Executor>()),
shut_down_(false) {}
// Cancelable is kept both in the executor context, and in the caller context.
// We want Cancelable to live until both caller and executor are done with it.
// Exclusive ownership model does not work for this case;
// using std:shared_ptr<> instead of std::unique_ptr<>.
std::shared_ptr<api::Cancelable> ScheduledExecutor::Schedule(
Runnable &&runnable, absl::Duration duration) {
if (shut_down_) {
LOG(ERROR) << __func__
<< ": Attempt to Schedule on a shut down executor.";
return nullptr;
}
// Cleans completed tasks
scheduled_tasks_.erase(
std::remove_if(
scheduled_tasks_.begin(), scheduled_tasks_.end(),
[](std::shared_ptr<ScheduledTask> &task) { return task->IsDone(); }),
scheduled_tasks_.end());
std::shared_ptr<ScheduledTask> task =
std::make_shared<ScheduledTask>(std::move(runnable), duration);
scheduled_tasks_.push_back(task);
executor_->Execute([task]() { task->Start(); });
return task;
}
void ScheduledExecutor::Execute(Runnable &&runnable) {
if (shut_down_) {
LOG(ERROR) << __func__
<< ": Attempt to Execute on a shut down executor.";
return;
}
executor_->Execute(std::move(runnable));
}
void ScheduledExecutor::Shutdown() {
if (!shut_down_) {
shut_down_ = true;
for (auto &task : scheduled_tasks_) {
task->Cancel();
}
scheduled_tasks_.clear();
executor_->Shutdown();
return;
}
LOG(ERROR) << __func__
<< ": Attempt to Shutdown on a shut down executor.";
}
} // namespace linux
} // namespace nearby
@@ -1,100 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_SCHEDULED_EXECUTOR_H_
#define PLATFORM_IMPL_LINUX_SCHEDULED_EXECUTOR_H_
#include <memory>
#include <utility>
#include <vector>
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/cancelable.h"
#include "internal/platform/implementation/linux/executor.h"
#include "internal/platform/implementation/scheduled_executor.h"
namespace nearby {
namespace linux {
#define TIMER_NAME_BUFFER_SIZE 64
// An Executor that can schedule commands to run after a given delay, or to
// execute periodically.
//
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html
class ScheduledExecutor : public api::ScheduledExecutor {
public:
ScheduledExecutor();
~ScheduledExecutor() override = default;
// Cancelable is kept both in the executor context, and in the caller context.
// We want Cancelable to live until both caller and executor are done with it.
// Exclusive ownership model does not work for this case;
// using std:shared_ptr<> instead if std::unique_ptr<>.
std::shared_ptr<api::Cancelable> Schedule(Runnable&& runnable,
absl::Duration duration) override;
// Executes the runnable task immedately.
void Execute(Runnable&& runnable) override;
// Shutdowns the executor, all scheduled task will be cancelled.
void Shutdown() override;
private:
class ScheduledTask : public api::Cancelable {
public:
explicit ScheduledTask(Runnable&& task, absl::Duration duration)
: task_(std::move(task)), duration_(duration) {}
bool Cancel() override {
if (is_executed_ || is_cancelled_) {
return false;
}
is_cancelled_ = true;
notification_.Notify();
return true;
};
void Start() {
if (is_executed_ ||
notification_.WaitForNotificationWithTimeout(duration_)) {
return;
}
is_executed_ = true;
task_();
}
bool IsDone() const { return is_cancelled_ || is_executed_; }
private:
Runnable task_;
absl::Duration duration_;
absl::Notification notification_;
bool is_cancelled_ = false;
bool is_executed_ = false;
};
std::unique_ptr<nearby::linux::Executor> executor_ = nullptr;
std::vector<std::shared_ptr<ScheduledTask>> scheduled_tasks_;
std::atomic_bool shut_down_ = false;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_SCHEDULED_EXECUTOR_H_
@@ -1,88 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_SERVER_SYNC_H_
#define PLATFORM_IMPL_LINUX_SERVER_SYNC_H_
#include "internal/platform/implementation/server_sync.h"
namespace nearby {
namespace linux {
// Abstraction that represents a Nearby endpoint exchanging data through
// ServerSync Medium.
class ServerSyncDevice : public api::ServerSyncDevice {
public:
// TODO(b/184975123): replace with real implementation.
~ServerSyncDevice() override = default;
// TODO(b/184975123): replace with real implementation.
std::string GetName() const override { return "Un-implemented"; }
// TODO(b/184975123): replace with real implementation.
std::string GetGuid() const override { return "Un-implemented"; }
// TODO(b/184975123): replace with real implementation.
std::string GetOwnGuid() const override { return "Un-implemented"; }
};
// Container of operations that can be performed over the Chrome Sync medium.
class ServerSyncMedium : public api::ServerSyncMedium {
public:
// TODO(b/184975123): replace with real implementation.
~ServerSyncMedium() override = default;
// TODO(b/184975123): replace with real implementation.
bool StartAdvertising(absl::string_view service_id,
absl::string_view endpoint_id,
const ByteArray& endpoint_info) override {
return false;
}
// TODO(b/184975123): replace with real implementation.
void StopAdvertising(absl::string_view service_id) override {}
class DiscoveredDeviceCallback
: public api::ServerSyncMedium::DiscoveredDeviceCallback {
public:
// TODO(b/184975123): replace with real implementation.
~DiscoveredDeviceCallback() override = default;
// Called on a new ServerSyncDevice discovery.
// TODO(b/184975123): replace with real implementation.
void OnDeviceDiscovered(api::ServerSyncDevice* device,
absl::string_view service_id,
absl::string_view endpoint_id,
const ByteArray& endpoint_info) override {}
// Called when ServerSyncDevice is no longer reachable.
// TODO(b/184975123): replace with real implementation.
void OnDeviceLost(api::ServerSyncDevice* device,
absl::string_view service_id) override {}
};
// Returns true once the Chrome Sync scan has been initiated.
// TODO(b/184975123): replace with real implementation.
bool StartDiscovery(absl::string_view service_id,
const api::ServerSyncMedium::DiscoveredDeviceCallback&
discovered_device_callback) override {
return false;
}
// Returns true once Chrome Sync scan for service_id is well and truly
// stopped; after this returns, there must be no more invocations of the
// DiscoveredDeviceCallback passed in to startScanning() for service_id.
// TODO(b/184975123): replace with real implementation.
void StopDiscovery(absl::string_view service_id) override {}
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_SERVER_SYNC_H_
@@ -1,82 +0,0 @@
// Copyright 2023 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.
#include <sys/socket.h>
#include <unistd.h>
#include <array>
#include <cerrno>
#include <cstdint>
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/linux/stream.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
ExceptionOr<ByteArray> InputStream::Read(std::int64_t size) {
if (!fd_.isValid()) return {Exception::kIo};
std::string buffer;
buffer.resize(size);
ssize_t ret = recv(fd_.get(), buffer.data(), buffer.size(), MSG_WAITALL);
if (ret == 0) {
return ExceptionOr(ByteArray());
}
if (ret < 0) {
LOG(ERROR) << __func__
<< ": error reading from fd: " << std::strerror(errno);
return {Exception::kIo};
}
buffer.resize(ret);
return ExceptionOr(ByteArray(std::move(buffer)));
}
Exception InputStream::Close() {
if (!fd_.isValid()) return Exception{Exception::kIo};
fd_.reset();
return {};
}
Exception OutputStream::Write(const ByteArray &data) {
if (!fd_.isValid()) return Exception{Exception::kIo};
size_t written = 0;
while (written < data.size()) {
ssize_t ret = write(fd_.get(), data.data(), data.size());
if (ret < 0) {
LOG(ERROR) << __func__
<< ": error writing to fd: " << std::strerror(errno);
return Exception{Exception::kIo};
}
written += ret;
}
return Exception{Exception::kSuccess};
}
Exception OutputStream::Flush() { return Exception{Exception::kSuccess}; }
Exception OutputStream::Close() {
if (!fd_.isValid()) return Exception{Exception::kIo};
auto ret = close(fd_.get()) < 0 ? Exception{Exception::kIo}
: Exception{Exception::kSuccess};
fd_.reset();
return ret;
}
} // namespace linux
} // namespace nearby
@@ -1,54 +0,0 @@
// Copyright 2023 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.
#ifndef PLATFORM_IMPL_LINUX_STREAM_H_
#define PLATFORM_IMPL_LINUX_STREAM_H_
#include <optional>
#include <sdbus-c++/Types.h>
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace linux {
class InputStream : public nearby::InputStream {
public:
explicit InputStream(sdbus::UnixFd fd) : fd_(std::move(fd)){};
ExceptionOr<ByteArray> Read(std::int64_t size) override;
Exception Close() override;
private:
sdbus::UnixFd fd_;
};
class OutputStream : public nearby::OutputStream {
public:
explicit OutputStream(sdbus::UnixFd fd) : fd_(std::move(fd)){};
Exception Write(const ByteArray &data) override;
Exception Flush() override;
Exception Close() override;
private:
sdbus::UnixFd fd_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -1,62 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/linux/executor.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
SubmittableExecutor::SubmittableExecutor(size_t max_concurrancy)
: executor_(std::make_unique<nearby::linux::Executor>(max_concurrancy)),
shut_down_(false) {}
bool SubmittableExecutor::DoSubmit(Runnable&& wrapped_callable) {
if (!shut_down_) {
executor_->Execute(std::move(wrapped_callable));
return true;
}
LOG(ERROR) << "Error: " << __func__
<< ": Attempt to DoSubmit on a shutdown executor.";
return false;
}
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
void SubmittableExecutor::Execute(Runnable&& runnable) {
if (!shut_down_) {
executor_->Execute(std::move(runnable));
} else {
LOG(ERROR) << "Error: " << __func__
<< ": Attempt to Execute on a shutdown executor.";
}
}
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
void SubmittableExecutor::Shutdown() {
if (!shut_down_) {
executor_->Shutdown();
shut_down_ = true;
return;
}
LOG(ERROR) << "Error: " << __func__
<< ": Attempt to Shutdown on a shutdown executor.";
}
} // namespace linux
} // namespace nearby
@@ -1,52 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_SUBMITTABLE_EXECUTOR_H_
#define PLATFORM_IMPL_LINUX_SUBMITTABLE_EXECUTOR_H_
#include "internal/platform/implementation/linux/executor.h"
#include "internal/platform/implementation/submittable_executor.h"
namespace nearby {
namespace linux {
// Main interface to be used by platform as a base class for
// - MultiThreadExecutorWrapper
// - SingleThreadExecutorWrapper
// Platform must override bool submit(absl::AnyInvocable<void()>) method.
class SubmittableExecutor : public api::SubmittableExecutor {
public:
SubmittableExecutor(size_t maxConcurrancy = 1);
~SubmittableExecutor() override = default;
// Submit a callable (with no delay).
// Returns true, if callable was submitted, false otherwise.
// Callable is not submitted if shutdown is in progress.
bool DoSubmit(Runnable&& wrapped_callable) override;
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
void Execute(Runnable&& runnable) override;
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
void Shutdown() override;
private:
std::unique_ptr<nearby::linux::Executor> executor_;
std::atomic_bool shut_down_ = false;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_SUBMITTABLE_EXECUTOR_H_
@@ -1,41 +0,0 @@
// Copyright 2021 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.
#ifndef PLATFORM_IMPL_LINUX_SYSTEM_CLOCK_H_
#define PLATFORM_IMPL_LINUX_SYSTEM_CLOCK_H_
#include "internal/platform/implementation/system_clock.h"
namespace nearby {
// Initialize global system state.
void SystemClock::Init() {}
// Returns current absolute time. It is guaranteed to be monotonic.
absl::Time SystemClock::ElapsedRealtime() {
return absl::FromUnixNanos(
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count());
}
// Pauses current thread for the specified duration.
Exception SystemClock::Sleep(absl::Duration duration) {
absl::SleepFor(duration);
return {Exception::kSuccess};
}
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_SYSTEM_CLOCK_H_
@@ -1,17 +1,3 @@
# Copyright 2024 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.
load("@rules_cc//cc:cc_test.bzl", "cc_test")
licenses(["notice"])
@@ -23,21 +9,7 @@ cc_test(
"atomic_boolean_test.cc",
"atomic_reference_test.cc",
"count_down_latch_test.cc",
"crypto_test.cc",
"device_info_test.cc",
"device_paths_test.cc",
"executor_test.cc",
"file_test.cc",
"http_loader_test.cc",
"platform_test.cc",
"preferences_manager_test.cc",
"preferences_repository_test.cc",
"scheduled_executor_test.cc",
"string_utils_test.cc",
"submittable_executor_test.cc",
"task_scheduler_test.cc",
"thread_pool_test.cc",
"timer_test.cc",
"utils_test.cc",
],
deps = [
@@ -45,14 +17,10 @@ cc_test(
"//internal/base:files",
"//internal/platform:logging",
"//internal/platform/implementation:platform",
"//internal/platform/implementation/linux:comm",
"//internal/platform/implementation/linux:crypto",
"//internal/platform/implementation/linux:linux",
"//internal/platform/implementation/linux:types",
"//internal/platform/implementation/linux:test_utils",
"@com_google_googletest//:gtest_main",
"@nlohmann_json//:json",
"@sdbus_cpp//:sdbus_cpp",
],
)
@@ -1,17 +1,3 @@
// Copyright 2020 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.
#include "internal/platform/implementation/linux/atomic_boolean.h"
#include "gtest/gtest.h"
@@ -1,17 +1,3 @@
// Copyright 2020 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.
#include "internal/platform/implementation/linux/atomic_reference.h"
#include "gtest/gtest.h"
@@ -1,50 +0,0 @@
// Copyright 2020 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.
#include "internal/platform/implementation/crypto.h"
#include <string>
#include "gtest/gtest.h"
namespace nearby {
namespace {
TEST(CryptoTest, Md5Hash) {
const std::string input{"Hello Nearby Connection"};
const ByteArray expected_md5(
"\x94\xa3\xbe\xc1\x8d\x30\xe3\x24\x5f\xa1\x4c\xee\xe7\x52\xe9\x36");
ByteArray md5_hash = Crypto::Md5(input);
EXPECT_EQ(md5_hash, expected_md5);
}
TEST(CryptoTest, Md5HashOnEmptyInput) {
EXPECT_EQ(Crypto::Md5(""), ByteArray{});
}
TEST(CryptoTest, Sha256Hash) {
const std::string input("Hello Nearby Connection");
const ByteArray expected_sha256(
"\xb4\x24\xd3\xc0\x58\x12\x9a\x42\xcb\x81\xa0\x4b\x6e\x9d\xfe\x45\x45\x9f"
"\x15\xf7\xc0\xa9\x32\x2f\xfb\x9\x45\xf0\xf9\xbe\x75\xb");
ByteArray sha256_hash = Crypto::Sha256(input);
EXPECT_EQ(sha256_hash, expected_sha256);
}
TEST(CryptoTest, Sha256HashOnEmptyInput) {
EXPECT_EQ(Crypto::Sha256(""), ByteArray{});
}
} // namespace
} // namespace nearby
@@ -1,93 +0,0 @@
// Copyright 2021-2023 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.
#include "internal/platform/implementation/linux/device_info.h"
#include <cstring>
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/linux/dbus.h"
namespace nearby {
namespace linux {
namespace {
class DeviceInfoTest : public ::testing::Test {
protected:
void SetUp() override {
system_bus_ = getSystemBusConnection();
device_info_ = std::make_unique<DeviceInfo>(system_bus_);
}
void TearDown() override {
device_info_.reset();
}
std::shared_ptr<sdbus::IConnection> system_bus_;
std::unique_ptr<DeviceInfo> device_info_;
};
TEST_F(DeviceInfoTest, GetComputerName) {
ASSERT_TRUE(device_info_->GetOsDeviceName().has_value());
std::string device_name = device_info_->GetOsDeviceName().value();
// Makes sure device_name does not include terminating null character.
EXPECT_EQ(device_name.size(), std::strlen(device_name.data()));
}
TEST_F(DeviceInfoTest, DISABLED_GetDeviceType) {
EXPECT_EQ(device_info_->GetDeviceType(), api::DeviceInfo::DeviceType::kLaptop);
}
TEST_F(DeviceInfoTest, GetOsType) {
EXPECT_EQ(device_info_->GetOsType(), api::DeviceInfo::OsType::kWindows);
}
TEST_F(DeviceInfoTest, DISABLED_GetLocalAppDataPath) {
EXPECT_TRUE(device_info_->GetLocalAppDataPath().has_value());
}
TEST_F(DeviceInfoTest, DISABLED_GetDownloadPath) {
EXPECT_TRUE(device_info_->GetDownloadPath().has_value());
}
TEST_F(DeviceInfoTest, DISABLED_GetTemporaryPath) {
EXPECT_TRUE(device_info_->GetTemporaryPath().has_value());
}
TEST_F(DeviceInfoTest, DISABLED_GetLogPath) {
EXPECT_TRUE(device_info_->GetLogPath().has_value());
}
TEST_F(DeviceInfoTest, DISABLED_GetCrashDumpPath) {
EXPECT_TRUE(device_info_->GetCrashDumpPath().has_value());
}
TEST_F(DeviceInfoTest, DISABLED_IsScreenLocked) {
EXPECT_FALSE(device_info_->IsScreenLocked());
}
TEST_F(DeviceInfoTest, DISABLED_PreventSleep) {
EXPECT_TRUE(device_info_->PreventSleep());
}
TEST_F(DeviceInfoTest, DISABLED_AllowSleep) {
EXPECT_TRUE(device_info_->AllowSleep());
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,27 +0,0 @@
// Copyright 2024 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.
#include "gtest/gtest.h"
namespace nearby {
namespace linux {
TEST(DevicePathsTest, PlaceholderTest) {
// Linux doesn't have device paths like Windows
// This test exists for parity but has no meaningful implementation
SUCCEED();
}
} // namespace linux
} // namespace nearby
@@ -1,322 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/linux/executor.h"
#include <algorithm>
#include <utility>
#include "gtest/gtest.h"
#include "absl/synchronization/blocking_counter.h"
#include "absl/synchronization/mutex.h"
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/linux/test_data.h"
namespace nearby {
namespace linux {
namespace {
constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200);
TEST(ExecutorTests, SingleThreadedExecutorSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto executor = std::make_unique<Executor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
executor->Execute([&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
});
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
executor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(ExecutorTests, SingleThreadedExecutorAfterShutdownFails) {
// Arrange
std::string expected("");
std::unique_ptr<Executor> executor = std::make_unique<Executor>();
std::unique_ptr<std::string> output = std::make_unique<std::string>();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
executor->Shutdown();
// Act
executor->Execute([&output, &threadIds]() {
threadIds->push_back(pthread_self());
output->append(RUNNABLE_0_TEXT.c_str());
});
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 1);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(*output.get(), expected);
}
TEST(ExecutorTests, SingleThreadedExecutorExecuteNullSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto executor = std::make_unique<Executor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
executor->Execute(nullptr);
executor->Execute([&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
});
executor->Execute(nullptr);
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
executor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(ExecutorTests, SingleThreadedExecutorMultipleTasksSucceeds) {
absl::BlockingCounter block_count(5);
// Arrange
std::string expected(RUNNABLE_ALL_TEXT.c_str());
auto executor = std::make_unique<Executor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
auto parent_thread = pthread_self();
// Act
for (int index = 0; index < 5; index++) {
executor->Execute([&, index]() {
threadIds->push_back(pthread_self());
char buffer[128];
snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index);
output.append(std::string(buffer));
block_count.DecrementCount();
});
}
block_count.Wait();
executor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 5);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), parent_thread);
// We should've run all runnables on the worker thread
auto workerThreadId = threadIds->at(0);
for (int index = 0; index < threadIds->size(); index++) {
ASSERT_EQ(threadIds->at(index), workerThreadId);
}
// We should of run them in the order submitted
ASSERT_EQ(output, expected);
}
TEST(ExecutorTests, MultiThreadedExecutorSingleTaskSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto executor = std::make_unique<Executor>(2);
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
std::shared_ptr<std::string> output = std::make_shared<std::string>();
threadIds->push_back(pthread_self());
// Act
executor->Execute([&, output]() {
threadIds->push_back(pthread_self());
output->append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
});
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
executor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run the task
ASSERT_EQ(*output.get(), expected);
}
TEST(ExecutorTests, MultiThreadedExecutorMultipleTasksSucceeds) {
absl::BlockingCounter block_count(5);
// Arrange
auto executor = std::make_unique<Executor>(2);
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
std::shared_ptr<std::string> output = std::make_shared<std::string>();
threadIds->push_back(pthread_self());
// Act
for (int index = 0; index < 5; index++) {
executor->Execute([&, index]() {
threadIds->push_back(pthread_self());
char buffer[128];
snprintf(buffer, sizeof(buffer), "%s %d, ", RUNNABLE_TEXT.c_str(), index);
output->append(std::string(buffer));
block_count.DecrementCount();
});
}
block_count.Wait();
executor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 6);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
}
TEST(ExecutorTests, MultiThreadedExecutorSingleTaskAfterShutdownFails) {
// Arrange
std::string expected("");
auto executor = std::make_unique<Executor>(2);
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
std::shared_ptr<std::string> output = std::make_shared<std::string>();
threadIds->push_back(pthread_self());
executor->Shutdown();
// Act
executor->Execute([output, &threadIds]() {
threadIds->push_back(pthread_self());
output->append(RUNNABLE_0_TEXT.c_str());
});
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 1);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run the task
ASSERT_EQ(*output.get(), expected);
}
TEST(ExecutorTests,
MultiThreadedExecutorMultipleTasksLargeNumberOfThreadsSucceeds) {
absl::BlockingCounter block_count(250);
// Arrange
auto executor = std::make_unique<Executor>(32);
// Container to note threads that ran
std::vector<pthread_t> threadIds = std::vector<pthread_t>();
threadIds.push_back(pthread_self());
absl::Mutex mutex;
// Act
for (int index = 0; index < 250; index++) {
executor->Execute([&]() mutable {
pthread_t id = pthread_self();
{
absl::MutexLock lock(&mutex);
threadIds.push_back(id);
}
// Using rand since this is in a critical section
// and windows doesn't have a rand_r anyway
auto sleepTime = (std::rand() % 101) + 1; // NOLINT
absl::SleepFor(absl::Milliseconds(sleepTime));
block_count.DecrementCount();
});
}
block_count.Wait();
executor->Shutdown();
// Assert
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds.at(0));
// We should've run 1 time on the main thread, and 200 times on the
// workerThreads
ASSERT_EQ(threadIds.size(), 251);
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,126 +0,0 @@
// Copyright 2024 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.
#include "internal/platform/implementation/linux/file.h"
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
namespace nearby {
namespace linux {
namespace {
constexpr char kTestContent[] = "Hello, World!";
constexpr char kTestFileName[] = "/tmp/nearby_file_test.txt";
class FileTest : public ::testing::Test {
protected:
void SetUp() override {
// Clean up any existing test file
std::filesystem::remove(kTestFileName);
}
void TearDown() override {
// Clean up test file
std::filesystem::remove(kTestFileName);
}
};
TEST_F(FileTest, CreateInputFileSuccess) {
// Create a test file
std::ofstream out(kTestFileName);
out << kTestContent;
out.close();
auto file = IOFile::CreateInputFile(kTestFileName, sizeof(kTestContent));
ASSERT_NE(file, nullptr);
EXPECT_EQ(file->GetFilePath(), kTestFileName);
EXPECT_GT(file->GetTotalSize(), 0);
file->Close();
}
TEST_F(FileTest, CreateOutputFileSuccess) {
auto file = IOFile::CreateOutputFile(kTestFileName);
ASSERT_NE(file, nullptr);
EXPECT_EQ(file->GetFilePath(), kTestFileName);
file->Close();
}
TEST_F(FileTest, ReadFileSuccess) {
// Create a test file
std::ofstream out(kTestFileName);
out << kTestContent;
out.close();
auto file = IOFile::CreateInputFile(kTestFileName, sizeof(kTestContent));
ASSERT_NE(file, nullptr);
auto result = file->Read(sizeof(kTestContent) - 1);
ASSERT_TRUE(result.ok());
ByteArray data = result.result();
EXPECT_EQ(data.size(), sizeof(kTestContent) - 1);
EXPECT_EQ(std::string(data.data(), data.size()), kTestContent);
file->Close();
}
TEST_F(FileTest, WriteFileSuccess) {
auto file = IOFile::CreateOutputFile(kTestFileName);
ASSERT_NE(file, nullptr);
ByteArray data(kTestContent, sizeof(kTestContent) - 1);
Exception result = file->Write(data);
EXPECT_EQ(result.value, Exception::kSuccess);
file->Close();
// Verify the file was written
std::ifstream in(kTestFileName);
std::string content((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
EXPECT_EQ(content, kTestContent);
}
TEST_F(FileTest, CloseFileSuccess) {
auto file = IOFile::CreateOutputFile(kTestFileName);
ASSERT_NE(file, nullptr);
Exception result = file->Close();
EXPECT_EQ(result.value, Exception::kSuccess);
}
TEST_F(FileTest, FlushFileSuccess) {
auto file = IOFile::CreateOutputFile(kTestFileName);
ASSERT_NE(file, nullptr);
ByteArray data(kTestContent, sizeof(kTestContent) - 1);
file->Write(data);
Exception result = file->Flush();
EXPECT_EQ(result.value, Exception::kSuccess);
file->Close();
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,51 +0,0 @@
// 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.
#include "internal/platform/implementation/linux/http_loader.h"
#include <string>
#include "gtest/gtest.h"
namespace nearby {
namespace linux {
namespace {
using ::nearby::api::WebRequest;
TEST(HttpLoader, DISABLED_TestGetUrl) {
WebRequest request;
request.url = "https://www.google.com?id=456#fragment";
request.method = "GET";
auto response = HttpLoader(request).GetResponse();
ASSERT_TRUE(response.ok());
EXPECT_EQ(response->status_code, 200);
}
TEST(HttpLoader, DISABLED_TestGetNotExistingUrl) {
WebRequest request;
request.url = "https://www.abcdefgabcdefg.com";
request.method = "GET";
EXPECT_FALSE(HttpLoader(request).GetResponse().ok());
}
TEST(HttpLoader, DISABLED_TestInvalidUrl) {
WebRequest request;
request.url = "https:/www.abcdefgabcdefg.com/name?id=456";
request.method = "GET";
EXPECT_FALSE(HttpLoader(request).GetResponse().ok());
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,219 +0,0 @@
// Copyright 2021-2023 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.
#include "internal/platform/implementation/linux/preferences_manager.h"
#include <stdint.h>
#include <fstream>
#include <memory>
#include <ostream>
#include <string>
#include <vector>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "internal/base/file_path.h"
#include "internal/base/files.h"
#include "internal/platform/logging.h"
// If nlohmann gives clangd errors, uncomment this when working on devcontainers. it helps. remove when building.
// build will fail.
// #include "external/nlohmann_json+/single_include/nlohmann/json.hpp"
namespace nearby {
namespace linux {
namespace {
using json = ::nlohmann::json;
constexpr absl::string_view kPreferencesFilePath = "Google/Nearby/Sharing";
class PreferencesManagerTest : public ::testing::Test {
protected:
void SetUp() override {
temp_dir_ = Files::GetTemporaryDirectory();
preferences_path_ = temp_dir_.GetPath();
if (Files::FileExists(FilePath(preferences_path_)))
{
Files::RemoveFile(FilePath(preferences_path_));
}
}
void TearDown() override {
// Clean up any created preference files
FilePath pref_file = temp_dir_;
pref_file.append(FilePath("preferences.json"));
if (Files::FileExists(pref_file)) {
Files::RemoveFile(pref_file);
}
}
FilePath temp_dir_;
std::string preferences_path_;
};
} // namespace
TEST_F(PreferencesManagerTest, CorruptedConfigFile) {
FilePath preferencesPath = temp_dir_;
preferencesPath.append(FilePath("preferences.json"));
std::ofstream output_stream{preferencesPath.GetPath()};
output_stream << "CORRUPTED" << std::endl;
output_stream.close();
LOG(INFO) << "Loading preferences from: " << temp_dir_.ToString();
PreferencesManager pm(preferences_path_);
EXPECT_EQ(pm.GetInteger("data", 100), 100);
}
TEST_F(PreferencesManagerTest, ValidConfigFile) {
FilePath preferencesPath = temp_dir_;
preferencesPath.append(FilePath("preferences.json"));
std::ofstream output_stream{preferencesPath.GetPath()};
output_stream << "{\"data\":8, \"name\": \"Valid\"}" << std::endl;
output_stream.close();
LOG(INFO) << "Loading preferences from: " << temp_dir_.ToString();
PreferencesManager pm(preferences_path_);
EXPECT_EQ(pm.GetInteger("data", 100), 8);
}
TEST(PreferencesManager, SetAndGetBoolean) {
std::string bool_key = "bool_key";
PreferencesManager pm(kPreferencesFilePath);
EXPECT_TRUE(pm.GetBoolean(bool_key, true));
pm.SetBoolean(bool_key, true);
EXPECT_TRUE(pm.GetBoolean(bool_key, false));
}
TEST(PreferencesManager, SetAndGetInt) {
std::string int_key = "int_key";
PreferencesManager pm(kPreferencesFilePath);
EXPECT_EQ(pm.GetInteger(int_key, 1234), 1234);
pm.SetInteger(int_key, 6789);
EXPECT_EQ(pm.GetInteger(int_key, 0), 6789);
}
TEST(PreferencesManager, SetAndGetInt64) {
std::string int64_key = "int64_key";
PreferencesManager pm(kPreferencesFilePath);
EXPECT_EQ(pm.GetInt64(int64_key, 1234), 1234);
pm.SetInt64(int64_key, 56789);
EXPECT_EQ(pm.GetInt64(int64_key, 0), 56789);
}
TEST(PreferencesManager, SetAndGetString) {
std::string string_key = "string_key";
PreferencesManager pm(kPreferencesFilePath);
EXPECT_EQ(pm.GetString(string_key, "abcd"), "abcd");
pm.SetString(string_key, "this is a test string");
EXPECT_EQ(pm.GetString(string_key, ""), "this is a test string");
}
TEST(PreferencesManager, SetAndGetTime) {
std::string time_key = "time_key";
PreferencesManager pm(kPreferencesFilePath);
absl::Time time = absl::Now();
EXPECT_EQ(pm.GetTime(time_key, time), time);
pm.SetTime(time_key, time);
absl::Time ret = pm.GetTime(time_key, absl::Now());
EXPECT_EQ(absl::ToUnixNanos(ret), absl::ToUnixNanos(time));
}
TEST(PreferencesManager, MultipleSetAndGetString) {
std::string string1_key = "string1_key";
PreferencesManager pm(kPreferencesFilePath);
pm.SetString(string1_key, "this is first string");
pm.SetString(string1_key, "this is second string");
EXPECT_EQ(pm.GetString(string1_key, ""), "this is second string");
}
TEST(PreferencesManager, SetAndGetValue) {
std::string value_key = "value_key";
PreferencesManager pm(kPreferencesFilePath);
json value = {{"key1", "value1"}, {"key2", "value2"}};
EXPECT_TRUE(pm.Get(value_key, json()).empty());
pm.Set(value_key, value);
auto result = pm.Get(value_key, json());
ASSERT_FALSE(result.empty());
auto val = result["key2"];
EXPECT_EQ(val.get<std::string>(), "value2");
}
TEST(PreferencesManager, SetAndGetBooleanArray) {
std::string bool_array_key = "bool_array_key";
auto pm = PreferencesManager(kPreferencesFilePath);
auto default_result =
pm.GetBooleanArray(bool_array_key, absl::Span<const bool>({true}));
EXPECT_EQ(default_result[0], true);
pm.SetBooleanArray(bool_array_key,
absl::Span<const bool>({true, false, false, true, true}));
auto result =
pm.GetBooleanArray(bool_array_key, absl::Span<const bool>({true}));
EXPECT_EQ(result[2], false);
EXPECT_EQ(result[3], true);
}
TEST(PreferencesManager, SetAndGetIntArray) {
std::string int_array_key = "int_array_key";
auto pm = PreferencesManager(kPreferencesFilePath);
auto result = pm.GetIntegerArray(int_array_key, std::vector<int>{5, 6});
EXPECT_EQ(result[1], 6);
pm.SetIntegerArray(int_array_key, std::vector<int>{1, 7, 4, 10, 12});
result = pm.GetIntegerArray(int_array_key, std::vector<int>{11, 17, 14, 110});
EXPECT_EQ(result[3], 10);
}
TEST(PreferencesManager, SetAndGetInt64Array) {
std::string int64_array_key = "int64_array_key";
auto pm = PreferencesManager(kPreferencesFilePath);
auto result = pm.GetInt64Array(int64_array_key, std::vector<int64_t>{99});
EXPECT_EQ(result[0], 99);
pm.SetInt64Array(int64_array_key, std::vector<int64_t>{16, 7, 64, 100, 12});
result = pm.GetInt64Array(int64_array_key, std::vector<int64_t>{1, 5, 6, 12});
EXPECT_EQ(result[3], 100);
EXPECT_EQ(result[4], 12);
}
TEST(PreferencesManager, SetAndGetStringArray) {
std::string string_array_key = "string_array_key";
auto pm = PreferencesManager(kPreferencesFilePath);
auto result = pm.GetStringArray(string_array_key,
std::vector<std::string>{"value", "morning"});
EXPECT_EQ(result[1], "morning");
pm.SetStringArray(
string_array_key,
std::vector<std::string>{"one", "two", "three", "four", "five"});
result = pm.GetStringArray(string_array_key,
std::vector<std::string>{"good", "morning"});
EXPECT_EQ(result[3], "four");
}
TEST(PreferencesManager, RemoveKey) {
std::string string_key = "string_key";
auto pm = PreferencesManager(kPreferencesFilePath);
pm.SetString(string_key, "remove key");
pm.Remove(string_key);
auto result = pm.GetString(string_key, "default key");
EXPECT_EQ(result, "default key");
}
} // namespace linux
} // namespace nearby
@@ -1,208 +0,0 @@
// Copyright 2023 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.
#include "internal/platform/implementation/linux/preferences_repository.h"
#include <fstream>
#include <memory>
#include <optional>
#include "gtest/gtest.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "internal/base/file_path.h"
#include "internal/base/files.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/implementation/linux/device_info.h"
#include "internal/platform/implementation/platform.h"
namespace nearby {
namespace linux {
namespace {
using json = ::nlohmann::json;
constexpr char kPreferencesFileName[] = "preferences.json";
constexpr char kPreferencesBackupFileName[] = "preferences_bak.json";
constexpr char kPreferencesPath[] = "Google/Nearby/Sharing";
class PreferencesRepositoryTest : public ::testing::Test {
protected:
void SetUp() override {
system_bus_ = getSystemBusConnection();
device_info_ = std::make_unique<DeviceInfo>(system_bus_);
std::optional<FilePath> app_data_path = device_info_->GetLocalAppDataPath();
if (app_data_path.has_value()) {
app_data_path_ = app_data_path.value();
test_path_ = app_data_path_.append(FilePath(kPreferencesPath));
test_path_str_ = test_path_.GetPath();
}
}
void TearDown() override {
// Clean up test files
if (!test_path_str_.empty()) {
FilePath pref_file = app_data_path_;
pref_file.append(FilePath(kPreferencesFileName));
if (Files::FileExists(pref_file)) {
Files::RemoveFile(pref_file);
}
FilePath backup_file = test_path_;
backup_file.append(FilePath(kPreferencesBackupFileName));
if (Files::FileExists(backup_file)) {
Files::RemoveFile(backup_file);
}
}
device_info_.reset();
}
std::shared_ptr<sdbus::IConnection> system_bus_;
std::unique_ptr<DeviceInfo> device_info_;
FilePath app_data_path_;
FilePath test_path_;
std::string test_path_str_;
};
TEST(PreferencesRepository, LoadWithBadPath) {
PreferencesRepository preferences_repository{"/invalid/path/a/b/c/d/e/f"};
json result = preferences_repository.LoadPreferences();
EXPECT_TRUE(result.empty());
}
TEST_F(PreferencesRepositoryTest, RecoverFromBadPreferences) {
if (test_path_str_.empty()) {
GTEST_SKIP() << "Cannot get app data path in test environment";
}
FilePath full_name = app_data_path_;
full_name.append(FilePath(kPreferencesFileName));
if (Files::FileExists(full_name)) {
Files::RemoveFile(full_name);
}
std::ofstream pref_file(full_name.GetPath());
pref_file << "\"Bad top level object\"";
pref_file.close();
PreferencesRepository preferences_repository{test_path_str_};
EXPECT_EQ(preferences_repository.LoadPreferences(), json::object());
}
TEST_F(PreferencesRepositoryTest, SaveAndLoadPreferences) {
if (test_path_str_.empty()) {
GTEST_SKIP() << "Cannot get app data path in test environment";
}
FilePath full_name = app_data_path_;
full_name.append(FilePath(kPreferencesFileName));
if (Files::FileExists(full_name)) {
Files::RemoveFile(full_name);
}
PreferencesRepository preferences_repository{test_path_str_};
json data;
data["key1"] = "value1";
data["key2"] = "value2";
EXPECT_TRUE(preferences_repository.SavePreferences(data));
json result = preferences_repository.LoadPreferences();
EXPECT_EQ(result.size(), 2);
EXPECT_EQ(result["key1"], "value1");
EXPECT_EQ(result["key2"], "value2");
Files::RemoveFile(full_name);
}
TEST_F(PreferencesRepositoryTest, LoadFromBackup) {
if (test_path_str_.empty()) {
GTEST_SKIP() << "Cannot get app data path in test environment";
}
FilePath full_name = app_data_path_;
full_name.append(FilePath(kPreferencesFileName));
FilePath full_name_backup = test_path_;
full_name_backup.append(FilePath(kPreferencesBackupFileName));
if (Files::FileExists(full_name)) {
Files::RemoveFile(full_name);
}
if (Files::FileExists(full_name_backup)) {
Files::RemoveFile(full_name_backup);
}
PreferencesRepository preferences_repository{test_path_str_};
json data;
data["key1"] = "value1";
data["key2"] = "value2";
std::ofstream backup_file(full_name_backup.GetPath());
backup_file << data;
backup_file.close();
std::optional<json> result;
result = preferences_repository.AttemptLoad();
EXPECT_FALSE(result.has_value());
result = preferences_repository.RestoreFromBackup();
EXPECT_TRUE(result.has_value());
EXPECT_EQ(result.value()["key1"], "value1");
EXPECT_EQ(result.value()["key2"], "value2");
Files::RemoveFile(full_name);
EXPECT_FALSE(Files::FileExists(full_name_backup));
}
TEST_F(PreferencesRepositoryTest, RecoverFromCorruption) {
if (test_path_str_.empty()) {
GTEST_SKIP() << "Cannot get app data path in test environment";
}
FilePath full_name = app_data_path_;
full_name.append(FilePath(kPreferencesFileName));
FilePath full_name_backup = test_path_;
full_name_backup.append(FilePath(kPreferencesBackupFileName));
if (Files::FileExists(full_name)) {
Files::RemoveFile(full_name);
}
if (Files::FileExists(full_name_backup)) {
Files::RemoveFile(full_name_backup);
}
PreferencesRepository preferences_repository{test_path_str_};
json data;
data["key1"] = "value1";
data["key2"] = "value2";
std::ofstream preferences_file(full_name_backup.GetPath());
preferences_file << data;
preferences_file.close();
std::ofstream backup_file(full_name.GetPath());
backup_file << "[BAD JSON FILE]";
backup_file.close();
std::optional<json> result = preferences_repository.LoadPreferences();
EXPECT_EQ(result.value()["key1"], "value1");
EXPECT_EQ(result.value()["key2"], "value2");
Files::RemoveFile(full_name);
EXPECT_FALSE(Files::FileExists(full_name_backup));
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,176 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/linux/scheduled_executor.h"
#include <chrono> // NOLINT
#include <memory>
#include <utility>
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/linux/test_data.h"
namespace nearby {
namespace linux {
namespace {
constexpr absl::Duration kWaitTimeout = absl::Milliseconds(2000);
TEST(ScheduledExecutorTest, ExecuteSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto submittableExecutor = std::make_unique<ScheduledExecutor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
submittableExecutor->Execute([&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
});
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
submittableExecutor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 1 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(ScheduledExecutorTest, ScheduleSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto submittableExecutor = std::make_unique<ScheduledExecutor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
std::chrono::system_clock::time_point timeExecuted;
// Act
submittableExecutor->Schedule(
[&]() {
timeExecuted = std::chrono::system_clock::now();
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
},
absl::Milliseconds(50));
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
submittableExecutor->Shutdown();
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(ScheduledExecutorTest, CancelSucceeds) {
absl::Notification notification;
// Arrange
std::string expected("");
auto submittableExecutor = std::make_unique<ScheduledExecutor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
auto cancelable = submittableExecutor->Schedule(
[&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
},
absl::Milliseconds(1000));
auto actual = cancelable->Cancel();
EXPECT_FALSE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
submittableExecutor->Shutdown();
// Assert
ASSERT_TRUE(actual);
ASSERT_EQ(threadIds->size(), 1);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(ScheduledExecutorTest, CancelAfterStartedFails) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto submittableExecutor = std::make_unique<ScheduledExecutor>();
std::string output = std::string();
// Container to note threads that ran
std::unique_ptr<std::vector<pthread_t>> threadIds =
std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
auto cancelable = submittableExecutor->Schedule(
[&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
},
absl::Milliseconds(100));
absl::SleepFor(absl::Milliseconds(500));
auto actual = cancelable->Cancel();
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
submittableExecutor->Shutdown();
// Assert
ASSERT_FALSE(actual);
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,27 +0,0 @@
// Copyright 2024 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.
#include "gtest/gtest.h"
namespace nearby {
namespace linux {
TEST(StringUtilsTest, PlaceholderTest) {
// Linux doesn't have a separate string_utils like Windows
// String conversion functionality is integrated into other modules
SUCCEED();
}
} // namespace linux
} // namespace nearby
@@ -1,249 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/linux/submittable_executor.h"
#include <utility>
#include "gtest/gtest.h"
#include "absl/synchronization/blocking_counter.h"
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/linux/test_data.h"
namespace nearby {
namespace linux {
namespace {
constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200);
TEST(SubmittableExecutorTests, SingleThreadedExecuteSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto submittableExecutor = std::make_unique<SubmittableExecutor>();
std::string output = std::string();
// Container to note threads that ran
auto threadIds = std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
submittableExecutor->Execute([&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
});
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
submittableExecutor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 1 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(SubmittableExecutorTests, SingleThreadedExecuteAfterShutdownFails) {
// Arrange
std::string expected("");
auto submittableExecutor = std::make_unique<SubmittableExecutor>();
std::string output = std::string();
// Container to note threads that ran
auto threadIds = std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
submittableExecutor->Shutdown();
// Act
submittableExecutor->Execute([&output, &threadIds]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
});
// Assert
// We should've run 1 time on the main thread, and 0 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 1);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(SubmittableExecutorTests, SingleThreadedDoSubmitSucceeds) {
absl::Notification notification;
// Arrange
std::string expected(RUNNABLE_0_TEXT.c_str());
auto submittableExecutor = std::make_unique<SubmittableExecutor>();
std::string output = std::string();
// Container to note threads that ran
auto threadIds = std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
auto result = submittableExecutor->DoSubmit([&]() {
threadIds->push_back(pthread_self());
output.append(RUNNABLE_0_TEXT.c_str());
notification.Notify();
});
ASSERT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
submittableExecutor->Shutdown();
// Assert
// We should've said we were going to run this one
ASSERT_TRUE(result);
// We should've run 1 time on the main thread, and 1 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 2);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(output, expected);
}
TEST(SubmittableExecutorTests,
SingleThreadedDoSubmitAfterShutdownReturnsFalse) {
// Arrange
std::string expected("");
auto submittableExecutor = std::make_unique<SubmittableExecutor>();
std::unique_ptr<std::string> output = std::make_unique<std::string>();
// Container to note threads that ran
auto threadIds = std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
submittableExecutor->Shutdown();
// Act
auto result = submittableExecutor->DoSubmit([&output, &threadIds]() {
threadIds->push_back(pthread_self());
output->append(RUNNABLE_0_TEXT.c_str());
});
// Assert
// We should've said we were going to run this one
ASSERT_FALSE(result);
// We should've run 1 time on the main thread, and 1 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 1);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
ASSERT_EQ(*output.get(), expected);
}
TEST(SubmittableExecutorTests, SingleThreadedExecuteMultipleTasksSucceeds) {
absl::BlockingCounter blocking_counter(5);
// Arrange
std::string expected(RUNNABLE_ALL_TEXT.c_str());
auto submittableExecutor = std::make_unique<SubmittableExecutor>();
std::unique_ptr<std::string> output = std::make_unique<std::string>();
// Container to note threads that ran
auto threadIds = std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
for (int index = 0; index < 5; index++) {
submittableExecutor->Execute([&, index]() {
threadIds->push_back(pthread_self());
char buffer[128];
snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index);
output->append(std::string(buffer));
blocking_counter.DecrementCount();
});
}
blocking_counter.Wait();
submittableExecutor->Shutdown();
// Assert
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 6);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
auto workerThreadId = threadIds->at(1);
for (int index = 1; index < threadIds->size(); index++) {
ASSERT_EQ(threadIds->at(index), workerThreadId);
}
// We should of run them in the order submitted
ASSERT_EQ(*output.get(), expected);
}
TEST(SubmittableExecutorTests, SingleThreadedDoSubmitMultipleTasksSucceeds) {
absl::BlockingCounter blocking_counter(5);
// Arrange
std::string expected(RUNNABLE_ALL_TEXT.c_str());
auto submittableExecutor = std::make_unique<SubmittableExecutor>();
std::unique_ptr<std::string> output = std::make_unique<std::string>();
// Container to note threads that ran
auto threadIds = std::make_unique<std::vector<pthread_t>>();
threadIds->push_back(pthread_self());
// Act
bool result = true;
for (int index = 0; index < 5; index++) {
result &= submittableExecutor->DoSubmit([&, index]() {
threadIds->push_back(pthread_self());
char buffer[128];
snprintf(buffer, sizeof(buffer), "%s%d, ", RUNNABLE_TEXT.c_str(), index);
output->append(std::string(buffer));
blocking_counter.DecrementCount();
});
}
blocking_counter.Wait();
submittableExecutor->Shutdown();
// Assert
// All of these should have submitted
ASSERT_TRUE(result);
// We should've run 1 time on the main thread, and 5 times on the
// workerThread
ASSERT_EQ(threadIds->size(), 6);
// We should still be on the main thread
ASSERT_EQ(pthread_self(), threadIds->at(0));
// We should've run all runnables on the worker thread
auto workerThreadId = threadIds->at(1);
for (int index = 1; index < threadIds->size(); index++) {
ASSERT_EQ(threadIds->at(index), workerThreadId);
}
// We should of run them in the order submitted
ASSERT_EQ(*output.get(), expected);
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,27 +0,0 @@
// Copyright 2024 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.
#include "gtest/gtest.h"
namespace nearby {
namespace linux {
TEST(TaskSchedulerTest, PlaceholderTest) {
// Linux doesn't have a separate task scheduler implementation like Windows
// Task scheduling is handled through executors
SUCCEED();
}
} // namespace linux
} // namespace nearby
@@ -1,158 +0,0 @@
// 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.
#include "internal/platform/implementation/linux/thread_pool.h"
#include <atomic>
#include <memory>
#include <vector>
#include "gtest/gtest.h"
#include "absl/synchronization/blocking_counter.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
namespace nearby {
namespace linux {
namespace {
constexpr int kTaskCount = 10;
TEST(ThreadPool, TasksInSingleThreadRunInSequence) {
absl::BlockingCounter blocking_counter(kTaskCount);
absl::Mutex mutex;
auto pool = std::make_unique<ThreadPool>(1);
std::vector<int> completed_tasks;
std::vector<int> expected_tasks;
for (int i = 0; i < kTaskCount; ++i) {
expected_tasks.push_back(i);
pool->Run([&, i]() {
absl::MutexLock lock(&mutex);
completed_tasks.push_back(i);
blocking_counter.DecrementCount();
});
}
blocking_counter.Wait();
EXPECT_EQ(completed_tasks, expected_tasks);
pool->ShutDown();
}
TEST(ThreadPool, TasksInMultipleThreadsRunInParallel) {
absl::BlockingCounter blocking_counter(kTaskCount);
absl::Time start_time = absl::Now();
auto pool = std::make_unique<ThreadPool>(2);
for (int i = 0; i < kTaskCount; ++i) {
pool->Run([&]() {
absl::SleepFor(absl::Milliseconds(100));
blocking_counter.DecrementCount();
});
}
blocking_counter.Wait();
EXPECT_TRUE(absl::Now() - start_time < absl::Milliseconds(1000));
pool->ShutDown();
}
// Test is flaky
TEST(ThreadPool, ShutdownWaitsForRunningTasks) {
auto pool = std::make_unique<ThreadPool>(1);
std::atomic_int value = 0;
std::atomic_bool task_started_ = false;
pool->Run([&]() {
task_started_ = true;
absl::SleepFor(absl::Milliseconds(1000));
value += 1;
});
while (!task_started_)
{
absl::SleepFor(absl::Milliseconds(100));
}
pool->ShutDown();
EXPECT_EQ(value, 1);
}
TEST(ThreadPool, RunNullTaskReturnsFalse) {
auto pool = std::make_unique<ThreadPool>(1);
EXPECT_FALSE(pool->Run(nullptr));
pool->ShutDown();
}
TEST(ThreadPool, RunTaskAfterShutdownReturnsFalse) {
auto pool = std::make_unique<ThreadPool>(1);
pool->ShutDown();
std::atomic_int value = 0;
EXPECT_FALSE(pool->Run([&]() { value += 1; }));
EXPECT_EQ(value, 0);
}
TEST(ThreadPool, MultipleTasksExecute) {
absl::BlockingCounter blocking_counter(5);
auto pool = std::make_unique<ThreadPool>(2);
std::atomic_int counter = 0;
for (int i = 0; i < 5; ++i) {
pool->Run([&]() {
counter++;
blocking_counter.DecrementCount();
});
}
blocking_counter.Wait();
EXPECT_EQ(counter, 5);
pool->ShutDown();
}
TEST(ThreadPool, LargeThreadPoolExecutesTasks) {
constexpr int kLargeTaskCount = 100;
absl::BlockingCounter blocking_counter(kLargeTaskCount);
auto pool = std::make_unique<ThreadPool>(10);
std::atomic_int counter = 0;
for (int i = 0; i < kLargeTaskCount; ++i) {
pool->Run([&]() {
counter++;
blocking_counter.DecrementCount();
});
}
blocking_counter.Wait();
EXPECT_EQ(counter, kLargeTaskCount);
pool->ShutDown();
}
TEST(ThreadPool, DestructorCallsShutdown) {
std::atomic_int value = 0;
std::atomic_bool task_started_ = false;
{
auto pool = std::make_unique<ThreadPool>(1);
pool->Run([&]() {
task_started_ = true;
absl::SleepFor(absl::Milliseconds(200));
value = 1;
});
while (!task_started_){ absl::SleepFor(absl::Milliseconds(50)); }
}
EXPECT_EQ(value, 1);
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,60 +0,0 @@
// Copyright 2021 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.
#include "internal/platform/implementation/timer.h"
#include <memory>
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/implementation/platform.h"
namespace nearby {
namespace linux {
namespace {
TEST(TimerTest, TestCreateTimer) {
int count = 0;
std::unique_ptr<nearby::api::Timer> timer =
nearby::api::ImplementationPlatform::CreateTimer();
ASSERT_TRUE(timer != nullptr);
EXPECT_FALSE(timer->Create(-100, 0, [&]() { ++count; }));
EXPECT_TRUE(timer->Stop());
}
// This test case cannot run on Google3
TEST(TimerTest, TestRepeatTimer) {
CountDownLatch latch(3);
int count = 0;
std::unique_ptr<nearby::api::Timer> timer =
nearby::api::ImplementationPlatform::CreateTimer();
ASSERT_TRUE(timer != nullptr);
EXPECT_TRUE(timer->Create(300, 300, [&]() {
++count;
latch.CountDown();
}));
EXPECT_TRUE(latch.Await(absl::Seconds(2)));
EXPECT_EQ(count, 3);
EXPECT_TRUE(timer->Stop());
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -1,36 +0,0 @@
// Copyright 2020 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.
#include <algorithm>
#include <codecvt>
#include <sstream>
#include "absl/strings/str_format.h"
#include "absl/strings/str_replace.h"
#include "internal/platform/implementation/linux/device_info.h"
#include "internal/platform/implementation/linux/test_utils.h"
#include "dbus.h"
namespace test_utils {
std::string GetPayloadPath(nearby::PayloadId payload_id) {
auto bus = nearby::linux::getSystemBusConnection();
std::optional<nearby::FilePath> path =
nearby::linux::DeviceInfo(bus).GetDownloadPath();
if (!path.has_value()) { return std::string(getenv("HOME")).append("Downloads");}
return path.value().ToString();
}
} // namespace test_utils
@@ -1,42 +0,0 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_TEST_UTILS_H_
#define PLATFORM_IMPL_LINUX_TEST_UTILS_H_
#include <string>
#include "internal/platform/payload_id.h"
#define TEST_BUFFER_SIZE 256
#define TEST_PAYLOAD_ID 64l
#define TEST_STRING \
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas " \
"eleifend nisl at magna maximus, id finibus mauris ultrices. Mauris " \
"interdum efficitur turpis eget auctor. Nullam commodo metus et ante " \
"bibendum molestie. Donec iaculis ante nec diam rutrum egestas. Proin " \
"maximus metus luctus rutrum congue. Integer et eros nunc. Etiam purus " \
"neque, tincidunt eu elementum in, pharetra sit amet magna. Quisque " \
"consequat aliquam aliquam. Vestibulum ante ipsum primis in faucibus orci " \
"luctus et ultrices posuere cubilia curae; Maecenas a semper eros, a " \
"auctor mi. In luctus diam sem, eu pretium nisi porttitor ac. Sed cursus, " \
"arcu in bibendum feugiat, leo erat finibus massa, ut tincidunt magna nunc " \
"eu tellus. Cras feugiat ornare vestibulum. Nullam at ipsum vestibulum " \
"sapien luctus dictum ac vel ligula."
namespace test_utils {
std::string GetPayloadPath(nearby::PayloadId payload_id);
} // namespace test_utils
#endif // PLATFORM_IMPL_LINUX_TEST_UTILS_H_
@@ -1,125 +0,0 @@
// Copyright 2021-2023 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.
#include <atomic>
#include <queue>
#include <utility>
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/thread_pool.h"
#include "internal/platform/logging.h"
#include "internal/platform/runnable.h"
namespace nearby {
namespace linux {
ThreadPool::ThreadPool(size_t max_pool_size)
: max_pool_size_(max_pool_size), shut_down_(false) {
threads_.reserve(max_pool_size);
Start();
}
ThreadPool::~ThreadPool() { ShutDown(); }
bool ThreadPool::Start() {
shut_down_.store(false, std::memory_order_acquire);
auto runner = [this]() {
while (true) {
auto task = NextTask();
if (task == nullptr) {
if (shut_down_) {
return;
}
LOG(WARNING) << __func__ << ": Tried to run a null task.";
continue;
}
task();
}
};
absl::MutexLock l(&threads_mutex_);
if (!threads_.empty()) {
LOG(ERROR) << __func__ << "thread pool is already active";
return false;
}
LOG(INFO) << __func__ << ": Starting thread pool with "
<< max_pool_size_ << " threads";
for (size_t i = 0; i < max_pool_size_; i++) {
threads_.emplace_back(runner);
}
return true;
}
bool ThreadPool::Run(Runnable &&task) {
if (shut_down_) {
LOG(ERROR) << __func__ << "thread pool has shut down";
return false;
}
if (task == nullptr) return false;
{
absl::ReaderMutexLock l(&threads_mutex_);
if (threads_.empty()) {
LOG(ERROR) << __func__ << ": thread pool is not active";
return false;
}
}
absl::MutexLock l(&tasks_mutex_);
tasks_.push(std::move(task));
return true;
}
void ThreadPool::ShutDown() {
{
absl::MutexLock l(&tasks_mutex_);
shut_down_.store(true, std::memory_order_acquire);
}
{
absl::ReaderMutexLock l(&threads_mutex_);
for (auto &thread : threads_) {
thread.join();
}
}
absl::MutexLock l(&threads_mutex_);
threads_.clear();
}
Runnable ThreadPool::NextTask() {
Runnable task;
auto task_available = [this]() {
this->tasks_mutex_.AssertReaderHeld();
return !this->tasks_.empty() || this->shut_down_;
};
{
absl::MutexLock l(&tasks_mutex_, absl::Condition(&task_available));
if (shut_down_) {
return nullptr;
}
task = std::move(tasks_.front());
tasks_.pop();
}
return task;
}
} // namespace linux
} // namespace nearby
@@ -1,63 +0,0 @@
// Copyright 2020-2023 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.
#ifndef PLATFORM_IMPL_LINUX_THREAD_POOL_H_
#define PLATFORM_IMPL_LINUX_THREAD_POOL_H_
#include <atomic>
#include <memory>
#include <queue>
#include <thread>
#include <utility>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/runnable.h"
namespace nearby {
namespace linux {
class ThreadPool {
public:
ThreadPool(const ThreadPool &) = delete;
ThreadPool(ThreadPool &&) = delete;
ThreadPool &operator=(const ThreadPool &) = delete;
ThreadPool &operator=(ThreadPool &&) = delete;
explicit ThreadPool(size_t max_pool_size);
~ThreadPool();
bool Start() ABSL_LOCKS_EXCLUDED(threads_mutex_);
// Runs a task on thread pool. The result indicates whether the task is put
// into the thread pool.
bool Run(Runnable &&task) ABSL_LOCKS_EXCLUDED(tasks_mutex_);
void ShutDown() ABSL_LOCKS_EXCLUDED(threads_mutex_);
private:
Runnable NextTask() ABSL_LOCKS_EXCLUDED(tasks_mutex_);
size_t max_pool_size_;
std::atomic_bool shut_down_;
absl::Mutex threads_mutex_;
std::vector<std::thread> threads_ ABSL_GUARDED_BY(threads_mutex_);
absl::Mutex tasks_mutex_;
std::queue<Runnable> tasks_ ABSL_GUARDED_BY(tasks_mutex_);
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_THREAD_POOL_H_
@@ -1,115 +0,0 @@
// Copyright 2021 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.
#include <bits/types/struct_itimerspec.h>
#include <signal.h>
#include <time.h>
#include <cerrno>
#include <cstring>
#include <ctime>
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/linux/timer.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
static void timer_callback(union sigval val) {
absl::AnyInvocable<void()> *callback =
reinterpret_cast<absl::AnyInvocable<void()> *>(val.sival_ptr);
if (*callback != nullptr) (*callback)();
}
Timer::~Timer() {
absl::MutexLock l(&mutex_);
if (timerid_.has_value())
if (timer_delete(*timerid_) < 0) {
LOG(ERROR) << __func__ << ": Error deleting POSIX timer: "
<< std::strerror(errno);
}
}
bool Timer::Create(int delay, int interval,
absl::AnyInvocable<void()> callback) {
if (delay < 0 || interval < 0) {
LOG(ERROR) << __func__
<< ": Delay and interval cannot be negative.";
return false;
}
absl::MutexLock l(&mutex_);
if (timerid_.has_value()) {
LOG(ERROR) << __func__
<< "Timer has already been created and armed.";
return false;
}
callback_ = std::move(callback);
struct sigevent ev;
ev.sigev_value.sival_ptr = &callback_;
ev.sigev_notify_function = timer_callback;
timer_t timerid;
struct itimerspec spec;
spec.it_value.tv_nsec = delay * 1000000;
spec.it_value.tv_sec = 0;
spec.it_interval.tv_nsec = interval * 1000000;
spec.it_interval.tv_sec = 0;
if (timer_create(CLOCK_MONOTONIC, &ev, &timerid) < 0) {
LOG(ERROR) << __func__ << ": Error creating POSIX timer: "
<< std::strerror(errno);
return false;
}
if (timer_settime(&timerid, 0, &spec, nullptr) < 0) {
LOG(ERROR) << __func__ << ": Error arming POSIX timer: "
<< std::strerror(errno);
if (!timer_delete(&timerid)) {
LOG(ERROR) << __func__ << ": error deleting POSIX timer: "
<< std::strerror(errno);
}
return false;
}
timerid_ = timerid;
return true;
}
bool Timer::Stop() {
absl::MutexLock l(&mutex_);
if (!timerid_.has_value()) {
LOG(WARNING) << __func__ << ": no timer created";
return true;
}
if (!timer_delete(&*timerid_)) {
LOG(ERROR) << __func__ << ": error deleting POSIX timer: "
<< std::strerror(errno);
return false;
}
timerid_.reset();
return true;
}
} // namespace linux
} // namespace nearby
@@ -1,51 +0,0 @@
// Copyright 2021 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.
#ifndef PLATFORM_IMPL_LINUX_TIMER_H_
#define PLATFORM_IMPL_LINUX_TIMER_H_
#include <signal.h>
#include <time.h>
#include <memory>
#include <optional>
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/timer.h"
namespace nearby {
namespace linux {
class Timer : public api::Timer {
public:
Timer() : timerid_(nullptr){};
~Timer() override;
bool Create(int delay, int interval,
absl::AnyInvocable<void()> callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool Stop() override ABSL_LOCKS_EXCLUDED(mutex_);
private:
absl::Mutex mutex_;
std::optional<timer_t> timerid_ ABSL_GUARDED_BY(mutex_);
absl::AnyInvocable<void()> callback_;
std::unique_ptr<SubmittableExecutor> task_executor_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_TIMER_H_
@@ -1,17 +1,3 @@
// Copyright 2020 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.
#include <random>
#include <systemd/sd-id128.h>
@@ -1,17 +1,3 @@
// Copyright 2020 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.
#ifndef PLATFORM_IMPL_LINUX_UTILS_H_
#define PLATFORM_IMPL_LINUX_UTILS_H_