You need to sign in or sign up before continuing.
未验证 提交 878c0a48 编写于 作者: O openharmony_ci 提交者: Gitee

!1328 系统内存优化-watcher整改

Merge pull request !1328 from cheng_jinsong/memwatcher
......@@ -17,7 +17,7 @@
namespace OHOS {
namespace init_param {
void Watcher::OnParameterChange(const std::string &name, const std::string &value)
void Watcher::OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
{
UNUSED(name);
UNUSED(value);
......
......@@ -26,7 +26,7 @@ public:
Watcher() = default;
virtual ~Watcher() = default;
void OnParameterChange(const std::string &name, const std::string &value) override;
void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) override;
};
} // namespace init_param
} // namespace OHOS
......
......@@ -25,36 +25,40 @@
namespace OHOS {
namespace init_param {
WatcherManagerKits &WatcherManagerKits::GetInstance()
WatcherManagerKits &WatcherManagerKits::GetInstance(void)
{
return DelayedRefSingleton<WatcherManagerKits>::GetInstance();
}
WatcherManagerKits::WatcherManagerKits() {}
WatcherManagerKits::WatcherManagerKits(void) {}
WatcherManagerKits::~WatcherManagerKits() {}
WatcherManagerKits::~WatcherManagerKits(void) {}
void WatcherManagerKits::ResetService(const wptr<IRemoteObject> &remote)
{
WATCHER_LOGI("Remote is dead, reset service instance");
bool resetService = false;
{
std::lock_guard<std::mutex> lock(lock_);
if (watcherManager_ != nullptr) {
sptr<IRemoteObject> object = watcherManager_->AsObject();
if ((object != nullptr) && (remote == object)) {
object->RemoveDeathRecipient(deathRecipient_);
watcherManager_ = nullptr;
resetService = true;
std::lock_guard<std::mutex> lock(lock_);
if (watcherManager_ != nullptr) {
sptr<IRemoteObject> object = watcherManager_->AsObject();
if ((object != nullptr) && (remote == object)) {
object->RemoveDeathRecipient(deathRecipient_);
watcherManager_ = nullptr;
remoteWatcherId_ = 0;
remoteWatcher_ = nullptr;
if (threadForReWatch_ != nullptr) {
WATCHER_LOGI("Thead exist, delete thread");
stop_ = true;
threadForReWatch_->join();
delete threadForReWatch_;
}
stop_ = false;
threadForReWatch_ = new (std::nothrow)std::thread(&WatcherManagerKits::ReAddWatcher, this);
WATCHER_CHECK(threadForReWatch_ != nullptr, return, "Failed to create thread");
}
}
if (resetService) {
ReAddWatcher();
}
}
sptr<IWatcherManager> WatcherManagerKits::GetService()
sptr<IWatcherManager> WatcherManagerKits::GetService(void)
{
std::lock_guard<std::mutex> lock(lock_);
if (watcherManager_ != nullptr) {
......@@ -84,92 +88,125 @@ void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject>
DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote);
}
WatcherManagerKits::ParamWatcherKitPtr WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix)
{
std::lock_guard<std::mutex> lock(mutex_);
if (watchers_.find(keyPrefix) == watchers_.end()) {
return nullptr;
}
return watchers_[keyPrefix];
}
void WatcherManagerKits::ReAddWatcher()
void WatcherManagerKits::ReAddWatcher(void)
{
WATCHER_LOGV("ReAddWatcher ");
WATCHER_LOGV("ReAddWatcher");
int count = 0;
const int maxRetryCount = 100;
const int sleepTime = 100;
auto watcherManager = GetService();
while (watcherManager == nullptr && count < maxRetryCount) {
if (stop_) {
return;
}
watcherManager = GetService();
usleep(sleepTime);
count++;
}
WATCHER_LOGV("ReAddWatcher count %d ", count);
WATCHER_CHECK(watcherManager != nullptr, return, "Failed to get watcher manager");
// add or get remote agent
uint32_t remoteWatcherId = GetRemoteWatcher();
WATCHER_CHECK(remoteWatcherId > 0, return, "Failed to get remote agent");
std::lock_guard<std::mutex> lock(mutex_);
for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) {
if (stop_) {
return;
}
if (iter->second == nullptr) {
continue;
}
WATCHER_LOGV("ReAddWatcher keyPrefix %s ", iter->first.c_str());
uint32_t watcherId = watcherManager->AddWatcher(iter->first, iter->second);
WATCHER_CHECK(watcherId != 0, continue, "Failed to add watcher for %s", iter->first.c_str());
iter->second->SetWatcherId(watcherId);
WATCHER_LOGI("Add old watcher keyPrefix %s ", iter->first.c_str());
int ret = watcherManager->AddWatcher(iter->first, remoteWatcherId);
WATCHER_CHECK(ret == 0, continue, "Failed to add watcher for %s", iter->first.c_str());
}
}
WatcherManagerKits::ParamWatcher *WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix)
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = watchers_.find(keyPrefix);
if (iter != watchers_.end()) {
return iter->second.get();
}
return nullptr;
}
uint32_t WatcherManagerKits::GetRemoteWatcher(void)
{
std::lock_guard<std::mutex> lock(mutex_);
if (remoteWatcher_ != nullptr) {
return remoteWatcherId_;
}
auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return 0, "Failed to get watcher manager");
remoteWatcher_ = new RemoteWatcher(this);
WATCHER_CHECK(remoteWatcher_ != nullptr, return 0, "Failed to create watcher");
remoteWatcherId_ = watcherManager->AddRemoteWatcher(getpid(), remoteWatcher_);
WATCHER_CHECK(remoteWatcherId_ != 0, return 0, "Failed to add watcher");
return remoteWatcherId_;
}
int32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
{
WATCHER_LOGV("AddWatcher keyPrefix %s", keyPrefix.c_str());
auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
bool newWatcher = false;
// add or get remote agent
uint32_t remoteWatcherId = GetRemoteWatcher();
WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent");
ParamWatcherKitPtr watcher = nullptr;
{
std::lock_guard<std::mutex> lock(mutex_);
// must check
WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent");
if (watchers_.find(keyPrefix) == watchers_.end()) {
watcher = new ParamWatcher(keyPrefix);
watcher = std::make_shared<ParamWatcher>(keyPrefix);
WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str());
watchers_[keyPrefix] = watcher;
newWatcher = true;
int ret = watcher->AddParameterListener(callback, context);
WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str());
uint32_t watcherId = watcherManager->AddWatcher(keyPrefix, watcher);
WATCHER_CHECK(watcherId != 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str());
watcher->SetWatcherId(watcherId);
ret = watcherManager->AddWatcher(keyPrefix, remoteWatcherId);
WATCHER_CHECK(ret == 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str());
watchers_[keyPrefix] = watcher;
} else {
watcher = watchers_[keyPrefix];
int ret = watcher->AddParameterListener(callback, context);
WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str());
ret = watcherManager->RefreshWatcher(keyPrefix, remoteWatcherId);
WATCHER_CHECK(ret == 0, return -1,
"Failed to refresh watcher for %s %d", keyPrefix.c_str(), remoteWatcherId);
}
}
// save callback
if (!newWatcher) { // refresh
int ret = watcher->AddParameterListener(callback, context);
WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str());
ret = watcherManager->RefreshWatcher(keyPrefix, watcher->GetWatcherId());
WATCHER_CHECK(ret == 0, return -1, "Failed to refresh watcher for %s", keyPrefix.c_str());
}
WATCHER_LOGI("AddWatcher keyPrefix %s watcherId %u success", keyPrefix.c_str(), watcher->GetWatcherId());
WATCHER_LOGI("Add watcher keyPrefix %s remoteWatcherId %u success", keyPrefix.c_str(), remoteWatcherId);
return 0;
}
int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
{
ParamWatcherKitPtr watcher = GetParamWatcher(keyPrefix);
WATCHER_CHECK(watcher != nullptr, return 0, "Can not find watcher for keyPrefix %s", keyPrefix.c_str());
auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
WatcherManagerKits::ParamWatcher *watcher = GetParamWatcher(keyPrefix);
WATCHER_CHECK(watcher != nullptr, return -1, "Failed to get watcher");
int count = watcher->DelParameterListener(callback, context);
WATCHER_LOGI("DelWatcher keyPrefix_ %s count %d", keyPrefix.c_str(), count);
if (count == 0) {
int ret = watcherManager->DelWatcher(keyPrefix, watcher->GetWatcherId());
WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str());
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = watchers_.find(keyPrefix);
if (iter != watchers_.end()) {
watchers_.erase(iter);
}
if (count != 0) {
return 0;
}
// delete watcher
int ret = watcherManager->DelWatcher(keyPrefix, remoteWatcherId_);
WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str());
{
std::lock_guard<std::mutex> lock(mutex_);
auto it = watchers_.find(keyPrefix); // delete watcher
if (it != watchers_.end()) {
watchers_.erase(it);
}
if (watchers_.empty()) { // no watcher, so delete remote agent
watcherManager->DelRemoteWatcher(remoteWatcherId_);
remoteWatcherId_ = 0;
remoteWatcher_ = nullptr;
}
}
return 0;
......@@ -179,7 +216,10 @@ WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::G
{
std::lock_guard<std::mutex> lock(mutex_);
uint32_t index = *idx;
while (index < static_cast<uint32_t>(parameterChangeListeners.size())) {
if (parameterChangeListeners.empty()) {
return nullptr;
}
while (index < listenerId_) {
auto it = parameterChangeListeners.find(index);
if (it != parameterChangeListeners.end()) {
*idx = index;
......@@ -193,32 +233,17 @@ WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::G
void WatcherManagerKits::ParamWatcher::RemoveParameterListener(uint32_t idx)
{
std::lock_guard<std::mutex> lock(mutex_);
if (idx >= static_cast<uint32_t>(parameterChangeListeners.size())) {
return;
}
parameterChangeListeners.erase(idx);
}
void WatcherManagerKits::ParamWatcher::OnParameterChange(const std::string &name, const std::string &value)
{
Watcher::OnParameterChange(name, value);
WATCHER_LOGI("OnParameterChange name %s value %s", name.c_str(), value.c_str());
uint32_t index = 0;
ParameterChangeListener *listener = GetParameterListener(&index);
while (listener != nullptr) {
if (!listener->CheckValueChange(value)) {
listener->OnParameterChange(name, value);
}
index++;
listener = GetParameterListener(&index);
auto it = parameterChangeListeners.find(idx);
if (it != parameterChangeListeners.end()) {
parameterChangeListeners.erase(it);
}
}
int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr callback, void *context)
{
WATCHER_CHECK(callback != nullptr, return -1, "Invalid callback ");
WATCHER_LOGV("AddParameterListener listenerId_ %d callback %p context %p", listenerId_, callback, context);
std::lock_guard<std::mutex> lock(mutex_);
WATCHER_LOGV("AddParameterListener %s listenerId_ %d callback %p context %p",
keyPrefix_.c_str(), listenerId_, callback, context);
for (auto it = parameterChangeListeners.begin(); it != parameterChangeListeners.end(); it++) {
if (it->second == nullptr) {
continue;
......@@ -237,12 +262,15 @@ int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr ca
int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr callback, void *context)
{
if (callback == nullptr) {
parameterChangeListeners.clear();
return 0;
}
uint32_t index = 0;
ParameterChangeListener *listener = GetParameterListener(&index);
while (listener != nullptr) {
if ((callback == nullptr && context == nullptr)) {
RemoveParameterListener(index);
} else if (listener->IsEqual(callback, context)) {
if (listener->IsEqual(callback, context)) {
WATCHER_LOGV("DelParameterListener listenerId_ %d callback %p context %p", index, callback, context);
RemoveParameterListener(index);
break;
}
......@@ -252,6 +280,31 @@ int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr ca
return static_cast<int>(parameterChangeListeners.size());
}
void WatcherManagerKits::RemoteWatcher::OnParameterChange(
const std::string &prefix, const std::string &name, const std::string &value)
{
// get param watcher
WatcherManagerKits::ParamWatcher *watcher = watcherManager_->GetParamWatcher(prefix);
WATCHER_CHECK(watcher != nullptr, return, "Failed to get watcher '%s'", prefix.c_str());
if (watcher != nullptr) {
watcher->OnParameterChange(name, value);
}
}
void WatcherManagerKits::ParamWatcher::OnParameterChange(const std::string &name, const std::string &value)
{
WATCHER_LOGI("OnParameterChange name %s value %s", name.c_str(), value.c_str());
uint32_t index = 0;
ParameterChangeListener *listener = GetParameterListener(&index);
while (listener != nullptr) {
if (!listener->CheckValueChange(value)) {
listener->OnParameterChange(name, value);
}
index++;
listener = GetParameterListener(&index);
}
}
void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::string &name, const std::string &value)
{
if (callback_ != nullptr) {
......@@ -261,20 +314,30 @@ void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::s
} // namespace init_param
} // namespace OHOS
static int ParameterWatcherCheck(const char *keyPrefix)
static int PreHandleWatchParam(std::string &prefix)
{
std::string key(keyPrefix);
if (key.rfind("*") == key.length() - 1) {
return WatchParamCheck(key.substr(0, key.length() - 1).c_str());
// clear space in head or tail
prefix.erase(0, prefix.find_first_not_of(" "));
prefix.erase(prefix.find_last_not_of(" ") + 1);
WATCHER_CHECK(!prefix.empty(), return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
int ret = 0;
if (prefix.rfind(".*") == prefix.length() - 2) { // 2 last index
ret = WatchParamCheck(prefix.substr(0, prefix.length() - 2).c_str()); // 2 last index
} else if (prefix.rfind("*") == prefix.length() - 1) {
ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
} else if (prefix.rfind(".") == prefix.length() - 1) {
ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
} else {
return WatchParamCheck(keyPrefix);
ret = WatchParamCheck(prefix.c_str());
}
return ret;
}
int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context)
{
WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
int ret = ParameterWatcherCheck(keyPrefix);
std::string key(keyPrefix);
int ret = PreHandleWatchParam(key);
if (ret != 0) {
return ret;
}
......@@ -290,7 +353,8 @@ int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, voi
int RemoveParameterWatcher(const char *keyPrefix, ParameterChgPtr callback, void *context)
{
WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
int ret = ParameterWatcherCheck(keyPrefix);
std::string key(keyPrefix);
int ret = PreHandleWatchParam(key);
if (ret != 0) {
return ret;
}
......
......@@ -18,6 +18,7 @@
#include <functional>
#include <map>
#include <mutex>
#include <thread>
#include "iwatcher.h"
#include "iwatcher_manager.h"
......@@ -33,10 +34,11 @@ class WatcherManagerKits final : public DelayedRefSingleton<WatcherManagerKits>
public:
DISALLOW_COPY_AND_MOVE(WatcherManagerKits);
static WatcherManagerKits &GetInstance();
static WatcherManagerKits &GetInstance(void);
int32_t AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context);
int32_t DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context);
void ReAddWatcher();
void ReAddWatcher(void);
#ifndef STARTUP_INIT_TEST
private:
#endif
......@@ -44,7 +46,7 @@ private:
public:
ParameterChangeListener(ParameterChangePtr callback, void *context)
: callback_(callback), context_(context) {}
~ParameterChangeListener() = default;
~ParameterChangeListener(void) = default;
bool IsEqual(ParameterChangePtr callback, void *context) const
{
......@@ -63,61 +65,63 @@ private:
void *context_ { nullptr };
};
class ParamWatcher final : public Watcher {
class ParamWatcher {
public:
explicit ParamWatcher(const std::string &key) : keyPrefix_(key) {}
~ParamWatcher() override
~ParamWatcher(void)
{
parameterChangeListeners.clear();
};
void OnParameterChange(const std::string &name, const std::string &value) override;
void SetWatcherId(uint32_t watcherId)
{
watcherId_ = watcherId;
}
uint32_t GetWatcherId()
{
return watcherId_;
}
void OnParameterChange(const std::string &name, const std::string &value);
int AddParameterListener(ParameterChangePtr callback, void *context);
int DelParameterListener(ParameterChangePtr callback, void *context);
private:
ParameterChangeListener *GetParameterListener(uint32_t *idx);
void RemoveParameterListener(uint32_t idx);
uint32_t watcherId_ { 0 };
std::string keyPrefix_ {};
std::mutex mutex_;
uint32_t listenerId_ { 0 };
std::map<uint32_t, std::shared_ptr<ParameterChangeListener>> parameterChangeListeners;
};
using ParamWatcherKitPtr = sptr<WatcherManagerKits::ParamWatcher>;
ParamWatcherKitPtr GetParamWatcher(const std::string &keyPrefix);
class RemoteWatcher final : public Watcher {
public:
RemoteWatcher(WatcherManagerKits *watcherManager) : watcherManager_(watcherManager) {}
~RemoteWatcher(void) override {}
void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) final;
private:
WatcherManagerKits *watcherManager_ = { nullptr };
};
using ParamWatcherKitPtr = std::shared_ptr<WatcherManagerKits::ParamWatcher>;
// For death event procession
class DeathRecipient final : public IRemoteObject::DeathRecipient {
public:
DeathRecipient() = default;
~DeathRecipient() final = default;
DeathRecipient(void) = default;
~DeathRecipient(void) final = default;
DISALLOW_COPY_AND_MOVE(DeathRecipient);
void OnRemoteDied(const wptr<IRemoteObject> &remote) final;
};
sptr<IRemoteObject::DeathRecipient> GetDeathRecipient()
sptr<IRemoteObject::DeathRecipient> GetDeathRecipient(void)
{
return deathRecipient_;
}
private:
uint32_t GetRemoteWatcher(void);
ParamWatcher *GetParamWatcher(const std::string &keyPrefix);
void ResetService(const wptr<IRemoteObject> &remote);
sptr<IWatcherManager> GetService();
sptr<IWatcherManager> GetService(void);
std::mutex lock_;
sptr<IWatcherManager> watcherManager_ {};
sptr<IRemoteObject::DeathRecipient> deathRecipient_ {};
std::mutex mutex_;
uint32_t remoteWatcherId_ = { 0 };
sptr<Watcher> remoteWatcher_ = { nullptr };
std::map<std::string, ParamWatcherKitPtr> watchers_;
std::atomic<bool> stop_ { false };
std::thread *threadForReWatch_ { nullptr };
};
} // namespace init_param
} // namespace OHOS
......
......@@ -17,55 +17,69 @@
namespace OHOS {
namespace init_param {
uint32_t WatcherManagerProxy::AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher)
uint32_t WatcherManagerProxy::AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher)
{
WATCHER_CHECK(watcher != nullptr, return ERR_INVALID_VALUE, "Invalid param");
WATCHER_LOGV("WatcherManagerProxy::AddWatcher %s", keyPrefix.c_str());
auto remote = Remote();
WATCHER_CHECK(remote != nullptr, return 0, "Can not get remote");
MessageParcel data;
data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor());
data.WriteString(keyPrefix);
bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote");
data.WriteUint32(id);
MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(ADD_WATCHER, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return 0, "Transact error");
int32_t res = remote->SendRequest(ADD_REMOTE_AGENT, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return 0, "Transact error %d", res);
return reply.ReadUint32();
}
int32_t WatcherManagerProxy::DelWatcher(const std::string &keyPrefix, uint32_t watcherId)
int32_t WatcherManagerProxy::DelRemoteWatcher(uint32_t remoteWatcherId)
{
WATCHER_LOGV("WatcherManagerProxy::DelWatcher %s", keyPrefix.c_str());
auto remote = Remote();
WATCHER_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
MessageParcel data;
data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor());
data.WriteString(keyPrefix);
data.WriteUint32(watcherId);
data.WriteUint32(remoteWatcherId);
MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(DEL_WATCHER, data, reply, option);
int32_t res = remote->SendRequest(DEL_REMOTE_AGENT, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
return reply.ReadInt32();
}
int32_t WatcherManagerProxy::RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId)
int32_t WatcherManagerProxy::SendMsg(int op, const std::string &keyPrefix, uint32_t remoteWatcherId)
{
auto remote = Remote();
WATCHER_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
WATCHER_CHECK(remote != nullptr, return 0, "Can not get remote");
MessageParcel data;
data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor());
data.WriteString(keyPrefix);
data.WriteUint32(watcherId);
data.WriteUint32(remoteWatcherId);
MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(REFRESH_WATCHER, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
return 0;
int32_t res = remote->SendRequest(op, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return 0, "Transact error");
return reply.ReadInt32();
}
int32_t WatcherManagerProxy::AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
{
return SendMsg(ADD_WATCHER, keyPrefix, remoteWatcherId);
}
int32_t WatcherManagerProxy::DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
{
return SendMsg(DEL_WATCHER, keyPrefix, remoteWatcherId);
}
int32_t WatcherManagerProxy::RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
{
return SendMsg(REFRESH_WATCHER, keyPrefix, remoteWatcherId);
}
}
} // namespace OHOS
......@@ -25,10 +25,13 @@ class WatcherManagerProxy : public IRemoteProxy<IWatcherManager> {
public:
explicit WatcherManagerProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IWatcherManager>(impl) {}
uint32_t AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId) override;
uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) override;
int32_t DelRemoteWatcher(uint32_t remoteWatcherId) override;
int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
private:
int32_t SendMsg(int op, const std::string &keyPrefix, uint32_t remoteWatcherId);
static inline BrokerDelegator<WatcherManagerProxy> delegator_;
};
} // namespace init_param
......
......@@ -22,15 +22,16 @@ namespace OHOS {
namespace init_param {
int32_t WatcherStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
std::u16string myDescripter = IWatcher::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken();
WATCHER_CHECK(myDescripter == remoteDescripter, return -1, "Invalid remoteDescripter");
std::u16string myDescriptor = IWatcher::GetDescriptor();
std::u16string remoteDescriptor = data.ReadInterfaceToken();
WATCHER_CHECK(myDescriptor == remoteDescriptor, return -1, "Invalid remoteDescriptor");
switch (code) {
case PARAM_CHANGE: {
std::string key = data.ReadString();
std::string name = data.ReadString();
std::string value = data.ReadString();
OnParameterChange(name, value);
OnParameterChange(key, name, value);
break;
}
default: {
......
......@@ -31,7 +31,7 @@ public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcher");
public:
virtual void OnParameterChange(const std::string &name, const std::string &value) = 0;
virtual void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) = 0;
};
} // namespace init_param
} // namespace OHOS
......
......@@ -28,14 +28,18 @@ public:
enum {
ADD_WATCHER,
DEL_WATCHER,
ADD_REMOTE_AGENT,
DEL_REMOTE_AGENT,
REFRESH_WATCHER
};
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcherManager");
public:
virtual uint32_t AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) = 0;
virtual int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) = 0;
virtual int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId) = 0;
virtual uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) = 0;
virtual int32_t DelRemoteWatcher(uint32_t remoteWatcherId) = 0;
virtual int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) = 0;
virtual int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) = 0;
virtual int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) = 0;
};
} // namespace update_engine
} // namespace OHOS
......
......@@ -27,13 +27,27 @@
#include "message_parcel.h"
#include "param_utils.h"
#include "parcel.h"
#include "param_message.h"
#include "system_ability.h"
#include "watcher_manager_stub.h"
namespace OHOS {
namespace init_param {
class WatcherNode;
class ParamWatcherList;
class WatcherGroup;
class RemoteWatcher;
using WatcherGroupPtr = WatcherGroup *;
using RemoteWatcherPtr = RemoteWatcher *;
using WatcherNodePtr = WatcherNode *;
using ListNodePtr = ListNode *;
using ListHeadPtr = ListHead *;
using ParamWatcherListPtr = ParamWatcherList *;
using ParamWatcherProcessor = std::function<void(ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index)>;
class WatcherManager : public SystemAbility, public WatcherManagerStub {
public:
friend class WatcherGroup;
DECLARE_SYSTEM_ABILITY(WatcherManager);
DISALLOW_COPY_AND_MOVE(WatcherManager);
explicit WatcherManager(int32_t systemAbilityId, bool runOnCreate = true)
......@@ -42,104 +56,28 @@ public:
}
~WatcherManager() override;
class ParamWatcher;
class WatcherGroup;
using ParamWatcherPtr = std::shared_ptr<WatcherManager::ParamWatcher>;
using WatcherGroupPtr = std::shared_ptr<WatcherManager::WatcherGroup>;
// For death event procession
class DeathRecipient final : public IRemoteObject::DeathRecipient {
public:
explicit DeathRecipient(WatcherManager *manager) : manager_(manager) {}
~DeathRecipient() final = default;
DISALLOW_COPY_AND_MOVE(DeathRecipient);
void OnRemoteDied(const wptr<IRemoteObject> &remote) final;
void OnRemoteDied(const wptr<IRemoteObject> &remote) final
{
manager_->OnRemoteDied(remote);
}
private:
WatcherManager *manager_;
};
sptr<IRemoteObject::DeathRecipient> GetDeathRecipient()
sptr<IRemoteObject::DeathRecipient> GetDeathRecipient(void)
{
return deathRecipient_;
}
class ParamWatcher {
public:
ParamWatcher(uint32_t watcherId, const sptr<IWatcher> &watcher, const WatcherGroupPtr &group)
: watcherId_(watcherId), watcher_(watcher), group_(group)
{
OH_ListInit(&groupNode_);
}
~ParamWatcher() = default;
uint32_t GetWatcherId() const
{
return watcherId_;
}
WatcherGroupPtr GetWatcherGroup()
{
return group_;
}
ListNode *GetGroupNode()
{
return &groupNode_;
}
sptr<IWatcher> GetRemoteWatcher() const
{
return watcher_;
}
void ProcessParameterChange(const std::string &name, const std::string &value)
{
#ifndef STARTUP_INIT_TEST
watcher_->OnParameterChange(name, value);
#endif
}
private:
ListNode groupNode_;
uint32_t watcherId_ = { 0 };
sptr<IWatcher> watcher_;
WatcherGroupPtr group_ { nullptr };
};
class WatcherGroup {
public:
WatcherGroup(uint32_t groupId, const std::string &key) : groupId_(groupId), keyPrefix_(key)
{
OH_ListInit(&watchers_);
}
~WatcherGroup() = default;
void AddWatcher(const ParamWatcherPtr &watcher);
void ProcessParameterChange(const std::string &name, const std::string &value);
const std::string GetKeyPrefix() const
{
return keyPrefix_;
}
bool Empty() const
{
return ListEmpty(watchers_);
}
uint32_t GetGroupId() const
{
return groupId_;
}
ListNode *GetWatchers()
{
return &watchers_;
}
ParamWatcher *GetNextWatcher(ParamWatcher *watcher);
private:
uint32_t groupId_;
std::string keyPrefix_ { };
ListNode watchers_;
};
uint32_t AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId) override;
int32_t DelWatcher(WatcherGroupPtr group, ParamWatcherPtr watcher);
ParamWatcherPtr GetWatcher(uint32_t watcherId);
ParamWatcherPtr GetWatcher(const wptr<IRemoteObject> &remote);
uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) override;
int32_t DelRemoteWatcher(uint32_t remoteWatcherId) override;
int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
#ifndef STARTUP_INIT_TEST
protected:
#endif
......@@ -149,33 +87,169 @@ protected:
#ifndef STARTUP_INIT_TEST
private:
#endif
void ProcessWatcherMessage(const std::vector<char> &buffer, uint32_t dataSize);
WatcherGroupPtr GetWatcherGroup(uint32_t groupId);
WatcherGroupPtr GetWatcherGroup(const std::string &keyPrefix);
void DelWatcherGroup(WatcherGroupPtr group);
void AddParamWatcher(const std::string &keyPrefix, WatcherGroupPtr group, ParamWatcherPtr watcher);
void DelParamWatcher(ParamWatcherPtr watcher);
void RunLoop();
void StartLoop();
void StopLoop();
void SendLocalChange(const std::string &keyPrefix, ParamWatcherPtr watcher);
void SendLocalChange(const std::string &keyPrefix, RemoteWatcherPtr &remoteWatcher);
int SendMessage(WatcherGroupPtr group, int type);
int GetServerFd(bool retry);
int GetWatcherId(uint32_t &watcherId);
int GetRemoteWatcherId(uint32_t &remoteWatcherId);
int GetGroupId(uint32_t &groupId);
void DumpWatcherGroup(int fd, const WatcherGroupPtr &group);
// for remote watcher
int AddRemoteWatcher(RemoteWatcherPtr remoteWatcher);
RemoteWatcherPtr GetRemoteWatcher(uint32_t remoteWatcherId);
RemoteWatcherPtr GetRemoteWatcher(const wptr<IRemoteObject> &remote);
void DelRemoteWatcher(RemoteWatcherPtr remoteWatcher);
// for group
WatcherGroupPtr AddWatcherGroup(const std::string &keyPrefix);
WatcherGroupPtr GetWatcherGroup(const std::string &keyPrefix);
WatcherGroupPtr GetWatcherGroup(uint32_t groupId);
void DelWatcherGroup(WatcherGroupPtr group);
// for param watcher
int AddParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher);
int DelParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher);
// for process message form init
void ProcessWatcherMessage(const ParamMessage *msg);
// for client died
void OnRemoteDied(const wptr<IRemoteObject> &remote);
void OnRemoteDied(RemoteWatcherPtr remoteWatcher);
// clear
void Clear(void);
// dump
void DumpAllGroup(int fd, ParamWatcherProcessor dumpHandle);
private:
std::atomic<uint32_t> watcherId_ { 0 };
std::atomic<uint32_t> remoteWatcherId_ { 0 };
std::atomic<uint32_t> groupId_ { 0 };
std::mutex mutex_;
std::mutex watcherMutex_;
int serverFd_ { -1 };
std::thread *pRecvThread_ { nullptr };
std::atomic<bool> stop_ { false };
std::map<std::string, uint32_t> groupMap_ {};
std::map<uint32_t, WatcherGroupPtr> watcherGroups_ {};
std::map<uint32_t, ParamWatcherPtr> watchers_ {};
std::map<std::string, WatcherGroupPtr> groupMap_ {};
sptr<IRemoteObject::DeathRecipient> deathRecipient_ {};
ParamWatcherListPtr watcherGroups_ {};
ParamWatcherListPtr remoteWatchers_ {};
};
class WatcherNode {
public:
WatcherNode(uint32_t nodeId) : nodeId_(nodeId)
{
OH_ListInit(&node_);
}
virtual ~WatcherNode(void) = default;
uint32_t GetNodeId(void) const { return nodeId_; }
void AddToList(ListHeadPtr list);
void RemoveFromList(ListHeadPtr list);
WatcherNodePtr GetNext(ListHeadPtr list);
static WatcherNodePtr GetFromList(ListHeadPtr list, uint32_t nodeId);
static WatcherNodePtr GetNextFromList(ListHeadPtr list, uint32_t nodeId);
static WatcherNodePtr ConvertNodeToBase(ListNodePtr node) {
WatcherNodePtr tmp = NULL;
return reinterpret_cast<WatcherNodePtr >((char *)node - (char *)tmp->GetListNode());
}
ListNodePtr GetListNode() { return &node_; }
private:
static int CompareNode(ListNodePtr node, ListNodePtr newNode);
static int CompareData(ListNodePtr node, void *data);
static int Greater(ListNodePtr node, void *data);
ListNode node_;
uint32_t nodeId_;
};
template<typename T>
inline T *ConvertTo(WatcherNodePtr node)
{
#ifdef PARAM_WATCHER_RTTI_ENABLE
// when -frtti is enabled, we use dynamic cast directly
// to achieve the correct base class side-to-side conversion.
T *obj = dynamic_cast<T *>(node);
#else
// adjust pointer position when multiple inheritance.
void *tmp = reinterpret_cast<void *>(node);
// when -frtti is not enable, we use static cast.
// static cast is not safe enough, but we have checked before we get here.
T *obj = static_cast<T *>(tmp);
#endif
return obj;
}
class ParamWatcher : public WatcherNode {
public:
ParamWatcher(uint32_t watcherId) : WatcherNode(watcherId) {}
~ParamWatcher(void) override {}
};
class ParamWatcherList {
public:
ParamWatcherList(void)
{
OH_ListInit(&nodeList_);
}
~ParamWatcherList(void) = default;
bool Empty(void) const
{
return nodeList_.next == &nodeList_;
}
uint32_t GetNodeCount(void) const { return nodeCount_; }
int AddNode(WatcherNodePtr node);
int RemoveNode(WatcherNodePtr node);
WatcherNodePtr GetNode(uint32_t nodeId);
WatcherNodePtr GetNextNodeSafe(WatcherNodePtr node);
WatcherNodePtr GetNextNode(WatcherNodePtr node);
void TraversalNode(ParamWatcherProcessor handle);
void TraversalNodeSafe(ParamWatcherProcessor processor);
public:
ListHead nodeList_ {};
uint32_t nodeCount_ = 0;
};
class RemoteWatcher : public WatcherNode, public ParamWatcherList {
public:
RemoteWatcher(uint32_t watcherId, const sptr<IWatcher> &watcher)
: WatcherNode(watcherId), ParamWatcherList(), watcher_(watcher) {}
~RemoteWatcher(void) override
{
watcher_ = nullptr;
TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
list->RemoveNode(node);
ParamWatcher *watcher = ConvertTo<ParamWatcher>(node);
delete watcher;
});
}
uint32_t GetRemoteWatcherId(void) const { return GetNodeId(); }
uint32_t GetAgentId(void) const { return id_; }
void SetAgentId(uint32_t id) { id_ = id; }
void ProcessParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
{
watcher_->OnParameterChange(prefix, name, value);
}
sptr<IWatcher> GetWatcher(void) { return watcher_; }
private:
uint32_t id_ = { 0 };
sptr<IWatcher> watcher_ {};
};
class WatcherGroup : public WatcherNode, public ParamWatcherList {
public:
WatcherGroup(uint32_t groupId, const std::string &key)
: WatcherNode(groupId), ParamWatcherList(), keyPrefix_(key) {}
~WatcherGroup() override
{
TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
list->RemoveNode(node);
ParamWatcher *watcher = ConvertTo<ParamWatcher>(node);
delete watcher;
});
}
void ProcessParameterChange(WatcherManager *mananger, const std::string &name, const std::string &value);
const std::string GetKeyPrefix() const { return keyPrefix_; }
uint32_t GetGroupId() const { return GetNodeId(); }
private:
std::string keyPrefix_ { };
};
} // namespace init_param
} // namespace OHOS
......
......@@ -21,32 +21,42 @@ namespace init_param {
int32_t WatcherManagerStub::OnRemoteRequest(uint32_t code,
MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
std::u16string myDescripter = IWatcherManager::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken();
WATCHER_CHECK(myDescripter == remoteDescripter, return -1, "Invalid remoteDescripter");
std::u16string myDescriptor = IWatcherManager::GetDescriptor();
std::u16string remoteDescriptor = data.ReadInterfaceToken();
WATCHER_CHECK(myDescriptor == remoteDescriptor, return -1, "Invalid remoteDescriptor");
WATCHER_LOGV("OnRemoteRequest code %u", code);
switch (code) {
case ADD_WATCHER: {
std::string key = data.ReadString();
int ret = AddWatcher(key, data.ReadUint32());
reply.WriteInt32(ret);
break;
}
case DEL_WATCHER: {
std::string key = data.ReadString();
int ret = DelWatcher(key, data.ReadUint32());
reply.WriteInt32(ret);
break;
}
case ADD_REMOTE_AGENT: {
auto remote = data.ReadRemoteObject();
// 0 is invalid watcherId
WATCHER_CHECK(remote != nullptr, reply.WriteUint32(0);
return 0, "Failed to read remote watcher");
uint32_t watcherId = AddWatcher(key, iface_cast<IWatcher>(remote));
reply.WriteUint32(watcherId);
uint32_t id = data.ReadUint32();
uint32_t remoteWatcherId = AddRemoteWatcher(id, iface_cast<IWatcher>(remote));
reply.WriteUint32(remoteWatcherId);
break;
}
case DEL_WATCHER: {
std::string key = data.ReadString();
uint32_t watcherId = data.ReadUint32();
int ret = DelWatcher(key, watcherId);
case DEL_REMOTE_AGENT: {
int ret = DelRemoteWatcher(data.ReadUint32());
reply.WriteInt32(ret);
break;
}
case REFRESH_WATCHER: {
std::string key = data.ReadString();
uint32_t watcherId = data.ReadUint32();
int ret = RefreshWatcher(key, watcherId);
int ret = RefreshWatcher(key, data.ReadUint32());
reply.WriteInt32(ret);
break;
}
......
......@@ -23,9 +23,9 @@
namespace OHOS {
namespace init_param {
void WatcherProxy::OnParameterChange(const std::string &name, const std::string &value)
void WatcherProxy::OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
{
WATCHER_LOGV("WatcherProxy::OnParameterChange %s %s", name.c_str(), value.c_str());
WATCHER_LOGV("WatcherProxy::OnParameterChange %s %s %s", prefix.c_str(), name.c_str(), value.c_str());
MessageParcel data;
MessageParcel reply;
MessageOption option { MessageOption::TF_ASYNC };
......@@ -33,10 +33,11 @@ void WatcherProxy::OnParameterChange(const std::string &name, const std::string
WATCHER_CHECK(remote != nullptr, return, "Can not get remote");
data.WriteInterfaceToken(WatcherProxy::GetDescriptor());
data.WriteString(prefix);
data.WriteString(name);
data.WriteString(value);
int ret = remote->SendRequest(PARAM_CHANGE, data, reply, option);
WATCHER_CHECK(ret == ERR_OK, return, "Can not SendRequest for name %s", name.c_str());
WATCHER_CHECK(ret == ERR_OK, return, "Can not SendRequest for name %s err:%d", name.c_str(), ret);
return;
}
}
......
......@@ -27,7 +27,7 @@ public:
virtual ~WatcherProxy() = default;
void OnParameterChange(const std::string &name, const std::string &value) override;
void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) override;
private:
static inline BrokerDelegator<WatcherProxy> delegator_;
......
......@@ -19,12 +19,18 @@
#include "begetctl.h"
#include "init_param.h"
#include "init_utils.h"
#include "loop_event.h"
#include "parameter.h"
#include "plugin_test.h"
#include "service_watcher.h"
#include "parameter.h"
#define MAX_THREAD_NUMBER 100
#define MAX_NUMBER 10
#define READ_DURATION 100000
#define CMD_INDEX 2
static char *GetLocalBuffer(uint32_t *buffSize)
{
static char buffer[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX] = {0};
......@@ -77,24 +83,138 @@ static int32_t BShellParamCmdRead(BShellHandle shell, int32_t argc, char *argv[]
return 0;
}
static void HandleParamChange(const char *key, const char *value, void *context)
typedef struct {
char name[PARAM_NAME_LEN_MAX];
pthread_t thread;
} TestWatchContext;
static void HandleParamChange2(const char *key, const char *value, void *context)
{
PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter");
long long commit = GetSystemCommitId();
printf("Receive parameter commit %lld change %s %s \n", commit, key, value);
size_t index = (size_t)context;
printf("[%zu] Receive parameter %p commit %lld change %s %s \n", index, context, commit, key, value);
static int addWatcher = 0;
int ret = 0;
if ((index == 4) && !addWatcher) { // 4 when context == 4 add
index = 5; // 5 add context
ret = SystemWatchParameter(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Add watcher %s fail %d \n", key, index);
}
addWatcher = 1;
return;
}
if (index == 2) { // 2 when context == 2 delete 3
index = 3; // 3 delete context
RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Remove watcher fail %d \n", index);
}
return;
}
if (index == 1) { // 1 when context == 1 delete 1
RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Remove watcher fail %d \n", index);
}
return;
}
if ((index == 5) && (addWatcher == 1)) { // 5 when context == 5 delete 5
RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Remove watcher fail %d \n", index);
}
addWatcher = 0;
}
}
static void HandleParamChange1(const char *key, const char *value, void *context)
{
PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter");
long long commit = GetSystemCommitId();
size_t index = (size_t)context;
printf("[%zu] Receive parameter commit %lld change %s %s \n", index, commit, key, value);
}
static void *CmdThreadWatcher(void *args)
{
TestWatchContext *context = (TestWatchContext *)args;
for (size_t i = 1; i <= MAX_NUMBER; i++) {
int ret = SystemWatchParameter(context->name, HandleParamChange2, (void *)i);
if (ret != 0) {
printf("Add watcher %s fail %d \n", context->name, i);
}
ret = SetParameter(context->name, context->name);
if (ret != 0) {
printf("Set parameter %s fail %d \n", context->name, i);
}
}
sleep(1);
for (size_t i = 1; i <= MAX_NUMBER; i++) {
int ret = RemoveParameterWatcher(context->name, HandleParamChange2, (void *)i);
if (ret != 0) {
printf("Remove watcher %s fail %d \n", context->name, i);
}
}
free(context);
return NULL;
}
static void StartWatcherInThread(const char *prefix)
{
TestWatchContext *context[MAX_THREAD_NUMBER] = { NULL };
for (size_t i = 0; i < MAX_THREAD_NUMBER; i++) {
context[i] = calloc(1, sizeof(TestWatchContext));
PLUGIN_CHECK(context[i] != NULL, return, "Failed to alloc context");
int len = sprintf_s(context[i]->name, sizeof(context[i]->name), "%s.%zu", prefix, i);
if (len > 0) {
printf("Add watcher %s \n", context[i]->name);
pthread_create(&context[i]->thread, NULL, CmdThreadWatcher, context[i]);
}
}
}
static void StartWatcher(const char *prefix)
{
static size_t index = 0;
int ret = SystemWatchParameter(prefix, HandleParamChange1, (void *)index);
if (ret != 0) {
printf("Add watcher %s fail \n", prefix);
return;
}
index++;
}
static int32_t BShellParamCmdWatch(BShellHandle shell, int32_t argc, char *argv[])
{
PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
PLUGIN_LOGV("BShellParamCmdWatch %s", argv[1]);
static size_t index = 0;
int ret = SystemWatchParameter(argv[1], HandleParamChange, (void *)index);
if (ret != 0) {
PLUGIN_LOGE("Failed to watch %s", argv[1]);
StartWatcher(argv[1]);
if (argc <= CMD_INDEX) {
return 0;
}
index++;
if (strcmp(argv[CMD_INDEX], "thread") == 0) { // 2 cmd index
StartWatcherInThread(argv[1]);
return 0;
}
int maxCount = StringToInt(argv[CMD_INDEX], -1); // 2 cmd index
if (maxCount <= 0 || maxCount > 65535) { // 65535 max count
PLUGIN_LOGE("Invalid input %s", argv[2]);
return 0;
}
uint32_t buffSize = 0;
char *buffer = GetLocalBuffer(&buffSize);
size_t count = 0;
while (count < (size_t)maxCount) { // 100 max count
int len = sprintf_s(buffer, buffSize, "%s.%d", argv[1], count);
PLUGIN_CHECK(len > 0, return -1, "Invalid buffer");
buffer[len] = '\0';
StartWatcher(buffer);
count++;
}
return 0;
}
......@@ -150,11 +270,71 @@ static int32_t BShellParamCmdUdidGet(BShellHandle shell, int32_t argc, char *arg
return 0;
}
static int CalcValue(const char *value)
{
char *begin = (char *)value;
while (*begin != '\0') {
if (*begin == ' ') {
begin++;
} else {
break;
}
}
char *end = begin + strlen(begin);
while (end > begin) {
if (*end > '9' || *end < '0') {
*end = '\0';
}
end--;
}
return StringToInt(begin, -1);
}
static int32_t BShellParamCmdMemGet(BShellHandle shell, int32_t argc, char *argv[])
{
PLUGIN_CHECK(argc > 1, return -1, "Invalid parameter");
uint32_t buffSize = 0; // 1024 max buffer for decode
char *buff = GetLocalBuffer(&buffSize);
int ret = sprintf_s(buff, buffSize - 1, "/proc/%s/smaps", argv[1]);
PLUGIN_CHECK(ret > 0, return -1, "Failed to format path %s", argv[1]);
buff[ret] = '\0';
int all = 0;
if (argc > 2 && strcmp(argv[2], "all") == 0) { // 2 2 max arg
all = 1;
}
FILE *fp = fopen(buff, "r");
int value = 0;
while (fp != NULL && buff != NULL && fgets(buff, buffSize, fp) != NULL) {
buff[buffSize - 1] = '\0';
if (strncmp(buff, "Pss:", strlen("Pss:")) == 0) {
int v = CalcValue(buff + strlen("Pss:"));
if (all) {
printf("Pss: %d kb\n", v);
}
value += v;
} else if (strncmp(buff, "SwapPss:", strlen("SwapPss:")) == 0) {
int v = CalcValue(buff + strlen("SwapPss:"));
if (all) {
printf("SwapPss: %d kb\n", v);
}
value += v;
}
}
if (fp != NULL) {
fclose(fp);
printf("Total mem %d kb\n", value);
} else {
printf("Failed to get memory for %s %s \n", argv[1], buff);
}
return 0;
}
int32_t BShellCmdRegister(BShellHandle shell, int execMode)
{
if (execMode == 0) {
const CmdInfo infos[] = {
{"init", BShellParamCmdGroupTest, "init group test", "init group test [stage]", "init group test"},
{"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
};
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegisterCmd(shell, &infos[i]);
......@@ -168,6 +348,7 @@ int32_t BShellCmdRegister(BShellHandle shell, int execMode)
{"uninstall", BShellParamCmdInstall, "uninstall plugin", "uninstall [name]", ""},
{"group", BShellParamCmdGroupTest, "group test", "group test [stage]", "group test"},
{"display", BShellParamCmdUdidGet, "display udid", "display udid", "display udid"},
{"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
};
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
......
......@@ -94,36 +94,40 @@ public:
ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
// has beed deleted
ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
EXPECT_NE(ret, 0);
// 非法
ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", TestParameterChange, nullptr);
EXPECT_NE(ret, 0);
ret = SystemWatchParameter("test.permission.read.test1*", TestParameterChange, nullptr);
#ifdef __MUSL__
EXPECT_EQ(ret, DAC_RESULT_FORBIDED);
#endif
return 0;
}
int TestDelWatcher()
{
int ret = SystemWatchParameter("test.permission.watcher.test1", nullptr, nullptr);
size_t index = 1;
int ret = SystemWatchParameter("test.permission.watcher.test3.1", TestParameterChange, (void *)index);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test3.1*", TestParameterChange, (void *)index);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test3.2", TestParameterChange, (void *)index);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test1*", nullptr, nullptr);
ret = SystemWatchParameter("test.permission.watcher.test3.1", nullptr, nullptr);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test2", nullptr, nullptr);
ret = SystemWatchParameter("test.permission.watcher.test3.1*", nullptr, nullptr);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test3.2", nullptr, nullptr);
EXPECT_EQ(ret, 0);
// 非法
ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", nullptr, nullptr);
EXPECT_NE(ret, 0);
ret = SystemWatchParameter("test.permission.read.test1*", nullptr, nullptr);
#ifdef __MUSL__
EXPECT_EQ(ret, DAC_RESULT_FORBIDED);
#endif
return 0;
}
......@@ -134,16 +138,15 @@ public:
MessageOption option;
data.WriteInterfaceToken(IWatcher::GetDescriptor());
data.WriteString(name);
data.WriteString(name);
data.WriteString("watcherId");
int ret = SystemWatchParameter(name.c_str(), TestParameterChange, nullptr);
EXPECT_EQ(ret, 0);
OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
OHOS::init_param::WatcherManagerKits::ParamWatcherKitPtr watcher = instance.GetParamWatcher(name);
if (watcher != nullptr) {
watcher->OnRemoteRequest(IWatcher::PARAM_CHANGE, data, reply, option);
watcher->OnRemoteRequest(IWatcher::PARAM_CHANGE + 1, data, reply, option);
watcher->OnParameterChange("testname", "testvalue");
WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
if (instance.remoteWatcher_ != nullptr) {
instance.remoteWatcher_->OnRemoteRequest(IWatcher::PARAM_CHANGE, data, reply, option);
instance.remoteWatcher_->OnRemoteRequest(IWatcher::PARAM_CHANGE + 1, data, reply, option);
instance.remoteWatcher_->OnParameterChange(name.c_str(), "testname", "testvalue");
}
return 0;
}
......
......@@ -26,6 +26,7 @@
#include "parcel.h"
#include "securec.h"
#include "system_ability_definition.h"
#include "string_ex.h"
#include "watcher.h"
#include "watcher_manager.h"
#include "watcher_proxy.h"
......@@ -41,7 +42,7 @@ public:
TestWatcher() {}
~TestWatcher() = default;
void OnParameterChange(const std::string &name, const std::string &value) override
void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) override
{
printf("TestWatcher::OnParameterChange name %s %s \n", name.c_str(), value.c_str());
}
......@@ -57,7 +58,7 @@ public:
void TearDown() {}
void TestBody() {}
int TestAddWatcher(const std::string &keyPrefix, uint32_t &watcherId)
int TestAddRemoteWatcher(uint32_t agentId, uint32_t &watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
......@@ -66,19 +67,58 @@ public:
MessageOption option;
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteString(keyPrefix);
sptr<IWatcher> watcher = new TestWatcher();
bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote");
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option);
data.WriteUint32(agentId);
watcherManager->OnRemoteRequest(IWatcherManager::ADD_REMOTE_AGENT, data, reply, option);
watcherId = reply.ReadUint32();
EXPECT_NE(watcherId, 0);
EXPECT_EQ(watcherManager->GetWatcherGroup(1000) != NULL, 0); // 1000 test group id
EXPECT_EQ(watcherManager->GetWatcherGroup("TestAddWatcher") != NULL, 0); // test key not exist
auto remoteWatcher = watcherManager->GetRemoteWatcher(watcherId);
if (remoteWatcher != nullptr) {
EXPECT_EQ(remoteWatcher->GetAgentId(), agentId);
} else {
EXPECT_EQ(0, agentId);
}
return 0;
}
int TestDelRemoteWatcher(uint32_t watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteUint32(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::DEL_REMOTE_AGENT, data, reply, option);
EXPECT_EQ(reply.ReadInt32(), 0);
EXPECT_EQ(watcherManager->GetRemoteWatcher(watcherId) == nullptr, 1);
return 0;
}
int TestAddWatcher(const std::string &keyPrefix, uint32_t watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteString(keyPrefix);
data.WriteUint32(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option);
int ret = reply.ReadInt32();
EXPECT_EQ(ret, 0);
EXPECT_EQ(watcherManager->GetWatcherGroup(keyPrefix) != nullptr, 1);
return 0;
}
int TestDelWatcher(const std::string &keyPrefix, uint32_t &watcherId)
int TestDelWatcher(const std::string &keyPrefix, uint32_t watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
......@@ -90,7 +130,6 @@ public:
data.WriteUint32(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::DEL_WATCHER, data, reply, option);
EXPECT_EQ(reply.ReadInt32(), 0);
printf("TestDelWatcher %s watcherId %d %p \n", keyPrefix.c_str(), watcherId, watcherManager);
return 0;
}
......@@ -103,7 +142,7 @@ public:
msgSize = PARAM_ALIGN(msgSize); // align
std::vector<char> buffer(msgSize, 0);
ParamMessage *msg = (ParamMessage *)buffer.data();
WATCHER_CHECK(msg != NULL, return -1, "Invalid msg");
WATCHER_CHECK(msg != nullptr, return -1, "Invalid msg");
msg->type = MSG_NOTIFY_PARAM;
msg->msgSize = msgSize;
msg->id.watcherId = watcherId;
......@@ -112,7 +151,7 @@ public:
uint32_t offset = 0;
ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, value.c_str(), value.size());
WATCHER_CHECK(ret == 0, return -1, "Failed to fill value");
watcherManager->ProcessWatcherMessage(buffer, msgSize);
watcherManager->ProcessWatcherMessage(msg);
return 0;
}
......@@ -124,59 +163,61 @@ public:
EXPECT_NE(remoteObj, nullptr);
WatcherProxy *watcher = new WatcherProxy(remoteObj);
if (watcher != nullptr) {
watcher->OnParameterChange(name, value);
watcher->OnParameterChange(name, name, value);
delete watcher;
}
return 0;
}
int TestWatchAgentDel(const std::string &keyPrefix)
int TestWatchAgentDump(const std::string &keyPrefix)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
MessageParcel data;
MessageParcel reply;
MessageOption option;
// dump watcher
std::vector<std::u16string> args = {};
watcherManager->Dump(STDOUT_FILENO, args);
// dump parameter
args.push_back(Str8ToStr16("-h"));
watcherManager->Dump(STDOUT_FILENO, args);
args.clear();
args.push_back(Str8ToStr16("-k"));
args.push_back(Str8ToStr16(keyPrefix.c_str()));
watcherManager->Dump(STDOUT_FILENO, args);
return 0;
}
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteString(keyPrefix);
sptr<IWatcher> watcher = new TestWatcher();
bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote");
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option);
uint32_t watcherId = reply.ReadUint32();
EXPECT_NE(watcherId, 0);
int TestWatchAgentDied(uint32_t watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get manager");
auto remoteWatcher = watcherManager->GetRemoteWatcher(watcherId);
WATCHER_CHECK(remoteWatcher != nullptr, return -1, "Failed to get remote watcher");
if (watcherManager->GetDeathRecipient() != nullptr) {
watcherManager->GetDeathRecipient()->OnRemoteDied(watcher->AsObject());
watcherManager->GetDeathRecipient()->OnRemoteDied(remoteWatcher->GetWatcher()->AsObject());
}
printf("TestWatchAgentDel %s success \n", keyPrefix.c_str());
EXPECT_EQ(watcherManager->GetWatcher(watcherId) == nullptr, 1);
EXPECT_EQ(watcherManager->GetRemoteWatcher(watcherId) == nullptr, 1);
return 0;
}
int TestInvalid(const std::string &keyPrefix)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get manager");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteString(keyPrefix);
sptr<IWatcher> watcher = new TestWatcher();
bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote");
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER + 1, data, reply, option);
watcherManager->OnRemoteRequest(IWatcherManager::REFRESH_WATCHER + 1, data, reply, option);
if (watcherManager->GetDeathRecipient() != nullptr) {
watcherManager->GetDeathRecipient()->OnRemoteDied(watcher->AsObject());
}
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteString(keyPrefix);
watcherManager->OnRemoteRequest(IWatcherManager::REFRESH_WATCHER + 1, data, reply, option);
return 0;
}
int TestStop()
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get manager");
watcherManager->OnStop();
return 0;
}
......@@ -199,61 +240,79 @@ HWTEST_F(WatcherProxyUnitTest, TestAddWatcher, TestSize.Level0)
{
WatcherProxyUnitTest test;
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1000, watcherId); // 1000 test agent
test.TestAddWatcher("test.permission.watcher.test1", watcherId);
test.TestProcessWatcherMessage("test.permission.watcher.test1", watcherId);
test.TestWatchAgentDump("test.permission.watcher.test1");
}
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher2, TestSize.Level0)
{
WatcherProxyUnitTest test;
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1001, watcherId); // 1001 test agent
test.TestAddWatcher("test.permission.watcher.test2", watcherId);
test.TestAddWatcher("test.permission.watcher.test2", watcherId);
test.TestAddWatcher("test.permission.watcher.test2", watcherId);
test.TestWatchAgentDump("test.permission.watcher.test2");
}
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher3, TestSize.Level0)
{
WatcherProxyUnitTest test;
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1003, watcherId); // 1003 test agent
test.TestAddWatcher("test.permission.watcher.test3", watcherId);
test.TestWatchAgentDump("test.permission.watcher.test3");
}
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher4, TestSize.Level0)
{
WatcherProxyUnitTest test;
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1004, watcherId); // 1004 test agent
SystemSetParameter("test.watcher.test4", "1101");
SystemSetParameter("test.watcher.test4.test", "1102");
test.TestAddWatcher("test.watcher.test4*", watcherId);
test.TestWatchAgentDump("test.watcher.test4*");
}
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher5, TestSize.Level0)
{
WatcherProxyUnitTest test;
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1005, watcherId); // 1005 test agent
test.TestAddWatcher("test.permission.watcher.test5", watcherId);
SystemSetParameter("test.permission.watcher.test5", "1101");
test.TestWatchAgentDump("test.permission.watcher.test5");
}
HWTEST_F(WatcherProxyUnitTest, TestDelWatcher, TestSize.Level0)
{
WatcherProxyUnitTest test;
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1006, watcherId); // 1005 test agent
test.TestAddWatcher("test.permission.watcher.testDel", watcherId);
test.TestDelWatcher("test.permission.watcher.testDel", watcherId);
test.TestDelRemoteWatcher(watcherId);
test.TestWatchAgentDump("test.permission.watcher.testDel");
}
HWTEST_F(WatcherProxyUnitTest, TestWatchProxy, TestSize.Level0)
HWTEST_F(WatcherProxyUnitTest, TestDiedWatcher, TestSize.Level0)
{
WatcherProxyUnitTest test;
test.TestWatchProxy("test.permission.watcher.test1", "watcherId");
uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1006, watcherId); // 1005 test agent
test.TestAddWatcher("test.permission.watcher.testdied", watcherId);
test.TestDelWatcher("test.permission.watcher.testdied", watcherId);
test.TestWatchAgentDied(watcherId);
test.TestWatchAgentDump("test.permission.watcher.testdied");
}
HWTEST_F(WatcherProxyUnitTest, TestWatchAgentDel, TestSize.Level0)
HWTEST_F(WatcherProxyUnitTest, TestWatchProxy, TestSize.Level0)
{
WatcherProxyUnitTest test;
test.TestWatchAgentDel("test.permission.watcher.test1");
test.TestWatchProxy("test.permission.watcher.test1", "watcherId");
}
HWTEST_F(WatcherProxyUnitTest, TestInvalid, TestSize.Level0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册