mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
removed everything except concurrency primitives
This commit is contained in:
@@ -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(
|
||||
|
||||
Generated
+2
-1
@@ -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",
|
||||
|
||||
@@ -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
|
||||
-86
@@ -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
|
||||
-388
@@ -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>
|
||||
-121
@@ -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_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user