mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Refactor the preferences repository to be a Windows implementation detail of the preferences manager
PiperOrigin-RevId: 531086202
This commit is contained in:
committed by
Copybara-Service
parent
0901aec6e2
commit
8886b99dde
@@ -31,7 +31,7 @@ cc_library(
|
||||
"log_message.h",
|
||||
"mutex.h",
|
||||
"output_file.h",
|
||||
"preferences_repository.h",
|
||||
"preferences_manager.h",
|
||||
"scheduled_executor.h",
|
||||
"settable_future.h",
|
||||
"submittable_executor.h",
|
||||
@@ -58,6 +58,7 @@ cc_library(
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@nlohmann_json//:json",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ objc_library(
|
||||
"log_message.mm",
|
||||
"multi_thread_executor.mm",
|
||||
"platform.mm",
|
||||
"preferences_repository.mm",
|
||||
"preferences_manager.mm",
|
||||
"scheduled_executor.mm",
|
||||
"timer.mm",
|
||||
"utils.mm",
|
||||
@@ -41,7 +41,7 @@ objc_library(
|
||||
"device_info.h",
|
||||
"log_message.h",
|
||||
"multi_thread_executor.h",
|
||||
"preferences_repository.h",
|
||||
"preferences_manager.h",
|
||||
"scheduled_executor.h",
|
||||
"single_thread_executor.h",
|
||||
"timer.h",
|
||||
@@ -71,6 +71,7 @@ objc_library(
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@nlohmann_json//:json",
|
||||
] + select({
|
||||
"@platforms//os:platform_ios": [
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/implementation/apple/atomic_boolean.h"
|
||||
#include "internal/platform/implementation/apple/atomic_uint32.h"
|
||||
#include "internal/platform/implementation/apple/ble.h"
|
||||
@@ -28,7 +29,7 @@
|
||||
#import "internal/platform/implementation/apple/log_message.h"
|
||||
#import "internal/platform/implementation/apple/multi_thread_executor.h"
|
||||
#include "internal/platform/implementation/apple/mutex.h"
|
||||
#include "internal/platform/implementation/apple/preferences_repository.h"
|
||||
#include "internal/platform/implementation/apple/preferences_manager.h"
|
||||
#import "internal/platform/implementation/apple/scheduled_executor.h"
|
||||
#import "internal/platform/implementation/apple/single_thread_executor.h"
|
||||
#include "internal/platform/implementation/apple/timer.h"
|
||||
@@ -248,9 +249,9 @@ std::unique_ptr<nearby::api::DeviceInfo> ImplementationPlatform::CreateDeviceInf
|
||||
}
|
||||
|
||||
// TODO(b/261503919): Add implementation.
|
||||
std::unique_ptr<nearby::api::PreferencesRepository>
|
||||
ImplementationPlatform::CreatePreferencesRepository(absl::string_view path) {
|
||||
return std::make_unique<apple::PreferencesRepository>(path);
|
||||
std::unique_ptr<nearby::api::PreferencesManager> ImplementationPlatform::CreatePreferencesManager(
|
||||
absl::string_view path) {
|
||||
return std::make_unique<apple::PreferencesManager>(path);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// 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_IMPLEMENTATION_APPLE_PREFERENCES_MANAGER_H_
|
||||
#define PLATFORM_IMPLEMENTATION_APPLE_PREFERENCES_MANAGER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
#include "internal/platform/implementation/preferences_manager.h"
|
||||
|
||||
namespace nearby::apple {
|
||||
|
||||
class PreferencesManager : public api::PreferencesManager {
|
||||
public:
|
||||
explicit PreferencesManager(absl::string_view path);
|
||||
|
||||
// Sets values
|
||||
|
||||
bool Set(const std::string& key, const nlohmann::json& value) override;
|
||||
|
||||
bool SetBoolean(absl::string_view key, bool value) override;
|
||||
bool SetInteger(absl::string_view key, int value) override;
|
||||
bool SetInt64(absl::string_view key, int64_t value) override;
|
||||
bool SetString(absl::string_view key, absl::string_view value) override;
|
||||
|
||||
bool SetBooleanArray(absl::string_view key,
|
||||
absl::Span<const bool> value) override;
|
||||
bool SetIntegerArray(absl::string_view key,
|
||||
absl::Span<const int> value) override;
|
||||
bool SetInt64Array(absl::string_view key,
|
||||
absl::Span<const int64_t> value) override;
|
||||
bool SetStringArray(absl::string_view key,
|
||||
absl::Span<const std::string> value) override;
|
||||
|
||||
bool SetTime(absl::string_view key, absl::Time value) override;
|
||||
|
||||
// Gets values
|
||||
nlohmann::json Get(absl::string_view key,
|
||||
const nlohmann::json& default_value) const override;
|
||||
|
||||
bool GetBoolean(absl::string_view key, bool default_value) const override;
|
||||
int GetInteger(absl::string_view key, int default_value) const override;
|
||||
int64_t GetInt64(absl::string_view key, int64_t default_value) const override;
|
||||
std::string GetString(absl::string_view key,
|
||||
const std::string& default_value) const override;
|
||||
|
||||
std::vector<bool> GetBooleanArray(
|
||||
absl::string_view key,
|
||||
absl::Span<const bool> default_value) const override;
|
||||
std::vector<int> GetIntegerArray(
|
||||
absl::string_view key,
|
||||
absl::Span<const int> default_value) const override;
|
||||
std::vector<int64_t> GetInt64Array(
|
||||
absl::string_view key,
|
||||
absl::Span<const int64_t> default_value) const override;
|
||||
std::vector<std::string> GetStringArray(
|
||||
absl::string_view key,
|
||||
absl::Span<const std::string> default_value) const override;
|
||||
|
||||
absl::Time GetTime(absl::string_view key,
|
||||
absl::Time default_value) const override;
|
||||
|
||||
// Removes preferences
|
||||
void Remove(absl::string_view key) override;
|
||||
};
|
||||
|
||||
} // namespace nearby::apple
|
||||
|
||||
#endif // PLATFORM_IMPLEMENTATION_APPLE_PREFERENCES_MANAGER_H_
|
||||
@@ -0,0 +1,256 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/preferences_manager.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace nearby::apple {
|
||||
|
||||
PreferencesManager::PreferencesManager(absl::string_view file_path)
|
||||
: api::PreferencesManager(file_path) {}
|
||||
|
||||
bool PreferencesManager::Set(const std::string& key, const nlohmann::json& value) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@(value.dump().c_str()) forKey:@(key.c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetBoolean(absl::string_view key, bool value) {
|
||||
[[NSUserDefaults standardUserDefaults] setBool:value forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetInteger(absl::string_view key, int value) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:value forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetInt64(absl::string_view key, int64_t value) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value]
|
||||
forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetString(absl::string_view key, absl::string_view value) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@(std::string(value).c_str())
|
||||
forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetBooleanArray(absl::string_view key, absl::Span<const bool> value) {
|
||||
NSMutableArray<NSNumber*>* array = [NSMutableArray array];
|
||||
for (const bool& item : value) {
|
||||
[array addObject:@(item)];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetIntegerArray(absl::string_view key, absl::Span<const int> value) {
|
||||
NSMutableArray<NSNumber*>* array = [NSMutableArray array];
|
||||
for (const int& item : value) {
|
||||
[array addObject:@(item)];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetInt64Array(absl::string_view key, absl::Span<const int64_t> value) {
|
||||
NSMutableArray<NSNumber*>* array = [NSMutableArray array];
|
||||
for (const int64_t& item : value) {
|
||||
[array addObject:@(item)];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetStringArray(absl::string_view key,
|
||||
absl::Span<const std::string> value) {
|
||||
NSMutableArray<NSString*>* array = [NSMutableArray array];
|
||||
for (const std::string& item : value) {
|
||||
[array addObject:@(item.c_str())];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetTime(absl::string_view key, absl::Time value) {
|
||||
int64_t nanos = absl::ToUnixNanos(value);
|
||||
NSDate* date = [[NSDate alloc] initWithTimeIntervalSince1970:nanos / NSEC_PER_SEC];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:date forKey:@(std::string(key).c_str())];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get JSON value.
|
||||
nlohmann::json PreferencesManager::Get(absl::string_view key,
|
||||
const nlohmann::json& default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (value == nil) {
|
||||
return default_value;
|
||||
}
|
||||
// We store JSON as a serialized string, so retrieve it as a string and deserialize.
|
||||
NSCAssert([value isKindOfClass:[NSString class]], @"value for key \"%@\" must be JSON",
|
||||
keyString);
|
||||
return nlohmann::json::parse([(NSString*)value UTF8String]);
|
||||
}
|
||||
|
||||
bool PreferencesManager::GetBoolean(absl::string_view key, bool default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (value == nil) {
|
||||
return default_value;
|
||||
}
|
||||
NSCAssert([value isKindOfClass:[NSNumber class]], @"value for key \"%@\" must be bool",
|
||||
keyString);
|
||||
return [(NSNumber*)value boolValue];
|
||||
}
|
||||
|
||||
int PreferencesManager::GetInteger(absl::string_view key, int default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (value == nil) {
|
||||
return default_value;
|
||||
}
|
||||
NSCAssert([value isKindOfClass:[NSNumber class]], @"value for key \"%@\" must be int", keyString);
|
||||
return [value integerValue];
|
||||
}
|
||||
|
||||
int64_t PreferencesManager::GetInt64(absl::string_view key, int64_t default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (value == nil) {
|
||||
return default_value;
|
||||
}
|
||||
NSCAssert([value isKindOfClass:[NSNumber class]], @"value for key \"%@\" must be int64_t",
|
||||
keyString);
|
||||
return [value longLongValue];
|
||||
}
|
||||
|
||||
std::string PreferencesManager::GetString(absl::string_view key,
|
||||
const std::string& default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (value == nil) {
|
||||
return default_value;
|
||||
}
|
||||
NSCAssert([value isKindOfClass:[NSString class]], @"value for key \"%@\" must be string",
|
||||
keyString);
|
||||
return [(NSString*)value UTF8String];
|
||||
}
|
||||
|
||||
std::vector<bool> PreferencesManager::GetBooleanArray(absl::string_view key,
|
||||
absl::Span<const bool> default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id array = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (array == nil) {
|
||||
return std::vector<bool>(default_value.begin(), default_value.end());
|
||||
}
|
||||
NSCAssert([array isKindOfClass:[NSArray class]], @"value for key \"%@\" must be array",
|
||||
keyString);
|
||||
std::vector<bool> vector;
|
||||
vector.reserve([array count]);
|
||||
for (id value in array) {
|
||||
NSCAssert([value isKindOfClass:[NSNumber class]],
|
||||
@"all values of array for key \"%@\" must be bool", keyString);
|
||||
vector.push_back([(NSNumber*)value boolValue]);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::vector<int> PreferencesManager::GetIntegerArray(absl::string_view key,
|
||||
absl::Span<const int> default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id array = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (array == nil) {
|
||||
return std::vector<int>(default_value.begin(), default_value.end());
|
||||
}
|
||||
NSCAssert([array isKindOfClass:[NSArray class]], @"value for key \"%@\" must be array",
|
||||
keyString);
|
||||
std::vector<int> vector;
|
||||
vector.reserve([array count]);
|
||||
for (id value in array) {
|
||||
NSCAssert([value isKindOfClass:[NSNumber class]],
|
||||
@"all values of array for key \"%@\" must be bool", keyString);
|
||||
vector.push_back([(NSNumber*)value integerValue]);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::vector<int64_t> PreferencesManager::GetInt64Array(
|
||||
absl::string_view key, absl::Span<const int64_t> default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id array = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (array == nil) {
|
||||
return std::vector<int64_t>(default_value.begin(), default_value.end());
|
||||
}
|
||||
NSCAssert([array isKindOfClass:[NSArray class]], @"value for key \"%@\" must be array",
|
||||
keyString);
|
||||
std::vector<int64_t> vector;
|
||||
vector.reserve([array count]);
|
||||
for (id value in array) {
|
||||
NSCAssert([value isKindOfClass:[NSNumber class]],
|
||||
@"all values of array for key \"%@\" must be bool", keyString);
|
||||
vector.push_back([(NSNumber*)value integerValue]);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::vector<std::string> PreferencesManager::GetStringArray(
|
||||
absl::string_view key, absl::Span<const std::string> default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id array = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (array == nil) {
|
||||
return std::vector<std::string>(default_value.begin(), default_value.end());
|
||||
}
|
||||
NSCAssert([array isKindOfClass:[NSArray class]], @"value for key \"%@\" must be array",
|
||||
keyString);
|
||||
std::vector<std::string> vector;
|
||||
vector.reserve([array count]);
|
||||
for (id value in array) {
|
||||
NSCAssert([value isKindOfClass:[NSString class]],
|
||||
@"all values of array for key \"%@\" must be bool", keyString);
|
||||
vector.push_back([(NSString*)value UTF8String]);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
absl::Time PreferencesManager::GetTime(absl::string_view key, absl::Time default_value) const {
|
||||
NSString* keyString = @(std::string(key).c_str());
|
||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:keyString];
|
||||
if (value == nil) {
|
||||
return default_value;
|
||||
}
|
||||
NSCAssert([value isKindOfClass:[NSDate class]], @"value for key \"%@\" must be time", keyString);
|
||||
return absl::FromUnixNanos([(NSDate*)value timeIntervalSince1970] * NSEC_PER_SEC);
|
||||
}
|
||||
|
||||
// Removes preferences
|
||||
void PreferencesManager::Remove(absl::string_view key) {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@(std::string(key).c_str())];
|
||||
}
|
||||
|
||||
} // namespace nearby::apple
|
||||
@@ -1,40 +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_IMPLEMENTATION_APPLE_PREFERENCES_REPOSITORY_H_
|
||||
#define PLATFORM_IMPLEMENTATION_APPLE_PREFERENCES_REPOSITORY_H_
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
#include "internal/platform/implementation/preferences_repository.h"
|
||||
|
||||
namespace nearby::apple {
|
||||
|
||||
class PreferencesRepository : public api::PreferencesRepository {
|
||||
public:
|
||||
explicit PreferencesRepository(absl::string_view path)
|
||||
: api::PreferencesRepository(path) {}
|
||||
|
||||
nlohmann::json LoadPreferences() override ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
bool SavePreferences(nlohmann::json preferences) override
|
||||
ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
|
||||
private:
|
||||
absl::Mutex mutex_;
|
||||
};
|
||||
|
||||
} // namespace nearby::apple
|
||||
|
||||
#endif // PLATFORM_IMPLEMENTATION_APPLE_PREFERENCES_REPOSITORY_H_
|
||||
@@ -1,32 +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.
|
||||
|
||||
#import "internal/platform/implementation/apple/preferences_repository.h"
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace nearby::apple {
|
||||
|
||||
nlohmann::json PreferencesRepository::LoadPreferences() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return nlohmann::json::object();
|
||||
}
|
||||
|
||||
bool PreferencesRepository::SavePreferences(nlohmann::json preferences) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace nearby::apple
|
||||
@@ -18,7 +18,7 @@ cc_library(
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"log_message.cc",
|
||||
"preferences_repository.cc",
|
||||
"preferences_manager.cc",
|
||||
"scheduled_executor.cc",
|
||||
"system_clock.cc",
|
||||
],
|
||||
@@ -31,13 +31,14 @@ cc_library(
|
||||
"multi_thread_executor.h",
|
||||
"mutex.h",
|
||||
"pipe.h",
|
||||
"preferences_repository.h",
|
||||
"preferences_manager.h",
|
||||
"scheduled_executor.h",
|
||||
"single_thread_executor.h",
|
||||
"timer.h",
|
||||
],
|
||||
visibility = ["//location/nearby/cpp:__subpackages__"],
|
||||
deps = [
|
||||
":preferences_repository",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:test_util",
|
||||
@@ -52,6 +53,7 @@ cc_library(
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_glog//:glog",
|
||||
"@com_google_nisaba//nisaba/port:thread_pool",
|
||||
"@nlohmann_json//:json",
|
||||
@@ -156,11 +158,21 @@ cc_library(
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/platform/implementation/shared:count_down_latch",
|
||||
"//internal/platform/implementation/shared:file",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "preferences_repository",
|
||||
srcs = ["preferences_repository.cc"],
|
||||
hdrs = ["preferences_repository.h"],
|
||||
deps = [
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@nlohmann_json//:json",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "internal/platform/implementation/condition_variable.h"
|
||||
#include "internal/platform/implementation/log_message.h"
|
||||
#include "internal/platform/implementation/mutex.h"
|
||||
#include "internal/platform/implementation/preferences_repository.h"
|
||||
#include "internal/platform/implementation/preferences_manager.h"
|
||||
#include "internal/platform/implementation/scheduled_executor.h"
|
||||
#include "internal/platform/implementation/server_sync.h"
|
||||
#include "internal/platform/implementation/shared/count_down_latch.h"
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "internal/platform/implementation/g3/log_message.h"
|
||||
#include "internal/platform/implementation/g3/multi_thread_executor.h"
|
||||
#include "internal/platform/implementation/g3/mutex.h"
|
||||
#include "internal/platform/implementation/g3/preferences_repository.h"
|
||||
#include "internal/platform/implementation/g3/preferences_manager.h"
|
||||
#include "internal/platform/implementation/g3/scheduled_executor.h"
|
||||
#include "internal/platform/implementation/g3/single_thread_executor.h"
|
||||
#include "internal/platform/implementation/g3/timer.h"
|
||||
@@ -237,9 +237,9 @@ ImplementationPlatform::CreateDeviceInfo() {
|
||||
return std::make_unique<g3::DeviceInfo>();
|
||||
}
|
||||
|
||||
std::unique_ptr<nearby::api::PreferencesRepository>
|
||||
ImplementationPlatform::CreatePreferencesRepository(absl::string_view path) {
|
||||
return std::make_unique<g3::PreferencesRepository>(path);
|
||||
std::unique_ptr<nearby::api::PreferencesManager>
|
||||
ImplementationPlatform::CreatePreferencesManager(absl::string_view path) {
|
||||
return std::make_unique<g3::PreferencesManager>(path);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
// 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/g3/preferences_manager.h"
|
||||
|
||||
#include <filesystem> // NOLINT(build/c++17)
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
#include "internal/platform/implementation/g3/preferences_repository.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
namespace {
|
||||
using json = ::nlohmann::json;
|
||||
} // namespace
|
||||
|
||||
PreferencesManager::PreferencesManager(absl::string_view file_path)
|
||||
: api::PreferencesManager(file_path) {
|
||||
std::optional<std::filesystem::path> path =
|
||||
nearby::api::ImplementationPlatform::CreateDeviceInfo()
|
||||
->GetLocalAppDataPath();
|
||||
if (!path.has_value()) {
|
||||
path = std::filesystem::temp_directory_path();
|
||||
}
|
||||
|
||||
std::filesystem::path full_path = *path / std::string(file_path);
|
||||
preferences_repository_ =
|
||||
std::make_unique<PreferencesRepository>(full_path.string());
|
||||
value_ = preferences_repository_->LoadPreferences();
|
||||
}
|
||||
|
||||
bool PreferencesManager::Set(const std::string& 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_)) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to save preference." << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetValue(absl::string_view key, const json& value) {
|
||||
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 {
|
||||
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) {
|
||||
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;
|
||||
|
||||
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 g3
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,141 @@
|
||||
// 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_G3_PREFERENCES_MANAGER_H_
|
||||
#define PLATFORM_IMPLEMENTATION_G3_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 "nlohmann/json.hpp"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
#include "internal/platform/implementation/g3/preferences_repository.h"
|
||||
#include "internal/platform/implementation/preferences_manager.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
// 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(const std::string& 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 g3
|
||||
} // namespace nearby
|
||||
|
||||
#endif // PLATFORM_IMPLEMENTATION_G3_PREFERENCES_MANAGER_H_
|
||||
@@ -15,30 +15,30 @@
|
||||
#ifndef PLATFORM_IMPLEMENTATION_G3_PREFERENCES_REPOSITORY_H_
|
||||
#define PLATFORM_IMPLEMENTATION_G3_PREFERENCES_REPOSITORY_H_
|
||||
|
||||
#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"
|
||||
#include "internal/platform/implementation/preferences_repository.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
class PreferencesRepository : public api::PreferencesRepository {
|
||||
class PreferencesRepository {
|
||||
public:
|
||||
explicit PreferencesRepository(absl::string_view path)
|
||||
: api::PreferencesRepository(path) {}
|
||||
explicit PreferencesRepository(absl::string_view path) : path_(path) {}
|
||||
|
||||
nlohmann::json LoadPreferences() override ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
bool SavePreferences(nlohmann::json preferences) override
|
||||
ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
nlohmann::json LoadPreferences() ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
bool SavePreferences(nlohmann::json preferences) ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
|
||||
private:
|
||||
// Avoid to write in google3, just create a memory value to simulate a
|
||||
// preferences storage
|
||||
nlohmann::json value_ = nlohmann::json::object();
|
||||
absl::Mutex mutex_;
|
||||
const std::string path_;
|
||||
};
|
||||
|
||||
} // namespace g3
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include "internal/platform/implementation/webrtc.h"
|
||||
#endif
|
||||
#ifndef NEARBY_CHROMIUM
|
||||
#include "internal/platform/implementation/preferences_repository.h"
|
||||
#include "internal/platform/implementation/preferences_manager.h"
|
||||
#endif
|
||||
#include "internal/platform/implementation/wifi.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
@@ -93,7 +93,7 @@ class ImplementationPlatform {
|
||||
static std::unique_ptr<AtomicBoolean> CreateAtomicBoolean(bool initial_value);
|
||||
|
||||
// Supports enums and integers up to 32-bit.
|
||||
// Does not use locking, if platform supports 32-bit atimics natively.
|
||||
// Does not use locking, if platform supports 32-bit atomics natively.
|
||||
// Does not use dynamic memory allocations in operations.
|
||||
static std::unique_ptr<AtomicUint32> CreateAtomicUint32(std::uint32_t value);
|
||||
|
||||
@@ -154,8 +154,8 @@ class ImplementationPlatform {
|
||||
static absl::StatusOr<WebResponse> SendRequest(const WebRequest& request);
|
||||
|
||||
#ifndef NEARBY_CHROMIUM
|
||||
static std::unique_ptr<nearby::api::PreferencesRepository>
|
||||
CreatePreferencesRepository(absl::string_view path);
|
||||
static std::unique_ptr<nearby::api::PreferencesManager>
|
||||
CreatePreferencesManager(absl::string_view path);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// 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_IMPLEMENTATION_PREFERENCE_MANAGER_H_
|
||||
#define PLATFORM_IMPLEMENTATION_PREFERENCE_MANAGER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
// A repository for preferences. The implementations are different on different
|
||||
// platforms.
|
||||
//
|
||||
// The data in preferences has multiple types, such as int, bool, string and
|
||||
// dictionary. Using proto to describe it is a little complicated. In the
|
||||
// repository, we use json as the parser for now.
|
||||
class PreferencesManager {
|
||||
public:
|
||||
explicit PreferencesManager(absl::string_view path) {}
|
||||
virtual ~PreferencesManager() = default;
|
||||
|
||||
// Sets values
|
||||
|
||||
virtual bool Set(const std::string& key, const nlohmann::json& value) = 0;
|
||||
|
||||
virtual bool SetBoolean(absl::string_view key, bool value) = 0;
|
||||
virtual bool SetInteger(absl::string_view key, int value) = 0;
|
||||
virtual bool SetInt64(absl::string_view key, int64_t value) = 0;
|
||||
virtual bool SetString(absl::string_view key, absl::string_view value) = 0;
|
||||
|
||||
virtual bool SetBooleanArray(absl::string_view key,
|
||||
absl::Span<const bool> value) = 0;
|
||||
virtual bool SetIntegerArray(absl::string_view key,
|
||||
absl::Span<const int> value) = 0;
|
||||
virtual bool SetInt64Array(absl::string_view key,
|
||||
absl::Span<const int64_t> value) = 0;
|
||||
virtual bool SetStringArray(absl::string_view key,
|
||||
absl::Span<const std::string> value) = 0;
|
||||
|
||||
virtual bool SetTime(absl::string_view key, absl::Time value) = 0;
|
||||
|
||||
// Gets values
|
||||
virtual nlohmann::json Get(absl::string_view key,
|
||||
const nlohmann::json& default_value) const = 0;
|
||||
|
||||
virtual bool GetBoolean(absl::string_view key, bool default_value) const = 0;
|
||||
virtual int GetInteger(absl::string_view key, int default_value) const = 0;
|
||||
virtual int64_t GetInt64(absl::string_view key,
|
||||
int64_t default_value) const = 0;
|
||||
virtual std::string GetString(absl::string_view key,
|
||||
const std::string& default_value) const = 0;
|
||||
|
||||
virtual std::vector<bool> GetBooleanArray(
|
||||
absl::string_view key, absl::Span<const bool> default_value) const = 0;
|
||||
virtual std::vector<int> GetIntegerArray(
|
||||
absl::string_view key, absl::Span<const int> default_value) const = 0;
|
||||
virtual std::vector<int64_t> GetInt64Array(
|
||||
absl::string_view key, absl::Span<const int64_t> default_value) const = 0;
|
||||
virtual std::vector<std::string> GetStringArray(
|
||||
absl::string_view key,
|
||||
absl::Span<const std::string> default_value) const = 0;
|
||||
|
||||
virtual absl::Time GetTime(absl::string_view key,
|
||||
absl::Time default_value) const = 0;
|
||||
|
||||
// Removes preferences
|
||||
virtual void Remove(absl::string_view key) = 0;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
|
||||
#endif // PLATFORM_IMPLEMENTATION_PREFERENCE_MANAGER_H_
|
||||
@@ -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.
|
||||
|
||||
#ifndef PLATFORM_IMPLEMENTATION_PREFERENCE_REPOSITORY_H_
|
||||
#define PLATFORM_IMPLEMENTATION_PREFERENCE_REPOSITORY_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
// A repository for preferences. The implementations are different on different
|
||||
// platforms.
|
||||
//
|
||||
// The data in preferences has multiple types, such as int, bool, string and
|
||||
// dictionary. Using proto to describe it is a little complicated. In the
|
||||
// repository, we use json as the parser for now.
|
||||
class PreferencesRepository {
|
||||
public:
|
||||
explicit PreferencesRepository(absl::string_view path) : path_(path) {}
|
||||
virtual ~PreferencesRepository() = default;
|
||||
|
||||
virtual nlohmann::json LoadPreferences() = 0;
|
||||
virtual bool SavePreferences(nlohmann::json preferences) = 0;
|
||||
|
||||
protected:
|
||||
std::string path_;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
|
||||
#endif // PLATFORM_IMPLEMENTATION_PREFERENCE_REPOSITORY_H_
|
||||
@@ -33,7 +33,7 @@ cc_library(
|
||||
"log_message.h",
|
||||
"mutex.h",
|
||||
"output_file.h",
|
||||
"preferences_repository.h",
|
||||
"preferences_manager.h",
|
||||
"scheduled_executor.h",
|
||||
"settable_future.h",
|
||||
"submittable_executor.h",
|
||||
@@ -44,16 +44,25 @@ cc_library(
|
||||
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
|
||||
visibility = ["//location/nearby/cpp/sharing/implementation/internal/impl/windows:__pkg__"],
|
||||
deps = [
|
||||
":comm",
|
||||
"//base",
|
||||
"//base:stringprintf",
|
||||
"//internal/base:bluetooth_address",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform:uuid",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/platform/implementation/windows:comm",
|
||||
"//internal/platform/implementation/windows/generated:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@nlohmann_json//:json",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -149,7 +158,9 @@ cc_library(
|
||||
"file_path.cc",
|
||||
"http_loader.cc",
|
||||
"platform.cc",
|
||||
"preferences_manager.cc",
|
||||
"preferences_repository.cc",
|
||||
"preferences_repository.h",
|
||||
"scheduled_executor.cc",
|
||||
"submittable_executor.cc",
|
||||
"system_clock.cc",
|
||||
@@ -194,7 +205,10 @@ cc_library(
|
||||
"//internal/platform/implementation/shared:count_down_latch",
|
||||
"//internal/platform/implementation/shared:file",
|
||||
"//internal/platform/implementation/windows/generated:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
@@ -202,6 +216,8 @@ cc_library(
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@nlohmann_json//:json",
|
||||
],
|
||||
)
|
||||
@@ -241,6 +257,7 @@ cc_test(
|
||||
"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",
|
||||
@@ -255,14 +272,21 @@ cc_test(
|
||||
":crypto",
|
||||
":test_utils",
|
||||
":types",
|
||||
":windows",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform/implementation:comm",
|
||||
"//internal/platform/implementation:platform",
|
||||
"//internal/platform/implementation/windows",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/platform/implementation/shared:count_down_latch",
|
||||
"//internal/platform/implementation/windows/generated:types",
|
||||
"@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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "internal/platform/implementation/windows/listenable_future.h"
|
||||
#include "internal/platform/implementation/windows/log_message.h"
|
||||
#include "internal/platform/implementation/windows/mutex.h"
|
||||
#include "internal/platform/implementation/windows/preferences_repository.h"
|
||||
#include "internal/platform/implementation/windows/preferences_manager.h"
|
||||
#include "internal/platform/implementation/windows/scheduled_executor.h"
|
||||
#include "internal/platform/implementation/windows/server_sync.h"
|
||||
#include "internal/platform/implementation/windows/settable_future.h"
|
||||
@@ -320,9 +320,9 @@ std::unique_ptr<DeviceInfo> ImplementationPlatform::CreateDeviceInfo() {
|
||||
return std::make_unique<windows::DeviceInfo>();
|
||||
}
|
||||
|
||||
std::unique_ptr<nearby::api::PreferencesRepository>
|
||||
ImplementationPlatform::CreatePreferencesRepository(absl::string_view path) {
|
||||
return std::make_unique<windows::PreferencesRepository>(path);
|
||||
std::unique_ptr<nearby::api::PreferencesManager>
|
||||
ImplementationPlatform::CreatePreferencesManager(absl::string_view path) {
|
||||
return std::make_unique<windows::PreferencesManager>(path);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
// 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/windows/preferences_manager.h"
|
||||
|
||||
#include <filesystem> // NOLINT(build/c++17)
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
#include "internal/platform/implementation/windows/preferences_repository.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
using json = ::nlohmann::json;
|
||||
} // namespace
|
||||
|
||||
PreferencesManager::PreferencesManager(absl::string_view file_path)
|
||||
: api::PreferencesManager(file_path) {
|
||||
std::optional<std::filesystem::path> path =
|
||||
nearby::api::ImplementationPlatform::CreateDeviceInfo()
|
||||
->GetLocalAppDataPath();
|
||||
if (!path.has_value()) {
|
||||
path = std::filesystem::temp_directory_path();
|
||||
}
|
||||
|
||||
std::filesystem::path full_path = *path / std::string(file_path);
|
||||
preferences_repository_ =
|
||||
std::make_unique<PreferencesRepository>(full_path.string());
|
||||
value_ = preferences_repository_->LoadPreferences();
|
||||
}
|
||||
|
||||
bool PreferencesManager::Set(const std::string& 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_)) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to save preference." << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PreferencesManager::SetValue(absl::string_view key, const json& value) {
|
||||
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 {
|
||||
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) {
|
||||
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;
|
||||
|
||||
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 windows
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,141 @@
|
||||
// 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_WINDOWS_PREFERENCES_MANAGER_H_
|
||||
#define PLATFORM_IMPLEMENTATION_WINDOWS_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 "nlohmann/json.hpp"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
#include "internal/platform/implementation/preferences_manager.h"
|
||||
#include "internal/platform/implementation/windows/preferences_repository.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
// 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(const std::string& 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 windows
|
||||
} // namespace nearby
|
||||
|
||||
#endif // PLATFORM_IMPLEMENTATION_WINDOWS_PREFERENCES_MANAGER_H_
|
||||
@@ -0,0 +1,186 @@
|
||||
// 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/windows/preferences_manager.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <filesystem> // NOLINT(build/c++17)
|
||||
#include <fstream>
|
||||
#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"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
using json = ::nlohmann::json;
|
||||
constexpr absl::Duration kTimeOut = absl::Milliseconds(200);
|
||||
constexpr char kPreferencesFilePath[] = "Google/Nearby/Sharing";
|
||||
} // namespace
|
||||
|
||||
TEST(PreferencesManager, CorruptedConfigFile) {
|
||||
std::filesystem::path settingsPath =
|
||||
std::filesystem::temp_directory_path() / "settings.json";
|
||||
std::ofstream output_stream{settingsPath};
|
||||
output_stream << "{\"data\":8, \"names\": [\"In valid\"}" << std::endl;
|
||||
output_stream.close();
|
||||
|
||||
// Should use an empty setting for a corrupted configuration file.
|
||||
EXPECT_EQ(PreferencesManager(kPreferencesFilePath).GetInteger("data", 100),
|
||||
100);
|
||||
}
|
||||
|
||||
TEST(PreferencesManager, ValidConfigFile) {
|
||||
std::filesystem::path settingsPath =
|
||||
std::filesystem::temp_directory_path() / "settings.json";
|
||||
std::ofstream output_stream{settingsPath};
|
||||
output_stream << "{\"data\":8, \"name\": \"Valid\"}" << std::endl;
|
||||
output_stream.close();
|
||||
|
||||
// Should use an empty setting for a corrupted configuration file.
|
||||
EXPECT_EQ(PreferencesManager(kPreferencesFilePath).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 windows
|
||||
} // namespace nearby
|
||||
@@ -16,30 +16,30 @@
|
||||
#define PLATFORM_IMPLEMENTATION_WINDOWS_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"
|
||||
#include "internal/platform/implementation/preferences_repository.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
class PreferencesRepository : public api::PreferencesRepository {
|
||||
class PreferencesRepository {
|
||||
public:
|
||||
explicit PreferencesRepository(absl::string_view path)
|
||||
: api::PreferencesRepository(path) {}
|
||||
explicit PreferencesRepository(absl::string_view path) : path_(path) {}
|
||||
|
||||
nlohmann::json LoadPreferences() override ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
bool SavePreferences(nlohmann::json preferences) override
|
||||
ABSL_LOCKS_EXCLUDED(&mutex_);
|
||||
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 windows
|
||||
|
||||
Reference in New Issue
Block a user