mirror of
https://github.com/openharmony/ace_ace_engine.git
synced 2026-07-19 22:54:50 -04:00
!2158 add distributedstorage support
Merge pull request !2158 from 何溯/dev
This commit is contained in:
@@ -26,11 +26,13 @@ template("ace_capability_ohos_source_set") {
|
||||
|
||||
sources = [
|
||||
"clipboard/clipboard_impl.cpp",
|
||||
"distributed/storage/distributed_storage.cpp",
|
||||
"preference/storage_impl.cpp",
|
||||
]
|
||||
include_dirs = [ "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_preferences/include/" ]
|
||||
external_deps = [
|
||||
"ability_base:want",
|
||||
"distributeddataobject:distributeddataobject_impl",
|
||||
"ipc:ipc_core",
|
||||
"native_appdatamgr:native_preferences",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
*
|
||||
* http://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 "adapter/ohos/capability/distributed/storage/distributed_storage.h"
|
||||
|
||||
#include "distributed_object.h"
|
||||
#include "distributed_objectstore.h"
|
||||
#include "objectstore_errors.h"
|
||||
|
||||
#include "base/log/log.h"
|
||||
#include "core/common/ace_application_info.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class DistributedObjectWatch final : public OHOS::ObjectStore::ObjectWatcher {
|
||||
public:
|
||||
DistributedObjectWatch(const std::string& sessionId, OnDataChangeCallback&& onChange)
|
||||
{
|
||||
onChange_ = std::move(onChange);
|
||||
}
|
||||
|
||||
void OnChanged(const std::string& sessionid, const std::vector<std::string>& changedData) override
|
||||
{
|
||||
if (onChange_) {
|
||||
onChange_(sessionid, changedData);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
OnDataChangeCallback onChange_;
|
||||
};
|
||||
|
||||
class DistributedObjectStatusNotifier final : public OHOS::ObjectStore::StatusNotifier {
|
||||
public:
|
||||
explicit DistributedObjectStatusNotifier(ObjectStatusNotifyCallback&& onNotify)
|
||||
{
|
||||
onNotify_ = std::move(onNotify);
|
||||
}
|
||||
void OnChanged(const std::string& sessionId, const std::string& networkId, const std::string& onlineStatus) override
|
||||
{
|
||||
LOGI("DistributedObjectStatusNotifier [%{public}s-%{public}s]", sessionId.c_str(), onlineStatus.c_str());
|
||||
if (onNotify_) {
|
||||
onNotify_(sessionId, onlineStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectStatusNotifyCallback onNotify_;
|
||||
};
|
||||
|
||||
DistributedObjectPtr::DistributedObjectPtr(const std::string& sessionId, OnDataChangeCallback&& onChange)
|
||||
{
|
||||
std::string bundleName = AceApplicationInfo::GetInstance().GetProcessName();
|
||||
if (bundleName.empty()) {
|
||||
LOGE("DistributedObjectStore bundleName is empty!");
|
||||
return;
|
||||
}
|
||||
OHOS::ObjectStore::DistributedObjectStore* store =
|
||||
OHOS::ObjectStore::DistributedObjectStore::GetInstance(bundleName);
|
||||
if (store == nullptr) {
|
||||
LOGE("DistributedObjectStore GetInstance failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
static std::once_flag onceFlag;
|
||||
std::call_once(onceFlag, [store]() {
|
||||
auto callback = [](const std::string& sessionId, const std::string& onlineStatus) {
|
||||
DistributedStorage::OnStatusNotify(sessionId, onlineStatus);
|
||||
};
|
||||
store->SetStatusNotifier(std::make_shared<DistributedObjectStatusNotifier>(callback));
|
||||
});
|
||||
|
||||
uint32_t ret = store->Get(sessionId, object_);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGW("DistributedObjectStore get object[%{private}s] failed, try to create", sessionId.c_str());
|
||||
object_ = store->CreateObject(sessionId);
|
||||
if (object_ == nullptr) {
|
||||
LOGE("DistributedObjectStore CreateObject failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sessionId_ = sessionId;
|
||||
watcher_ = std::make_shared<DistributedObjectWatch>(sessionId, std::move(onChange));
|
||||
ret = store->Watch(object_, watcher_);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("DistributedObjectStore Watch failed!, err=[%{private}u", ret);
|
||||
}
|
||||
LOGI("DistributedObjectPtr init success[%{public}s]", sessionId_.c_str());
|
||||
}
|
||||
|
||||
DistributedObjectPtr::~DistributedObjectPtr()
|
||||
{
|
||||
if (object_ != nullptr) {
|
||||
std::string bundleName = AceApplicationInfo::GetInstance().GetProcessName();
|
||||
OHOS::ObjectStore::DistributedObjectStore* store =
|
||||
OHOS::ObjectStore::DistributedObjectStore::GetInstance(bundleName);
|
||||
if (store == nullptr) {
|
||||
LOGE("DistributedObjectStore GetInstance failed!");
|
||||
return;
|
||||
}
|
||||
uint32_t ret = store->UnWatch(object_);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("DistributedObjectStore UnWatch failed!, err=[%{private}u", ret);
|
||||
}
|
||||
ret = OHOS::ObjectStore::SUCCESS;
|
||||
ret = store->DeleteObject(sessionId_);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("DistributedObjectStore DeleteObject failed!, err=[%{private}u", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OHOS::ObjectStore::DistributedObject* DistributedObjectPtr::GetRawPtr()
|
||||
{
|
||||
return object_;
|
||||
}
|
||||
|
||||
std::map<std::string, RefPtr<DistributedStorage>> DistributedStorage::storageMap_;
|
||||
|
||||
void DistributedStorage::AddStorage(const std::string& sessionId, RefPtr<DistributedStorage> storage)
|
||||
{
|
||||
storageMap_.try_emplace(sessionId, storage);
|
||||
}
|
||||
|
||||
void DistributedStorage::DeleteStorage(const std::string& sessionId)
|
||||
{
|
||||
storageMap_.erase(sessionId);
|
||||
}
|
||||
|
||||
void DistributedStorage::OnStatusNotify(const std::string& sessionId, const std::string& status)
|
||||
{
|
||||
auto storage = storageMap_.find(sessionId);
|
||||
if (storage != storageMap_.end()) {
|
||||
storage->second->NotifyStatus(status);
|
||||
}
|
||||
}
|
||||
|
||||
bool DistributedStorage::Init(std::function<void(const std::string&)>&& notifyCallback)
|
||||
{
|
||||
notifyCallback_ = std::move(notifyCallback);
|
||||
auto onChangeCallback = [weak = WeakClaim(this)](
|
||||
const std::string& sessionid, const std::vector<std::string>& changedData) {
|
||||
auto storage = weak.Upgrade();
|
||||
for (auto& key : changedData) {
|
||||
storage->OnDataChange(key);
|
||||
}
|
||||
};
|
||||
objectPtr_ = std::make_unique<DistributedObjectPtr>(sessionId_, std::move(onChangeCallback));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DistributedStorage::SetString(const std::string& key, const std::string& value)
|
||||
{
|
||||
auto ret = objectPtr_->GetRawPtr()->PutString(key, value);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Set string failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
}
|
||||
}
|
||||
|
||||
std::string DistributedStorage::GetString(const std::string& key)
|
||||
{
|
||||
std::string value;
|
||||
auto ret = objectPtr_->GetRawPtr()->GetString(key, value);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Get string failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void DistributedStorage::SetDouble(const std::string& key, const double value)
|
||||
{
|
||||
auto ret = objectPtr_->GetRawPtr()->PutDouble(key, value);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Set Double failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
}
|
||||
}
|
||||
|
||||
bool DistributedStorage::GetDouble(const std::string& key, double& value)
|
||||
{
|
||||
auto ret = objectPtr_->GetRawPtr()->GetDouble(key, value);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Get double failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DistributedStorage::SetBoolean(const std::string& key, const bool value)
|
||||
{
|
||||
auto ret = objectPtr_->GetRawPtr()->PutBoolean(key, value);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Set Boolean failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
}
|
||||
}
|
||||
|
||||
bool DistributedStorage::GetBoolean(const std::string& key, bool& value)
|
||||
{
|
||||
auto ret = objectPtr_->GetRawPtr()->GetBoolean(key, value);
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Get Boolean failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Storage::DataType DistributedStorage::GetDataType(const std::string& key)
|
||||
{
|
||||
OHOS::ObjectStore::Type type = OHOS::ObjectStore::Type::TYPE_STRING;
|
||||
auto ret = objectPtr_->GetRawPtr()->GetType(key, type);
|
||||
|
||||
if (ret != OHOS::ObjectStore::SUCCESS) {
|
||||
LOGE("Get type failed! sessionId=[%{private}s], key=[%{private}s], err=[%{private}u", sessionId_.c_str(),
|
||||
key.c_str(), ret);
|
||||
return Storage::DataType::NONE;
|
||||
}
|
||||
|
||||
Storage::DataType dataType = Storage::DataType::NONE;
|
||||
switch (type) {
|
||||
case OHOS::ObjectStore::Type::TYPE_STRING:
|
||||
dataType = Storage::DataType::STRING;
|
||||
break;
|
||||
case OHOS::ObjectStore::Type::TYPE_BOOLEAN:
|
||||
dataType = Storage::DataType::BOOLEAN;
|
||||
break;
|
||||
case OHOS::ObjectStore::Type::TYPE_DOUBLE:
|
||||
dataType = Storage::DataType::DOUBLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
||||
void DistributedStorage::NotifyStatus(const std::string& status)
|
||||
{
|
||||
if (!taskExecutor_) {
|
||||
return;
|
||||
}
|
||||
LOGI("DistributedStorage::NotifyStatus [%{public}s-%{public}s]", sessionId_.c_str(), status.c_str());
|
||||
taskExecutor_->PostTask(
|
||||
[weak = WeakClaim(this), status] {
|
||||
auto storage = weak.Upgrade();
|
||||
if (storage && storage->notifyCallback_) {
|
||||
storage->notifyCallback_(status);
|
||||
}
|
||||
},
|
||||
TaskExecutor::TaskType::JS);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
*
|
||||
* http://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 FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_DISTRIBUTED_STORAGE_DISTRIBUTED_STORAGE_H
|
||||
#define FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_DISTRIBUTED_STORAGE_DISTRIBUTED_STORAGE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "core/common/storage/storage.h"
|
||||
|
||||
namespace OHOS::ObjectStore {
|
||||
class DistributedObject;
|
||||
class ObjectWatcher;
|
||||
} // namespace OHOS::ObjectStore
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
using OnDataChangeCallback = std::function<void(const std::string&, const std::vector<std::string>&)>;
|
||||
using ObjectStatusNotifyCallback = std::function<void(const std::string&, const std::string&)>;
|
||||
|
||||
class DistributedObjectPtr final {
|
||||
public:
|
||||
DistributedObjectPtr(const std::string& sessionId, OnDataChangeCallback&& onChange);
|
||||
~DistributedObjectPtr();
|
||||
|
||||
OHOS::ObjectStore::DistributedObject* GetRawPtr();
|
||||
|
||||
private:
|
||||
std::string sessionId_;
|
||||
OHOS::ObjectStore::DistributedObject* object_ = nullptr;
|
||||
std::shared_ptr<OHOS::ObjectStore::ObjectWatcher> watcher_;
|
||||
};
|
||||
|
||||
class DistributedStorage final : public Storage {
|
||||
DECLARE_ACE_TYPE(DistributedStorage, Storage);
|
||||
|
||||
public:
|
||||
explicit DistributedStorage(const std::string& sessionId, const RefPtr<TaskExecutor>& taskExecutor)
|
||||
: Storage(taskExecutor), sessionId_(sessionId)
|
||||
{}
|
||||
~DistributedStorage() override = default;
|
||||
|
||||
bool Init(std::function<void(const std::string&)>&& notifier);
|
||||
|
||||
void SetString(const std::string& key, const std::string& value) override;
|
||||
std::string GetString(const std::string& key) override;
|
||||
void SetDouble(const std::string& key, const double value) override;
|
||||
bool GetDouble(const std::string& key, double& value) override;
|
||||
void SetBoolean(const std::string& key, const bool value) override;
|
||||
bool GetBoolean(const std::string& key, bool& value) override;
|
||||
DataType GetDataType(const std::string& key) override;
|
||||
void Clear() override {}
|
||||
void Delete(const std::string& key) override {}
|
||||
void NotifyStatus(const std::string& status);
|
||||
|
||||
static void AddStorage(const std::string& sessionId, RefPtr<DistributedStorage> storage);
|
||||
static void DeleteStorage(const std::string& sessionId);
|
||||
static void OnStatusNotify(const std::string& sessionId, const std::string& status);
|
||||
|
||||
private:
|
||||
std::unique_ptr<DistributedObjectPtr> objectPtr_;
|
||||
std::string sessionId_;
|
||||
std::function<void(const std::string&)> notifyCallback_;
|
||||
|
||||
static std::map<std::string, RefPtr<DistributedStorage>> storageMap_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_DISTRIBUTED_STORAGE_DISTRIBUTED_STORAGE_H
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
*
|
||||
* http://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 FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_DISTRIBUTED_STORAGE_DISTRIBUTED_STORAGE_INTERFACE_H
|
||||
#define FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_DISTRIBUTED_STORAGE_DISTRIBUTED_STORAGE_INTERFACE_H
|
||||
|
||||
#include "adapter/ohos/capability/distributed/storage/distributed_storage.h"
|
||||
#include "base/memory/referenced.h"
|
||||
#include "core/common/storage/storage_interface.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class DistributedStorageInterface final : public StorageInterface {
|
||||
public:
|
||||
~DistributedStorageInterface() override = default;
|
||||
|
||||
RefPtr<Storage> GetStorage(const std::string& sessionId, std::function<void(const std::string&)>&& notifier,
|
||||
const RefPtr<TaskExecutor>& taskExecutor) const override
|
||||
{
|
||||
auto storage = Referenced::MakeRefPtr<DistributedStorage>(sessionId, taskExecutor);
|
||||
if (!storage->Init(std::move(notifier))) {
|
||||
return nullptr;
|
||||
}
|
||||
DistributedStorage::AddStorage(sessionId, storage);
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_DISTRIBUTED_STORAGE_DISTRIBUTED_STORAGE_INTERFACE_H
|
||||
@@ -22,7 +22,7 @@ std::shared_ptr<NativePreferences::Preferences> StorageImpl::GetPreference(const
|
||||
return NativePreferences::PreferencesHelper::GetPreferences(fileName, errCode_);
|
||||
}
|
||||
|
||||
void StorageImpl::Set(const std::string& key, const std::string& value)
|
||||
void StorageImpl::SetString(const std::string& key, const std::string& value)
|
||||
{
|
||||
std::shared_ptr<NativePreferences::Preferences> pref = GetPreference(fileName_);
|
||||
if (!pref) {
|
||||
@@ -34,7 +34,7 @@ void StorageImpl::Set(const std::string& key, const std::string& value)
|
||||
pref->Flush();
|
||||
}
|
||||
|
||||
std::string StorageImpl::Get(const std::string& key)
|
||||
std::string StorageImpl::GetString(const std::string& key)
|
||||
{
|
||||
std::shared_ptr<NativePreferences::Preferences> pref = GetPreference(fileName_);
|
||||
if (!pref) {
|
||||
|
||||
@@ -37,8 +37,20 @@ public:
|
||||
};
|
||||
~StorageImpl() override = default;
|
||||
|
||||
void Set(const std::string& key, const std::string& value) override;
|
||||
std::string Get(const std::string& key) override;
|
||||
void SetString(const std::string& key, const std::string& value) override;
|
||||
std::string GetString(const std::string& key) override;
|
||||
void SetDouble(const std::string& key, const double value) override
|
||||
{}
|
||||
bool GetDouble(const std::string& key, double& value) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void SetBoolean(const std::string& key, const bool value) override
|
||||
{}
|
||||
bool GetBoolean(const std::string& key, bool& value) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void Clear() override;
|
||||
void Delete(const std::string& key) override;
|
||||
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
#include "adapter/ohos/entrance/capability_registry.h"
|
||||
|
||||
#include "adapter/ohos/capability/clipboard/clipboard_impl.h"
|
||||
#include "adapter/ohos/capability/distributed/storage/distributed_storage_interface.h"
|
||||
#include "adapter/ohos/capability/preference/storage_impl.h"
|
||||
#include "core/common/clipboard/clipboard_proxy.h"
|
||||
#include "core/common/storage/storage_proxy.h"
|
||||
#include "adapter/ohos/capability/preference/storage_impl.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
@@ -26,6 +27,7 @@ void CapabilityRegistry::Register()
|
||||
{
|
||||
ClipboardProxy::GetInstance()->SetDelegate(std::make_unique<ClipboardProxyImpl>());
|
||||
StorageProxy::GetInstance()->SetDelegate(std::make_unique<StorageProxyImpl>());
|
||||
StorageProxy::GetInstance()->SetDistributedDelegate(std::make_unique<DistributedStorageInterface>());
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -145,6 +145,7 @@ template("declarative_js_engine") {
|
||||
"jsview/js_counter.cpp",
|
||||
"jsview/js_data_panel.cpp",
|
||||
"jsview/js_datepicker.cpp",
|
||||
"jsview/js_distributed.cpp",
|
||||
"jsview/js_divider.cpp",
|
||||
"jsview/js_ellipse.cpp",
|
||||
"jsview/js_environment.cpp",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_counter.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_data_panel.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_datepicker.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_distributed.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_divider.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_ellipse.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_environment.h"
|
||||
@@ -1082,6 +1083,7 @@ void JsRegisterViews(BindingTarget globalObj)
|
||||
JSCustomDialogController::JSBind(globalObj);
|
||||
JSShareData::JSBind(globalObj);
|
||||
JSPersistent::JSBind(globalObj);
|
||||
JSDistributed::JSBind(globalObj);
|
||||
JSScroller::JSBind(globalObj);
|
||||
|
||||
JSProfiler::JSBind(globalObj);
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_counter.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_data_panel.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_datepicker.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_distributed.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_divider.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_ellipse.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_environment.h"
|
||||
@@ -876,6 +877,7 @@ void JsRegisterViews(BindingTarget globalObj)
|
||||
JSBlank::JSBind(globalObj);
|
||||
JSCalendar::JSBind(globalObj);
|
||||
JSPersistent::JSBind(globalObj);
|
||||
JSDistributed::JSBind(globalObj);
|
||||
JSRadio::JSBind(globalObj);
|
||||
JSCalendarController::JSBind(globalObj);
|
||||
JSRenderingContext::JSBind(globalObj);
|
||||
|
||||
@@ -1991,6 +1991,157 @@ class PersistentStorage {
|
||||
}
|
||||
}
|
||||
PersistentStorage.Instance_ = undefined;
|
||||
|
||||
class DistributedStorage {
|
||||
constructor(sessionId, statusNotifier) {
|
||||
this.links_ = new Map();
|
||||
this.id_ = SubscriberManager.Get().MakeId();
|
||||
SubscriberManager.Get().add(this);
|
||||
this.aviliable_ = false;
|
||||
this.storage_ = new DistributedObject(sessionId, this);
|
||||
this.notifier_ = statusNotifier;
|
||||
}
|
||||
keys() {
|
||||
let result = [];
|
||||
const it = this.links_.keys();
|
||||
let val = it.next();
|
||||
while (!val.done) {
|
||||
result.push(val.value);
|
||||
val = it.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
distributeProp(propName, defaultValue) {
|
||||
if (this.link(propName, defaultValue)) {
|
||||
console.debug(`DistributedStorage: writing '${propName}' - '${this.links_.get(propName)}' to storage`);
|
||||
}
|
||||
}
|
||||
distributeProps(properties) {
|
||||
properties.forEach(property => this.link(property.key, property.defaultValue));
|
||||
}
|
||||
link(propName, defaultValue) {
|
||||
if (defaultValue == null || defaultValue == undefined) {
|
||||
console.error(`DistributedStorage: linkProp for ${propName} called with 'null' or 'undefined' default value!`);
|
||||
return false;
|
||||
}
|
||||
if (this.links_.get(propName)) {
|
||||
console.warn(`DistributedStorage: linkProp: ${propName} is already exist`);
|
||||
return false;
|
||||
}
|
||||
let link = AppStorage.GetOrCreate().link(propName, this);
|
||||
if (link) {
|
||||
console.debug(`DistributedStorage: linkProp ${propName} in AppStorage, using that`);
|
||||
this.links_.set(propName, link);
|
||||
this.setDistributedProp(propName, defaultValue);
|
||||
}
|
||||
else {
|
||||
let returnValue = defaultValue;
|
||||
if (this.aviliable_) {
|
||||
let newValue = this.getDistributedProp(propName);
|
||||
if (newValue == null) {
|
||||
console.debug(`DistributedStorage: no entry for ${propName}, will initialize with default value`);
|
||||
this.setDistributedProp(propName, defaultValue);
|
||||
}
|
||||
else {
|
||||
returnValue = newValue;
|
||||
}
|
||||
}
|
||||
link = AppStorage.GetOrCreate().setAndLink(propName, returnValue, this);
|
||||
this.links_.set(propName, link);
|
||||
console.debug(`DistributedStorage: created new linkProp prop for ${propName}`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
deleteProp(propName) {
|
||||
let link = this.links_.get(propName);
|
||||
if (link) {
|
||||
link.aboutToBeDeleted();
|
||||
this.links_.delete(propName);
|
||||
if (this.aviliable_) {
|
||||
this.storage_.delete(propName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(`DistributedStorage: '${propName}' is not a distributed property warning.`);
|
||||
}
|
||||
}
|
||||
write(key) {
|
||||
let link = this.links_.get(key);
|
||||
if (link) {
|
||||
console.info(`DistributedStorage: write ${key}-${JSON.stringify(link.get())} `);
|
||||
this.setDistributedProp(key, link.get())
|
||||
}
|
||||
}
|
||||
// public required by the interface, use the static method instead!
|
||||
aboutToBeDeleted() {
|
||||
console.debug("DistributedStorage: about to be deleted");
|
||||
this.links_.forEach((val, key, map) => {
|
||||
console.debug(`DistributedStorage: removing ${key}`);
|
||||
val.aboutToBeDeleted();
|
||||
});
|
||||
this.links_.clear();
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
id__() {
|
||||
return this.id_;
|
||||
}
|
||||
propertyHasChanged(info) {
|
||||
console.info(`DistributedStorage: property changed info:${JSON.stringify(info)} `);
|
||||
this.write(info);
|
||||
}
|
||||
onDataOnChange(propName) {
|
||||
let link = this.links_.get(propName);
|
||||
let newValue = this.getDistributedProp(propName);
|
||||
if (link && newValue != null) {
|
||||
console.info(`DistributedStorage: dataOnChange[${propName}-${newValue}]`);
|
||||
link.set(newValue)
|
||||
}
|
||||
}
|
||||
onConnected(status) {
|
||||
console.info(`DistributedStorage onConnected: status = ${status}`);
|
||||
if (!this.aviliable_) {
|
||||
this.syncProp();
|
||||
this.aviliable_ = true;
|
||||
}
|
||||
if (this.notifier_ != null) {
|
||||
this.notifier_(status);
|
||||
}
|
||||
}
|
||||
syncProp() {
|
||||
this.links_.forEach((val, key) => {
|
||||
let newValue = this.getDistributedProp(key);
|
||||
if (newValue == null) {
|
||||
this.setDistributedProp(key, val.get());
|
||||
} else {
|
||||
val.set(newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
setDistributedProp(key, value) {
|
||||
if (!this.aviliable_) {
|
||||
console.warn(`DistributedStorage is not aviliable`);
|
||||
return;
|
||||
}
|
||||
if (typeof value == 'object') {
|
||||
this.storage_.set(key, JSON.stringify(value));
|
||||
return;
|
||||
}
|
||||
this.storage_.set(key, value);
|
||||
}
|
||||
getDistributedProp(key) {
|
||||
let value = this.storage_.get(key);
|
||||
if (typeof value == 'string') {
|
||||
try {
|
||||
let returnValue = JSON.parse(value);
|
||||
return returnValue;
|
||||
}
|
||||
finally {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_checkbox.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_checkboxgroup.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_clipboard.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_distributed.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_hyperlink.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_offscreen_rendering_context.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_path2d.h"
|
||||
@@ -771,6 +772,7 @@ void JsRegisterViews(BindingTarget globalObj)
|
||||
JSPanHandler::JSBind(globalObj);
|
||||
JsDragFunction::JSBind(globalObj);
|
||||
JSPersistent::JSBind(globalObj);
|
||||
JSDistributed::JSBind(globalObj);
|
||||
JSClipboard::JSBind(globalObj);
|
||||
|
||||
JSProfiler::JSBind(globalObj);
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
*
|
||||
* http://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 "bridge/declarative_frontend/jsview/js_distributed.h"
|
||||
|
||||
#include "base/memory/referenced.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_view_common_def.h"
|
||||
#include "core/common/ace_engine.h"
|
||||
#include "core/common/container.h"
|
||||
#include "core/common/container_scope.h"
|
||||
#include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h"
|
||||
|
||||
namespace OHOS::Ace::Framework {
|
||||
|
||||
void JSDistributed::JSBind(BindingTarget globalObj)
|
||||
{
|
||||
JSClass<JSDistributed>::Declare("DistributedObject");
|
||||
JSClass<JSDistributed>::CustomMethod("set", &JSDistributed::Set);
|
||||
JSClass<JSDistributed>::CustomMethod("get", &JSDistributed::Get);
|
||||
JSClass<JSDistributed>::CustomMethod("delete", &JSDistributed::Delete);
|
||||
JSClass<JSDistributed>::Bind(globalObj, JSDistributed::ConstructorCallback, JSDistributed::DestructorCallback);
|
||||
}
|
||||
|
||||
void JSDistributed::ConstructorCallback(const JSCallbackInfo& args)
|
||||
{
|
||||
std::string sessionId;
|
||||
if (args.Length() > 0 && args[0]->IsString() && args[1]->IsObject()) {
|
||||
sessionId = args[0]->ToString();
|
||||
LOGE("sessionId %{public}s", sessionId.c_str());
|
||||
auto distributed = Referenced::MakeRefPtr<JSDistributed>(sessionId);
|
||||
distributed->IncRefCount();
|
||||
distributed->Init(JSRef<JSObject>::Cast(args[1]), sessionId);
|
||||
args.SetReturnValue(Referenced::RawPtr(distributed));
|
||||
}
|
||||
}
|
||||
|
||||
void JSDistributed::DestructorCallback(JSDistributed* distributed)
|
||||
{
|
||||
if (distributed != nullptr) {
|
||||
distributed->DecRefCount();
|
||||
}
|
||||
}
|
||||
|
||||
void JSDistributed::Set(const JSCallbackInfo& args)
|
||||
{
|
||||
#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
|
||||
LOGW("[Engine Log] Unable to use the DistributedStorage in the Previewer. Perform this operation on the "
|
||||
"emulator or a real device instead.");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (args.Length() < 2) {
|
||||
LOGW("fail to set distributed data");
|
||||
return;
|
||||
}
|
||||
if (!stroage_) {
|
||||
LOGW("distributed stroage is null, faid to set distributed data");
|
||||
return;
|
||||
}
|
||||
std::string key = args[0]->ToString();
|
||||
if (args[1]->IsBoolean()) {
|
||||
auto val = args[1]->ToBoolean();
|
||||
LOGW("JSDistributed::Set [%{public}s--%{public}d]", key.c_str(), val);
|
||||
stroage_->SetBoolean(key, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[1]->IsNumber()) {
|
||||
auto val = args[1]->ToNumber<double>();
|
||||
LOGW("JSDistributed::Set [%{public}s--%{public}lf]", key.c_str(), val);
|
||||
stroage_->SetDouble(key, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[1]->IsString()) {
|
||||
auto val = args[1]->ToString();
|
||||
LOGW("JSDistributed::Set [%{public}s--%{public}s]", key.c_str(), val.c_str());
|
||||
stroage_->SetString(key, val);
|
||||
return;
|
||||
}
|
||||
LOGW("JSDistributed::Set type not support [%{public}s]", key.c_str());
|
||||
}
|
||||
|
||||
void JSDistributed::Get(const JSCallbackInfo& args)
|
||||
{
|
||||
#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
|
||||
LOGW("[Engine Log] Unable to use the DistributedStorage in the Previewer. Perform this operation on the "
|
||||
"emulator or a real device instead.");
|
||||
return;
|
||||
#endif
|
||||
if (args.Length() < 1) {
|
||||
LOGW("fail to Get distributed data");
|
||||
return;
|
||||
}
|
||||
std::string key = args[0]->ToString();
|
||||
LOGW("JSDistributed::Get [%{public}s]", key.c_str());
|
||||
|
||||
if (!stroage_) {
|
||||
LOGW("distributed stroage is null, faid to set distributed data");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dataType = stroage_->GetDataType(key);
|
||||
JSVal returnValue = JSVal();
|
||||
|
||||
switch (dataType) {
|
||||
case Storage::DataType::STRING: {
|
||||
auto value = stroage_->GetString(key);
|
||||
if (!value.empty()) {
|
||||
returnValue = JSVal(ToJSValue(value));
|
||||
LOGE("Get distributed data success, key = [%{public}s] value = [%{public}s]", key.c_str(),
|
||||
value.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Storage::DataType::DOUBLE: {
|
||||
double value = 0.0;
|
||||
if (stroage_->GetDouble(key, value)) {
|
||||
returnValue = JSVal(ToJSValue(value));
|
||||
LOGE("Get distributed data success, key = [%{public}s] value = [%{public}lf]", key.c_str(), value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Storage::DataType::BOOLEAN: {
|
||||
bool value = false;
|
||||
if (stroage_->GetBoolean(key, value)) {
|
||||
returnValue = JSVal(ToJSValue(value));
|
||||
LOGE("Get distributed data success, key = [%{public}s] value = [%{public}d]", key.c_str(), value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (returnValue.IsEmpty()) {
|
||||
LOGE("fail to Get distributed data, key = [%{public}s]", key.c_str());
|
||||
return;
|
||||
}
|
||||
auto returnPtr = JSRef<JSVal>::Make(returnValue);
|
||||
args.SetReturnValue(returnPtr);
|
||||
}
|
||||
|
||||
void JSDistributed::Delete(const JSCallbackInfo& args)
|
||||
{
|
||||
#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
|
||||
LOGW("[Engine Log] Unable to use the DistributedStorage in the Previewer. Perform this operation on the "
|
||||
"emulator or a real device instead.");
|
||||
return;
|
||||
#endif
|
||||
if (args.Length() < 1) {
|
||||
LOGW("fail to Delete distributed data");
|
||||
return;
|
||||
}
|
||||
std::string key = args[0]->ToString();
|
||||
stroage_->Delete(key);
|
||||
}
|
||||
|
||||
void JSDistributed::Init(const JSRef<JSObject>& object, const std::string& sessionId)
|
||||
{
|
||||
JSRef<JSVal> jsVal = object->GetProperty("onDataOnChange");
|
||||
if (!jsVal->IsFunction()) {
|
||||
LOGE("JSDistributed, get func onDataOnChange failed.");
|
||||
return;
|
||||
}
|
||||
onDataOnChange_ = JSRef<JSFunc>::Cast(jsVal);
|
||||
|
||||
jsVal = object->GetProperty("onConnected");
|
||||
if (!jsVal->IsFunction()) {
|
||||
LOGE("JSDistributed, get func onConnected failed.");
|
||||
return;
|
||||
}
|
||||
onConnected_ = JSRef<JSFunc>::Cast(jsVal);
|
||||
|
||||
object_ = object;
|
||||
auto instanceId = ContainerScope::CurrentId();
|
||||
auto notifier = [weak = WeakClaim(this), instanceId](const std::string& onlineStatus) {
|
||||
ContainerScope scope(instanceId);
|
||||
auto distributed = weak.Upgrade();
|
||||
distributed->OnStatusNotify(onlineStatus);
|
||||
};
|
||||
|
||||
auto container = Container::Current();
|
||||
if (!container) {
|
||||
LOGW("container is null");
|
||||
return;
|
||||
}
|
||||
auto executor = container->GetTaskExecutor();
|
||||
|
||||
stroage_ = StorageProxy::GetInstance()->GetStorage(sessionId, notifier, executor);
|
||||
|
||||
auto onChangeCallback = [weak = WeakClaim(this), weakExecutor = WeakPtr<TaskExecutor>(executor), instanceId](
|
||||
const std::string& key) {
|
||||
auto taskExecutor_ = weakExecutor.Upgrade();
|
||||
if (!taskExecutor_) {
|
||||
return;
|
||||
}
|
||||
taskExecutor_->PostTask(
|
||||
[weak, key, instanceId] {
|
||||
ContainerScope scope(instanceId);
|
||||
auto distributed = weak.Upgrade();
|
||||
if (distributed) {
|
||||
distributed->OnDataOnChanged(key);
|
||||
}
|
||||
},
|
||||
TaskExecutor::TaskType::JS);
|
||||
};
|
||||
|
||||
stroage_->SetDataOnChangeCallback(std::move(onChangeCallback));
|
||||
}
|
||||
|
||||
void JSDistributed::OnDataOnChanged(const std::string& key)
|
||||
{
|
||||
LOGI("distributed date on change key = [%{public}s]", key.c_str());
|
||||
|
||||
auto params = ConvertToJSValues(key);
|
||||
onDataOnChange_->Call(object_, params.size(), params.data());
|
||||
}
|
||||
|
||||
void JSDistributed::OnStatusNotify(const std::string& onlineStatus)
|
||||
{
|
||||
LOGI("distributed OnStatusNotify = [%{public}s]", onlineStatus.c_str());
|
||||
auto params = ConvertToJSValues(onlineStatus);
|
||||
onConnected_->Call(object_, params.size(), params.data());
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
*
|
||||
* http://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 FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_DISTRIBUTED_H
|
||||
#define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_DISTRIBUTED_H
|
||||
|
||||
#include "base/memory/referenced.h"
|
||||
#include "bridge/declarative_frontend/engine/bindings.h"
|
||||
#include "core/common/storage/storage_proxy.h"
|
||||
#include "frameworks/bridge/declarative_frontend/engine/js_types.h"
|
||||
|
||||
namespace OHOS::Ace::Framework {
|
||||
|
||||
class JSDistributed final : public Referenced {
|
||||
public:
|
||||
JSDistributed(const std::string& sessionId) : sessionId_(sessionId) {}
|
||||
|
||||
void Set(const JSCallbackInfo& args);
|
||||
void Get(const JSCallbackInfo& args);
|
||||
void Delete(const JSCallbackInfo& args);
|
||||
|
||||
static void ConstructorCallback(const JSCallbackInfo& args);
|
||||
static void DestructorCallback(JSDistributed* obj);
|
||||
|
||||
static void JSBind(BindingTarget globalObj);
|
||||
|
||||
void Init(const JSRef<JSObject>& object, const std::string& sessionId);
|
||||
|
||||
void OnDataOnChanged(const std::string& key);
|
||||
|
||||
void OnStatusNotify(const std::string& onlineStatus);
|
||||
|
||||
private:
|
||||
std::string sessionId_;
|
||||
|
||||
JSRef<JSFunc> onDataOnChange_;
|
||||
JSRef<JSFunc> onConnected_;
|
||||
JSRef<JSObject> object_;
|
||||
RefPtr<Storage> stroage_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
#endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_DISTRIBUTED_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
@@ -75,7 +75,7 @@ void JSPersistent::Set(const JSCallbackInfo& args)
|
||||
if(!StorageProxy::GetInstance()->GetStorage(executor)) {
|
||||
return;
|
||||
}
|
||||
StorageProxy::GetInstance()->GetStorage(executor)->Set(key, value);
|
||||
StorageProxy::GetInstance()->GetStorage(executor)->SetString(key, value);
|
||||
LOGD("cross window notify, containerId=%{private}d", container->GetInstanceId());
|
||||
AceEngine::Get().NotifyContainers(
|
||||
[currInstanceId = container->GetInstanceId(), key, value](const RefPtr<Container>& container) {
|
||||
@@ -103,7 +103,7 @@ void JSPersistent::Get(const JSCallbackInfo& args)
|
||||
return;
|
||||
}
|
||||
auto executor = container->GetTaskExecutor();
|
||||
std::string value = StorageProxy::GetInstance()->GetStorage(executor)->Get(key);
|
||||
std::string value = StorageProxy::GetInstance()->GetStorage(executor)->GetString(key);
|
||||
auto returnValue = JSVal(ToJSValue(value));
|
||||
auto returnPtr = JSRef<JSVal>::Make(returnValue);
|
||||
args.SetReturnValue(returnPtr);
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
class DistributedStorage implements IMultiPropertiesChangeSubscriber {
|
||||
private storage_: IStorage;
|
||||
|
||||
private id_: number;
|
||||
private links_: Map<string, ObservedPropertyAbstract<any>>;
|
||||
private aviliable_: boolean;
|
||||
private notifier_: (status: string) => void;
|
||||
|
||||
public constructor(sessionId: string, notifier: (status: string) => void) {
|
||||
this.links_ = new Map<string, ObservedPropertyAbstract<any>>();
|
||||
this.id_ = SubscriberManager.Get().MakeId();
|
||||
SubscriberManager.Get().add(this);
|
||||
this.aviliable_ = false;
|
||||
this.notifier_ = notifier;
|
||||
}
|
||||
|
||||
public keys(): Array<string> {
|
||||
let result = [];
|
||||
const it = this.links_.keys();
|
||||
let val = it.next();
|
||||
|
||||
while (!val.done) {
|
||||
result.push(val.value);
|
||||
val = it.next();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public distributeProp<T>(propName: string, defaultValue: T): void {
|
||||
if (this.link(propName, defaultValue)) {
|
||||
console.debug(`DistributedStorage: writing '${propName}' - '${this.links_.get(propName)}' to storage`);
|
||||
}
|
||||
}
|
||||
|
||||
public distributeProps(properties: {
|
||||
key: string,
|
||||
defaultValue: any
|
||||
}[]): void {
|
||||
properties.forEach(property => this.link(property.key, property.defaultValue));
|
||||
}
|
||||
|
||||
public link<T>(propName: string, defaultValue: T): boolean {
|
||||
if (defaultValue == null || defaultValue == undefined) {
|
||||
console.error(`DistributedStorage: linkProp for ${propName} called with 'null' or 'undefined' default value!`);
|
||||
return false;
|
||||
}
|
||||
if (this.links_.get(propName)) {
|
||||
console.warn(`DistributedStorage: linkProp: ${propName} is already exist`);
|
||||
return false;
|
||||
}
|
||||
let link = AppStorage.GetOrCreate().link(propName, this);
|
||||
if (link) {
|
||||
console.debug(`DistributedStorage: linkProp ${propName} in AppStorage, using that`);
|
||||
this.links_.set(propName, link);
|
||||
this.setDistributedProp(propName, defaultValue);
|
||||
}
|
||||
else {
|
||||
let returnValue = defaultValue;
|
||||
if (this.aviliable_) {
|
||||
let newValue = this.getDistributedProp(propName);
|
||||
if (newValue == null) {
|
||||
console.debug(`DistributedStorage: no entry for ${propName}, will initialize with default value`);
|
||||
this.setDistributedProp(propName, defaultValue);
|
||||
}
|
||||
else {
|
||||
returnValue = newValue;
|
||||
}
|
||||
}
|
||||
link = AppStorage.GetOrCreate().setAndLink(propName, returnValue, this);
|
||||
this.links_.set(propName, link);
|
||||
console.debug(`DistributedStorage: created new linkProp prop for ${propName}`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public deleteProp(propName: string): void {
|
||||
let link = this.links_.get(propName);
|
||||
if (link) {
|
||||
link.aboutToBeDeleted();
|
||||
this.links_.delete(propName);
|
||||
if (this.aviliable_) {
|
||||
this.storage_.delete(propName);
|
||||
}
|
||||
} else {
|
||||
console.warn(`DistributedStorage: '${propName}' is not a distributed property warning.`);
|
||||
}
|
||||
}
|
||||
|
||||
private write(key: string): void {
|
||||
let link = this.links_.get(key);
|
||||
if (link) {
|
||||
this.setDistributedProp(key, link.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public required by the interface, use the static method instead!
|
||||
public aboutToBeDeleted(): void {
|
||||
console.debug("DistributedStorage: about to be deleted");
|
||||
this.links_.forEach((val, key, map) => {
|
||||
console.debug(`DistributedStorage: removing ${key}`);
|
||||
val.aboutToBeDeleted();
|
||||
});
|
||||
|
||||
this.links_.clear();
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
|
||||
public id__(): number {
|
||||
return this.id_;
|
||||
}
|
||||
|
||||
public propertyHasChanged(info?: PropertyInfo): void {
|
||||
console.debug("DistributedStorage: property changed");
|
||||
this.write(info);
|
||||
}
|
||||
|
||||
public onDataOnChange(propName: string): void {
|
||||
let link = this.links_.get(propName);
|
||||
let newValue = this.getDistributedProp(propName);
|
||||
if (link && newValue != null) {
|
||||
console.info(`DistributedStorage: dataOnChange[${propName}-${newValue}]`);
|
||||
link.set(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
public onConnected(status): void {
|
||||
console.info(`DistributedStorage onConnected: status = ${status}`);
|
||||
if (!this.aviliable_) {
|
||||
this.syncProp();
|
||||
this.aviliable_ = true;
|
||||
}
|
||||
if (this.notifier_ != null) {
|
||||
this.notifier_(status);
|
||||
}
|
||||
}
|
||||
|
||||
private syncProp(): void {
|
||||
this.links_.forEach((val, key) => {
|
||||
let newValue = this.getDistributedProp(key);
|
||||
if (newValue == null) {
|
||||
this.setDistributedProp(key, val.get());
|
||||
} else {
|
||||
val.set(newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private setDistributedProp(key, value): void {
|
||||
if (!this.aviliable_) {
|
||||
console.warn(`DistributedStorage is not aviliable`);
|
||||
return;
|
||||
}
|
||||
console.error(`DistributedStorage value is object ${key}-${JSON.stringify(value)}`);
|
||||
if (typeof value == 'object') {
|
||||
this.storage_.set(key, JSON.stringify(value));
|
||||
return;
|
||||
}
|
||||
this.storage_.set(key, value);
|
||||
}
|
||||
|
||||
private getDistributedProp(key): any {
|
||||
let value = this.storage_.get(key);
|
||||
if (typeof value == 'string') {
|
||||
try {
|
||||
let returnValue = JSON.parse(value);
|
||||
return returnValue;
|
||||
}
|
||||
finally {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
@@ -22,6 +22,7 @@
|
||||
"src/lib/view_native.d.ts",
|
||||
"src/lib/view.ts",
|
||||
"src/lib/persistent_storage.ts",
|
||||
"src/lib/distributed_storage.ts",
|
||||
"src/lib/environment.ts",
|
||||
"src/lib/i_environment_backend.ts",
|
||||
"src/index.ts",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"src/lib/view_native.d.ts",
|
||||
"src/lib/view.ts",
|
||||
"src/lib/persistent_storage.ts",
|
||||
"src/lib/distributed_storage.ts",
|
||||
"src/lib/environment.ts",
|
||||
"src/lib/i_environment_backend.ts",
|
||||
"src/index.ts",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
@@ -25,16 +25,49 @@ class Storage : public AceType {
|
||||
DECLARE_ACE_TYPE(Storage, AceType);
|
||||
|
||||
public:
|
||||
enum class DataType : uint32_t {
|
||||
NONE = 0,
|
||||
STRING,
|
||||
DOUBLE,
|
||||
BOOLEAN,
|
||||
};
|
||||
|
||||
using DataOnChange = std::function<void(const std::string& key)>;
|
||||
|
||||
~Storage() override = default;
|
||||
|
||||
virtual void Set(const std::string& key, const std::string& value) = 0;
|
||||
virtual std::string Get(const std::string& key) = 0;
|
||||
virtual void SetString(const std::string& key, const std::string& value) = 0;
|
||||
virtual std::string GetString(const std::string& key) = 0;
|
||||
virtual void SetDouble(const std::string& key, const double value) = 0;
|
||||
virtual bool GetDouble(const std::string& key, double& value) = 0;
|
||||
virtual void SetBoolean(const std::string& key, const bool value) = 0;
|
||||
virtual bool GetBoolean(const std::string& key, bool& value) = 0;
|
||||
|
||||
virtual DataType GetDataType(const std::string& key)
|
||||
{
|
||||
return DataType::NONE;
|
||||
}
|
||||
|
||||
virtual void Clear() = 0;
|
||||
virtual void Delete(const std::string& key) = 0;
|
||||
|
||||
void SetDataOnChangeCallback(DataOnChange&& dataOnChange)
|
||||
{
|
||||
dataOnChange_ = std::move(dataOnChange);
|
||||
}
|
||||
|
||||
void OnDataChange(const std::string& key)
|
||||
{
|
||||
if (dataOnChange_) {
|
||||
dataOnChange_(key);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit Storage(const RefPtr<TaskExecutor>& taskExecutor) : taskExecutor_(taskExecutor) {}
|
||||
Storage() = default;
|
||||
RefPtr<TaskExecutor> taskExecutor_;
|
||||
DataOnChange dataOnChange_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
@@ -26,7 +26,16 @@ class StorageInterface {
|
||||
public:
|
||||
virtual ~StorageInterface() = default;
|
||||
|
||||
virtual RefPtr<Storage> GetStorage(const RefPtr<TaskExecutor>& taskExecutor) const = 0;
|
||||
virtual RefPtr<Storage> GetStorage(const RefPtr<TaskExecutor>& taskExecutor) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual RefPtr<Storage> GetStorage(const std::string& sessionId, std::function<void(const std::string&)>&& notifier,
|
||||
const RefPtr<TaskExecutor>& taskExecutor) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
@@ -32,6 +32,11 @@ void StorageProxy::SetDelegate(std::unique_ptr<StorageInterface>&& delegate)
|
||||
delegate_ = std::move(delegate);
|
||||
}
|
||||
|
||||
void StorageProxy::SetDistributedDelegate(std::unique_ptr<StorageInterface>&& delegate)
|
||||
{
|
||||
distributedDelegate_ = std::move(delegate);
|
||||
}
|
||||
|
||||
RefPtr<Storage> StorageProxy::GetStorage(const RefPtr<TaskExecutor>& taskExecutor) const
|
||||
{
|
||||
if (!delegate_) {
|
||||
@@ -40,4 +45,13 @@ RefPtr<Storage> StorageProxy::GetStorage(const RefPtr<TaskExecutor>& taskExecuto
|
||||
return delegate_->GetStorage(taskExecutor);
|
||||
}
|
||||
|
||||
RefPtr<Storage> StorageProxy::GetStorage(const std::string& sessionId,
|
||||
std::function<void(const std::string&)>&& notifier, const RefPtr<TaskExecutor>& taskExecutor) const
|
||||
{
|
||||
if (!distributedDelegate_) {
|
||||
return nullptr;
|
||||
}
|
||||
return distributedDelegate_->GetStorage(sessionId, std::move(notifier), taskExecutor);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* 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
|
||||
@@ -25,12 +25,16 @@ class ACE_EXPORT StorageProxy : public StorageInterface {
|
||||
public:
|
||||
ACE_EXPORT static StorageProxy* GetInstance();
|
||||
void SetDelegate(std::unique_ptr<StorageInterface>&& delegate);
|
||||
void SetDistributedDelegate(std::unique_ptr<StorageInterface>&& delegate);
|
||||
RefPtr<Storage> GetStorage(const RefPtr<TaskExecutor>& taskExecutor) const override;
|
||||
RefPtr<Storage> GetStorage(const std::string& sessionId, std::function<void(const std::string&)>&& notifier,
|
||||
const RefPtr<TaskExecutor>& taskExecutor) const override;
|
||||
StorageProxy() = default;
|
||||
~StorageProxy() = default;
|
||||
|
||||
private:
|
||||
std::unique_ptr<StorageInterface> delegate_;
|
||||
std::unique_ptr<StorageInterface> distributedDelegate_;
|
||||
static StorageProxy* inst_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user