!1143 域账号监听机制增强

Merge pull request !1143 from liushuling/listener
This commit is contained in:
openharmony_ci 2023-05-05 13:54:55 +00:00 committed by Gitee
commit f5499f88ec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
21 changed files with 418 additions and 120 deletions

View File

@ -63,8 +63,6 @@ enum {
ERR_ACCOUNT_COMMON_POST_TASK,
ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED,
ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED,
ERR_ACCOUNT_COMMON_LISTENER_EXIST_FAILED,
ERR_ACCOUNT_COMMON_LISTENER_NOT_EXIST_FAILED
};
// Error code for AccountMgr

View File

@ -33,7 +33,10 @@ public:
const std::string &domain, const std::string &accountName, DomainAccountStatus &status) override;
ErrCode RegisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener) override;
ErrCode UnregisterAccountStatusListener(const DomainAccountInfo &info) override;
ErrCode RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener) override;
ErrCode UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener) override;
ErrCode UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener) override;
ErrCode Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
const sptr<IDomainAuthCallback> &callback) override;
ErrCode AuthUser(int32_t userId, const std::vector<uint8_t> &password,

View File

@ -38,7 +38,9 @@ public:
DOMAIN_GET_ACCESS_TOKEN = 7,
DOMAIN_ACCOUNT_STATUS_ENQUIRY = 8,
DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER = 9,
DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER = 10
DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER = 10,
DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER_BY_INFO = 11,
DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER_BY_INFO = 12,
};
virtual ErrCode RegisterPlugin(const sptr<IDomainAccountPlugin> &plugin) = 0;
@ -47,7 +49,10 @@ public:
const std::string &domain, const std::string &accountName, DomainAccountStatus &status) = 0;
virtual ErrCode RegisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener) = 0;
virtual ErrCode UnregisterAccountStatusListener(const DomainAccountInfo &info) = 0;
virtual ErrCode RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener) = 0;
virtual ErrCode UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener) = 0;
virtual ErrCode UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener) = 0;
virtual ErrCode Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
const sptr<IDomainAuthCallback> &callback) = 0;
virtual ErrCode AuthUser(int32_t userId, const std::vector<uint8_t> &password,

View File

@ -201,11 +201,54 @@ ErrCode DomainAccountClient::RegisterAccountStatusListener(
ACCOUNT_LOGE("callback is nullptr");
return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
}
std::lock_guard<std::mutex> lock(recordMutex_);
auto recordIter = listenerRecords_.find(listener);
sptr<IDomainAccountCallback> callback = nullptr;
if (recordIter == listenerRecords_.end()) {
std::shared_ptr<DomainAccountStatusListenerService> listenerService =
std::make_shared<DomainAccountStatusListenerService>(listener);
callback = new (std::nothrow) DomainAccountCallbackService(listenerService);
if (callback == nullptr) {
ACCOUNT_LOGE("failed to check domain account callback service");
return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
}
} else {
callback = recordIter->second.callback_;
}
auto proxy = GetDomainAccountProxy();
if (proxy == nullptr) {
ACCOUNT_LOGE("failed to get domain account proxy");
return ERR_ACCOUNT_COMMON_GET_PROXY;
}
ErrCode result = proxy->RegisterAccountStatusListener(info, callback);
if (result != ERR_OK) {
ACCOUNT_LOGE("RegisterAccountStatusListener failed, error is %{public}d", result);
return result;
}
if (recordIter == listenerRecords_.end()) {
listenerRecords_.emplace(listener, DomainAccountClient::DomainAccountListenerRecord(info, callback));
} else {
recordIter->second.infos_.emplace_back(info);
}
return result;
}
ErrCode DomainAccountClient::RegisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> &listener)
{
if (listener == nullptr) {
ACCOUNT_LOGE("callback is nullptr");
return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
}
std::lock_guard<std::mutex> lock(recordMutex_);
auto recordIt = listenerRecords_.find(listener);
if (recordIt != listenerRecords_.end()) {
ACCOUNT_LOGI("listener already exist");
return ERR_OK;
}
std::shared_ptr<DomainAccountStatusListenerService> listenerService =
std::make_shared<DomainAccountStatusListenerService>(listener);
sptr<IDomainAccountCallback> callback =
new (std::nothrow) DomainAccountCallbackService(listenerService);
sptr<IDomainAccountCallback> callback = new (std::nothrow) DomainAccountCallbackService(listenerService);
if (callback == nullptr) {
ACCOUNT_LOGE("failed to check domain account callback service");
return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
@ -215,17 +258,71 @@ ErrCode DomainAccountClient::RegisterAccountStatusListener(
ACCOUNT_LOGE("failed to get domain account proxy");
return ERR_ACCOUNT_COMMON_GET_PROXY;
}
return proxy->RegisterAccountStatusListener(info, callback);
ErrCode result = proxy->RegisterAccountStatusListener(callback);
if (result == ERR_OK) {
listenerRecords_.emplace(listener, DomainAccountClient::DomainAccountListenerRecord(callback));
}
return result;
}
ErrCode DomainAccountClient::UnregisterAccountStatusListener(const DomainAccountInfo &info)
ErrCode DomainAccountClient::UnregisterAccountStatusListener(
const std::shared_ptr<DomainAccountStatusListener> &listener)
{
if (listener == nullptr) {
ACCOUNT_LOGE("callback is nullptr");
return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
}
std::lock_guard<std::mutex> lock(recordMutex_);
auto recordIt = listenerRecords_.find(listener);
if (recordIt == listenerRecords_.end()) {
ACCOUNT_LOGI("listener not register");
return ERR_OK;
}
auto proxy = GetDomainAccountProxy();
if (proxy == nullptr) {
ACCOUNT_LOGE("failed to get domain account proxy");
return ERR_ACCOUNT_COMMON_GET_PROXY;
}
return proxy->UnregisterAccountStatusListener(info);
ErrCode result = proxy->UnregisterAccountStatusListener(recordIt->second.callback_);
if (result == ERR_OK) {
listenerRecords_.erase(recordIt);
}
return result;
}
ErrCode DomainAccountClient::UnregisterAccountStatusListener(
const DomainAccountInfo &info, const std::shared_ptr<DomainAccountStatusListener> &listener)
{
if (listener == nullptr) {
ACCOUNT_LOGE("callback is nullptr");
return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
}
auto proxy = GetDomainAccountProxy();
if (proxy == nullptr) {
ACCOUNT_LOGE("failed to get domain account proxy");
return ERR_ACCOUNT_COMMON_GET_PROXY;
}
std::lock_guard<std::mutex> lock(recordMutex_);
auto recordIt = listenerRecords_.find(listener);
if (recordIt == listenerRecords_.end()) {
ACCOUNT_LOGI("listener not exist");
return ERR_OK;
}
ErrCode result = proxy->UnregisterAccountStatusListener(info, recordIt->second.callback_);
if (result != ERR_OK) {
return result;
}
for (auto it = recordIt->second.infos_.begin(); it != recordIt->second.infos_.end(); ++it) {
if ((info.accountId_ == it->accountId_) ||
((info.accountName_ == it->accountName_) && (info.domain_ == it->domain_))) {
recordIt->second.infos_.erase(it);
if (recordIt->second.infos_.empty()) {
listenerRecords_.erase(recordIt);
}
break;
}
}
return result;
}
void DomainAccountClient::DomainAccountDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)

View File

@ -166,6 +166,30 @@ ErrCode DomainAccountProxy::RegisterAccountStatusListener(
return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
}
MessageParcel reply;
ErrCode result = SendRequest(IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER_BY_INFO, data, reply);
if (result != ERR_OK) {
ACCOUNT_LOGE("SendRequest err, result %{public}d.", result);
return result;
}
if (!reply.ReadInt32(result)) {
ACCOUNT_LOGE("fail to read result");
return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
}
return result;
}
ErrCode DomainAccountProxy::RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
ACCOUNT_LOGE("failed to write descriptor!");
return ERR_ACCOUNT_COMMON_WRITE_DESCRIPTOR_ERROR;
}
if ((listener == nullptr) || (!data.WriteRemoteObject(listener->AsObject()))) {
ACCOUNT_LOGE("fail to write callback");
return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
}
MessageParcel reply;
ErrCode result = SendRequest(IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER, data, reply);
if (result != ERR_OK) {
ACCOUNT_LOGE("SendRequest err, result %{public}d.", result);
@ -178,15 +202,15 @@ ErrCode DomainAccountProxy::RegisterAccountStatusListener(
return result;
}
ErrCode DomainAccountProxy::UnregisterAccountStatusListener(const DomainAccountInfo &info)
ErrCode DomainAccountProxy::UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
ACCOUNT_LOGE("failed to write descriptor!");
return ERR_ACCOUNT_COMMON_WRITE_DESCRIPTOR_ERROR;
}
if (!data.WriteParcelable(&info)) {
ACCOUNT_LOGE("fail to write parcelable");
if ((listener == nullptr) || (!data.WriteRemoteObject(listener->AsObject()))) {
ACCOUNT_LOGE("fail to write callback");
return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
}
@ -203,8 +227,39 @@ ErrCode DomainAccountProxy::UnregisterAccountStatusListener(const DomainAccountI
return result;
}
ErrCode DomainAccountProxy::Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
const sptr<IDomainAuthCallback> &callback)
ErrCode DomainAccountProxy::UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
ACCOUNT_LOGE("failed to write descriptor!");
return ERR_ACCOUNT_COMMON_WRITE_DESCRIPTOR_ERROR;
}
if (!data.WriteParcelable(&info)) {
ACCOUNT_LOGE("fail to write parcelable");
return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
}
if ((listener == nullptr) || (!data.WriteRemoteObject(listener->AsObject()))) {
ACCOUNT_LOGE("fail to write callback");
return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
}
MessageParcel reply;
ErrCode result =
SendRequest(IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER_BY_INFO, data, reply);
if (result != ERR_OK) {
ACCOUNT_LOGE("SendRequest err, result %{public}d.", result);
return result;
}
if (!reply.ReadInt32(result)) {
ACCOUNT_LOGE("fail to read result");
return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
}
return result;
}
ErrCode DomainAccountProxy::Auth(
const DomainAccountInfo &info, const std::vector<uint8_t> &password, const sptr<IDomainAuthCallback> &callback)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
@ -240,8 +295,8 @@ ErrCode DomainAccountProxy::Auth(const DomainAccountInfo &info, const std::vecto
return result;
}
ErrCode DomainAccountProxy::AuthUser(int32_t userId, const std::vector<uint8_t> &password,
const sptr<IDomainAuthCallback> &callback)
ErrCode DomainAccountProxy::AuthUser(
int32_t userId, const std::vector<uint8_t> &password, const sptr<IDomainAuthCallback> &callback)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
@ -361,5 +416,5 @@ ErrCode DomainAccountProxy::GetAccessToken(
}
return result;
}
} // namespace AccountSA
} // namespace OHOS
} // namespace AccountSA
} // namespace OHOS

View File

@ -54,6 +54,12 @@ void DomainAccountStatusListenerService::OnResult(const int32_t errCode, Parcel
return;
}
report.status = static_cast<DomainAccountStatus>(status);
int32_t userId;
if (!parcel.ReadInt32(userId)) {
ACCOUNT_LOGE("Read userId failed");
return;
}
report.userId = userId;
listener_->OnStatusChanged(report);
ACCOUNT_LOGI("OnStatusChanged end");
return;

View File

@ -1126,7 +1126,6 @@ public:
EXPECT_EQ(data.event, DomainAccountEvent::LOG_IN);
EXPECT_EQ(data.status, DomainAccountStatus::LOGIN);
visited = true;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo), ERR_OK);
}
bool visited = false;
@ -1143,7 +1142,6 @@ public:
EXPECT_EQ(data.event, DomainAccountEvent::LOG_IN);
EXPECT_EQ(data.status, DomainAccountStatus::LOGIN_BACKGROUND);
visited = true;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo), ERR_OK);
}
bool visited = false;
@ -1160,7 +1158,6 @@ public:
EXPECT_EQ(data.event, DomainAccountEvent::TOKEN_UPDATED);
EXPECT_EQ(data.status, DomainAccountStatus::LOGIN);
visited = true;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo), ERR_OK);
}
bool visited = false;
@ -1177,7 +1174,6 @@ public:
EXPECT_EQ(data.event, DomainAccountEvent::TOKEN_UPDATED);
EXPECT_EQ(data.status, DomainAccountStatus::LOGIN_BACKGROUND);
visited = true;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo), ERR_OK);
}
bool visited = false;
@ -1194,7 +1190,6 @@ public:
EXPECT_EQ(data.event, DomainAccountEvent::TOKEN_INVALID);
EXPECT_EQ(data.status, DomainAccountStatus::LOGOUT);
visited = true;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo), ERR_OK);
}
bool visited = false;
@ -1211,9 +1206,6 @@ public:
EXPECT_EQ(data.event, DomainAccountEvent::LOG_OUT);
EXPECT_EQ(data.status, DomainAccountStatus::LOGOUT);
visited = true;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo), ERR_OK);
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(data.domainAccountInfo),
ERR_ACCOUNT_COMMON_LISTENER_NOT_EXIST_FAILED);
}
bool visited = false;
@ -1250,8 +1242,8 @@ HWTEST_F(DomainAccountClientModuleTest, UnregisterAccountStatusListener_001, Tes
domainInfo.accountName_ = STRING_NAME_NEW;
domainInfo.domain_ = STRING_DOMAIN;
domainInfo.accountId_ = STRING_ACCOUNTID;
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(domainInfo),
ERR_ACCOUNT_COMMON_LISTENER_NOT_EXIST_FAILED);
auto listener = std::make_shared<ListenerLogIn>();
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(listener), ERR_OK);
}
/**
@ -1296,10 +1288,9 @@ HWTEST_F(DomainAccountClientModuleTest, RegisterAccountStatusListener_003, TestS
auto listener = std::make_shared<ListenerLogIn>();
EXPECT_EQ(DomainAccountClient::GetInstance().RegisterAccountStatusListener(domainInfo, listener), ERR_OK);
EXPECT_EQ(DomainAccountClient::GetInstance().RegisterAccountStatusListener(domainInfo, listener),
ERR_ACCOUNT_COMMON_LISTENER_EXIST_FAILED);
EXPECT_EQ(DomainAccountClient::GetInstance().RegisterAccountStatusListener(domainInfo, listener), ERR_OK);
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(domainInfo), ERR_OK);
EXPECT_EQ(DomainAccountClient::GetInstance().UnregisterAccountStatusListener(listener), ERR_OK);
int32_t userId = -1;
errCode = OsAccountManager::GetOsAccountLocalIdFromDomain(domainInfo, userId);
EXPECT_EQ(errCode, ERR_OK);

View File

@ -213,7 +213,7 @@ void MockDomainPlugin::GetAccessToken(const DomainAccountInfo &domainInfo, const
const GetAccessTokenOptions &option, const std::shared_ptr<DomainAccountCallback> &callback)
{
Parcel parcel;
if (domainInfo.accountName_ == STRING_NAME) {
if ((domainInfo.accountName_ == STRING_NAME) || (domainInfo.accountId_ == "555")) {
parcel.WriteUInt8Vector(DEFAULT_PASSWORD);
callback->OnResult(0, parcel);
}

View File

@ -227,7 +227,6 @@ Json OsAccountInfo::ToJson() const
{DOMAIN_NAME, domainInfo_.domain_},
{DOMAIN_ACCOUNT_NAME, domainInfo_.accountName_},
{DOMAIN_ACCOUNT_ID, domainInfo_.accountId_},
{DOMAIN_ACCOUNT_STATUS, domainInfo_.status_},
},
}
};
@ -286,10 +285,6 @@ void OsAccountInfo::FromJson(const Json &jsonObject)
typeJson, typeJson.end(), DOMAIN_ACCOUNT_NAME, domainInfo_.accountName_, OHOS::AccountSA::JsonType::STRING);
OHOS::AccountSA::GetDataByType<std::string>(
typeJson, typeJson.end(), DOMAIN_ACCOUNT_ID, domainInfo_.accountId_, OHOS::AccountSA::JsonType::STRING);
int status;
OHOS::AccountSA::GetDataByType<int>(
typeJson, typeJson.end(), DOMAIN_ACCOUNT_STATUS, status, OHOS::AccountSA::JsonType::NUMBER);
domainInfo_.status_ = static_cast<DomainAccountStatus>(status);
}
bool OsAccountInfo::Marshalling(Parcel &parcel) const

View File

@ -36,6 +36,7 @@
#ifndef OS_ACCOUNT_INTERFACES_INNERKITS_DOMAIN_ACCOUNT_INCLUDE_DOMAIN_ACCOUNT_CLIENT_H
#define OS_ACCOUNT_INTERFACES_INNERKITS_DOMAIN_ACCOUNT_INCLUDE_DOMAIN_ACCOUNT_CLIENT_H
#include <map>
#include <mutex>
#include "account_error_no.h"
#include "domain_account_callback.h"
@ -116,11 +117,26 @@ public:
ErrCode GetAccountStatus(const std::string &domain, const std::string &accountName, DomainAccountStatus &status);
ErrCode RegisterAccountStatusListener(
const DomainAccountInfo &info, const std::shared_ptr<DomainAccountStatusListener> &listener);
ErrCode UnregisterAccountStatusListener(const DomainAccountInfo &info);
ErrCode RegisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> &listener);
ErrCode UnregisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> &listener);
ErrCode UnregisterAccountStatusListener(
const DomainAccountInfo &info, const std::shared_ptr<DomainAccountStatusListener> &listener);
private:
DomainAccountClient() = default;
~DomainAccountClient() = default;
public:
class DomainAccountListenerRecord {
public:
DomainAccountListenerRecord(const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
: infos_({info}), callback_(callback){};
DomainAccountListenerRecord(const sptr<IDomainAccountCallback> &callback) : infos_({}), callback_(callback){};
std::vector<DomainAccountInfo> infos_;
sptr<IDomainAccountCallback> callback_;
};
private:
class DomainAccountDeathRecipient : public IRemoteObject::DeathRecipient {
public:
DomainAccountDeathRecipient() = default;
@ -131,14 +147,17 @@ private:
DISALLOW_COPY_AND_MOVE(DomainAccountDeathRecipient);
};
sptr<IDomainAccount> GetDomainAccountProxy();
void ResetDomainAccountProxy(const wptr<IRemoteObject>& remote);
void ResetDomainAccountProxy(const wptr<IRemoteObject> &remote);
ErrCode AuthProxyInit(const std::shared_ptr<DomainAuthCallback> &callback,
sptr<DomainAuthCallbackService> &callbackService, sptr<IDomainAccount> &proxy);
private:
std::mutex mutex_;
std::mutex recordMutex_;
sptr<IDomainAccount> proxy_ = nullptr;
sptr<DomainAccountDeathRecipient> deathRecipient_ = nullptr;
std::map<std::shared_ptr<DomainAccountStatusListener>, DomainAccountClient::DomainAccountListenerRecord>
listenerRecords_;
};
} // namespace AccountSA
} // namespace OHOS

View File

@ -96,11 +96,12 @@ struct DomainAuthResult : public Parcelable {
static DomainAuthResult *Unmarshalling(Parcel &parcel);
};
typedef struct {
struct DomainAccountEventData {
int32_t userId = -1;
DomainAccountInfo domainAccountInfo;
DomainAccountEvent event;
DomainAccountStatus status;
} DomainAccountEventData;
};
} // namespace AccountSA
} // namespace OHOS
#endif // OS_ACCOUNT_INTERFACES_INNERKITS_DOMAIN_ACCOUNT_INCLUDE_DOMAIN_ACCOUNT_COMMON_H

View File

@ -34,7 +34,10 @@ public:
const std::string &domain, const std::string &accountName, DomainAccountStatus &status) override;
ErrCode RegisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener) override;
ErrCode UnregisterAccountStatusListener(const DomainAccountInfo &info) override;
ErrCode RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener) override;
ErrCode UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener) override;
ErrCode UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener) override;
ErrCode Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
const sptr<IDomainAuthCallback> &callback) override;
ErrCode AuthUser(int32_t userId, const std::vector<uint8_t> &password,

View File

@ -44,6 +44,8 @@ private:
ErrCode ProcGetDomainAccessToken(MessageParcel &data, MessageParcel &reply);
ErrCode ProcUnregisterAccountStatusListener(MessageParcel &data, MessageParcel &reply);
ErrCode ProcRegisterAccountStatusListener(MessageParcel &data, MessageParcel &reply);
ErrCode ProcUnregisterAccountStatusListenerByInfo(MessageParcel &data, MessageParcel &reply);
ErrCode ProcRegisterAccountStatusListenerByInfo(MessageParcel &data, MessageParcel &reply);
private:
static const std::map<uint32_t, DomainAccountStubFunc> stubFuncMap_;

View File

@ -56,9 +56,11 @@ public:
void GetTokenFromMap(int32_t userId, std::vector<uint8_t> &token);
void RemoveTokenFromMap(int32_t userId);
ErrCode GetAccountStatus(const std::string &domain, const std::string &accountName, DomainAccountStatus &status);
ErrCode RegisterAccountStatusListener(
ErrCode RegisterAccountStatusListener(const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener);
ErrCode RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener);
ErrCode UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener);
ErrCode UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener);
ErrCode UnregisterAccountStatusListener(const DomainAccountInfo &info);
void NotifyDomainAccountEvent(
int32_t userId, DomainAccountEvent event, DomainAccountStatus status, const DomainAccountInfo &info);
ErrCode GetDomainAccountInfoByUserId(int32_t userId, DomainAccountInfo &domainInfo);

View File

@ -18,6 +18,7 @@
#include <map>
#include <mutex>
#include <set>
#include <vector>
#include "domain_account_common.h"
@ -31,11 +32,12 @@ public:
StatusListenerManager();
static StatusListenerManager& GetInstance();
ErrCode InsertListenerToMap(
ErrCode InsertListenerToRecords(
const std::string &domain, const std::string &accountName, const sptr<IRemoteObject> &listener);
ErrCode InsertListenerToRecords(const sptr<IRemoteObject> &listener);
ErrCode RemoveListenerByListener(const sptr<IRemoteObject> &listener);
ErrCode RemoveListenerByInfoAndListener(
const std::string &domain, const std::string &accountName, const sptr<IRemoteObject> &listener);
ErrCode RemoveListenerByStr(const std::string &domain, const std::string &accountName);
ErrCode RemoveListenerByObject(const sptr<IRemoteObject> &listener);
sptr<IRemoteObject> GetListenerInMap(const std::string &domainAccountStr);
void NotifyEventAsync(const DomainAccountEventData &report);
std::string GetDomainAccountStr(const std::string &domain, const std::string &accountName) const;
@ -43,7 +45,9 @@ private:
void DomainAccountEventParcel(const DomainAccountEventData &report, Parcel &parcel);
std::mutex mutex_;
std::map<std::string, sptr<IRemoteObject>> statusListenerMap_;
std::set<sptr<IRemoteObject>> listenerAll_;
std::map<sptr<IRemoteObject>, std::set<std::string>> listenerToAccount_;
std::map<std::string, std::set<sptr<IRemoteObject>>> accountToListener_;
sptr<IRemoteObject::DeathRecipient> listenerDeathRecipient_;
};
} // namespace AccountSA

View File

@ -90,15 +90,26 @@ ErrCode DomainAccountManagerService::GetAccountStatus(
return InnerDomainAccountManager::GetInstance().GetAccountStatus(domain, accountName, status);
}
ErrCode DomainAccountManagerService::RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
{
return InnerDomainAccountManager::GetInstance().RegisterAccountStatusListener(listener);
}
ErrCode DomainAccountManagerService::RegisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener)
{
return InnerDomainAccountManager::GetInstance().RegisterAccountStatusListener(info, listener);
}
ErrCode DomainAccountManagerService::UnregisterAccountStatusListener(const DomainAccountInfo &info)
ErrCode DomainAccountManagerService::UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener)
{
return InnerDomainAccountManager::GetInstance().UnregisterAccountStatusListener(info);
return InnerDomainAccountManager::GetInstance().UnregisterAccountStatusListener(info, listener);
}
ErrCode DomainAccountManagerService::UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
{
return InnerDomainAccountManager::GetInstance().UnregisterAccountStatusListener(listener);
}
} // namespace AccountSA
} // namespace OHOS

View File

@ -74,6 +74,14 @@ const std::map<uint32_t, DomainAccountStub::DomainAccountStubFunc> DomainAccount
{
IDomainAccount::Message::DOMAIN_GET_ACCESS_TOKEN,
&DomainAccountStub::ProcGetDomainAccessToken
},
{
IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER_BY_INFO,
&DomainAccountStub::ProcUnregisterAccountStatusListenerByInfo
},
{
IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER_BY_INFO,
&DomainAccountStub::ProcRegisterAccountStatusListenerByInfo
}
};
@ -217,6 +225,22 @@ ErrCode DomainAccountStub::ProcGetAccountStatus(MessageParcel &data, MessageParc
}
ErrCode DomainAccountStub::ProcRegisterAccountStatusListener(MessageParcel &data, MessageParcel &reply)
{
auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
if (callback == nullptr) {
ACCOUNT_LOGE("failed to read domain callback");
return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
}
ErrCode result = RegisterAccountStatusListener(callback);
if (!reply.WriteInt32(result)) {
ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_OK;
}
ErrCode DomainAccountStub::ProcRegisterAccountStatusListenerByInfo(MessageParcel &data, MessageParcel &reply)
{
std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
if (info == nullptr) {
@ -237,14 +261,34 @@ ErrCode DomainAccountStub::ProcRegisterAccountStatusListener(MessageParcel &data
return ERR_OK;
}
ErrCode DomainAccountStub::ProcUnregisterAccountStatusListener(MessageParcel &data, MessageParcel &reply)
ErrCode DomainAccountStub::ProcUnregisterAccountStatusListenerByInfo(MessageParcel &data, MessageParcel &reply)
{
std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
if (info == nullptr) {
ACCOUNT_LOGE("failed to read domain account info");
return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
}
ErrCode result = UnregisterAccountStatusListener(*info);
auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
if (callback == nullptr) {
ACCOUNT_LOGE("failed to read domain callback");
return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
}
ErrCode result = UnregisterAccountStatusListener(*info, callback);
if (!reply.WriteInt32(result)) {
ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_OK;
}
ErrCode DomainAccountStub::ProcUnregisterAccountStatusListener(MessageParcel &data, MessageParcel &reply)
{
auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
if (callback == nullptr) {
ACCOUNT_LOGE("failed to read domain callback");
return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
}
ErrCode result = UnregisterAccountStatusListener(callback);
if (!reply.WriteInt32(result)) {
ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
return IPC_STUB_WRITE_PARCEL_ERR;
@ -346,6 +390,8 @@ ErrCode DomainAccountStub::CheckPermission(uint32_t code, int32_t uid)
case IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_ENQUIRY:
case IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER:
case IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER:
case IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER_BY_INFO:
case IDomainAccount::Message::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER_BY_INFO:
permissionName = AccountPermissionManager::GET_LOCAL_ACCOUNTS;
break;
case IDomainAccount::Message::DOMAIN_AUTH:

View File

@ -254,6 +254,7 @@ void InnerDomainAccountManager::NotifyDomainAccountEvent(
report.domainAccountInfo = info;
report.event = event;
report.status = status;
report.userId = userId;
StatusListenerManager::GetInstance().NotifyEventAsync(report);
}
@ -443,6 +444,11 @@ ErrCode InnerDomainAccountManager::GetAccountStatus(
return res;
}
ErrCode InnerDomainAccountManager::RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
{
return StatusListenerManager::GetInstance().InsertListenerToRecords(listener->AsObject());
}
ErrCode InnerDomainAccountManager::RegisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener)
{
@ -451,14 +457,26 @@ ErrCode InnerDomainAccountManager::RegisterAccountStatusListener(
if (res != ERR_OK) {
return res;
}
return StatusListenerManager::GetInstance().InsertListenerToMap(
return StatusListenerManager::GetInstance().InsertListenerToRecords(
info.domain_, info.accountName_, listener->AsObject());
}
ErrCode InnerDomainAccountManager::UnregisterAccountStatusListener(const DomainAccountInfo &info)
ErrCode InnerDomainAccountManager::UnregisterAccountStatusListener(
const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &listener)
{
int32_t userId = 0;
ErrCode res = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
if (res != ERR_OK) {
return res;
}
return StatusListenerManager::GetInstance().RemoveListenerByInfoAndListener(
info.domain_, info.accountName_, listener->AsObject());
}
ErrCode InnerDomainAccountManager::UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
{
// userid may be removed already.
return StatusListenerManager::GetInstance().RemoveListenerByStr(info.domain_, info.accountName_);
return StatusListenerManager::GetInstance().RemoveListenerByListener(listener->AsObject());
}
ErrCode InnerDomainAccountManager::GetAuthStatusInfo(

View File

@ -34,7 +34,7 @@ void StatusListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remot
ACCOUNT_LOGE("object is nullptr.");
return;
}
StatusListenerManager::GetInstance().RemoveListenerByObject(object);
StatusListenerManager::GetInstance().RemoveListenerByListener(object);
ACCOUNT_LOGI("end");
}
} // namespace AccessToken

View File

@ -55,71 +55,98 @@ std::string StatusListenerManager::GetDomainAccountStr(const std::string &domain
return domain + "&" + accountName;
}
sptr<IRemoteObject> StatusListenerManager::GetListenerInMap(const std::string &domainAccountStr)
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = statusListenerMap_.find(domainAccountStr);
if (iter != statusListenerMap_.end()) {
return iter->second;
}
return nullptr;
}
ErrCode StatusListenerManager::InsertListenerToMap(
const std::string &domain, const std::string &accountName, const sptr<IRemoteObject> &listener)
ErrCode StatusListenerManager::InsertListenerToRecords(const sptr<IRemoteObject> &listener)
{
if (listener == nullptr) {
ACCOUNT_LOGE("input is nullptr");
ACCOUNT_LOGE("listener is nullptr");
return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
}
std::string domainAccountStr = GetDomainAccountStr(domain, accountName);
if (GetListenerInMap(domainAccountStr) != nullptr) {
ACCOUNT_LOGE("listener has exist");
return ERR_ACCOUNT_COMMON_LISTENER_EXIST_FAILED;
}
std::lock_guard<std::mutex> lock(mutex_);
if (listenerAll_.find(listener) != listenerAll_.end()) {
ACCOUNT_LOGI("listener is already exist");
return ERR_OK;
}
if ((listenerDeathRecipient_ != nullptr) && (!listener->AddDeathRecipient(listenerDeathRecipient_))) {
ACCOUNT_LOGE("AddDeathRecipient failed");
return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
}
statusListenerMap_[domainAccountStr] = listener;
return 0;
listenerAll_.insert(listener);
return ERR_OK;
}
ErrCode StatusListenerManager::RemoveListenerByStr(const std::string &domain, const std::string &accountName)
ErrCode StatusListenerManager::InsertListenerToRecords(
const std::string &domain, const std::string &accountName, const sptr<IRemoteObject> &listener)
{
ACCOUNT_LOGI("RemoveListenerByStr enter.");
std::string domainAccountStr = GetDomainAccountStr(domain, accountName);
sptr<IRemoteObject> listener = GetListenerInMap(domainAccountStr);
if (listener == nullptr) {
ACCOUNT_LOGE("listener does not exist.");
return ERR_ACCOUNT_COMMON_LISTENER_NOT_EXIST_FAILED;
ACCOUNT_LOGE("listener is nullptr");
return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
}
std::lock_guard<std::mutex> lock(mutex_);
statusListenerMap_.erase(domainAccountStr);
std::string domainAccountStr = GetDomainAccountStr(domain, accountName);
auto listenerIt = listenerToAccount_.find(listener);
if (listenerIt != listenerToAccount_.end()) {
if (listenerIt->second.find(domainAccountStr) != listenerIt->second.end()) {
ACCOUNT_LOGI("listener is already exist");
return ERR_OK;
}
listenerIt->second.insert(domainAccountStr);
accountToListener_[domainAccountStr].insert(listener);
} else {
if ((listenerDeathRecipient_ != nullptr) && (!listener->AddDeathRecipient(listenerDeathRecipient_))) {
ACCOUNT_LOGE("AddDeathRecipient failed");
return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
}
std::set<std::string> domainSet;
domainSet.insert(domainAccountStr);
listenerToAccount_.emplace(listener, domainSet);
}
auto accountToListenerIt = accountToListener_.find(domainAccountStr);
if (accountToListenerIt != accountToListener_.end()) {
accountToListener_[domainAccountStr].insert(listener);
} else {
std::set<sptr<IRemoteObject>> listenerSet;
listenerSet.insert(listener);
accountToListener_.emplace(domainAccountStr, listenerSet);
}
return ERR_OK;
}
ErrCode StatusListenerManager::RemoveListenerByListener(const sptr<IRemoteObject> &listener)
{
std::lock_guard<std::mutex> lock(mutex_);
auto listenerToAccountIt = listenerToAccount_.find(listener);
if (listenerToAccountIt != listenerToAccount_.end()) {
for (auto domainAccount : listenerToAccountIt->second) {
accountToListener_[domainAccount].erase(listener);
}
listenerToAccount_.erase(listenerToAccountIt);
}
auto listenerToAllIt = listenerAll_.find(listener);
if (listenerToAllIt != listenerAll_.end()) {
listenerAll_.erase(listenerToAllIt);
}
if (listenerDeathRecipient_ != nullptr) {
listener->RemoveDeathRecipient(listenerDeathRecipient_);
}
return ERR_OK;
}
ErrCode StatusListenerManager::RemoveListenerByObject(const sptr<IRemoteObject> &listener)
ErrCode StatusListenerManager::RemoveListenerByInfoAndListener(
const std::string &domain, const std::string &accountName, const sptr<IRemoteObject> &listener)
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = statusListenerMap_.begin();
while (iter != statusListenerMap_.end()) {
if (listener == iter->second) {
statusListenerMap_.erase(iter->first);
if (listenerDeathRecipient_ != nullptr) {
listener->RemoveDeathRecipient(listenerDeathRecipient_);
}
ACCOUNT_LOGI("listener erased");
return ERR_OK;
}
iter++;
auto listenerToAccountIt = listenerToAccount_.find(listener);
if (listenerToAccountIt == listenerToAccount_.end()) {
ACCOUNT_LOGE("listener is not exist");
return ERR_OK;
}
return ERR_ACCOUNT_COMMON_LISTENER_NOT_EXIST_FAILED;
std::string domainAccountStr = GetDomainAccountStr(domain, accountName);
listenerToAccountIt->second.erase(domainAccountStr);
accountToListener_[domainAccountStr].erase(listener);
if (listenerDeathRecipient_ != nullptr) {
listener->RemoveDeathRecipient(listenerDeathRecipient_);
}
return ERR_OK;
}
void StatusListenerManager::DomainAccountEventParcel(const DomainAccountEventData &report, Parcel &parcel)
@ -136,6 +163,10 @@ void StatusListenerManager::DomainAccountEventParcel(const DomainAccountEventDat
ACCOUNT_LOGE("write status failed.");
return;
}
if (!parcel.WriteInt32(report.userId)) {
ACCOUNT_LOGE("write userId failed.");
return;
}
return;
}
@ -149,24 +180,35 @@ void StatusListenerManager::NotifyEventAsync(const DomainAccountEventData &repor
ACCOUNT_LOGI("No common event part! Publish nothing!");
#endif // HAS_CES_PART
std::string domainAccountStr = GetDomainAccountStr(
report.domainAccountInfo.domain_, report.domainAccountInfo.accountName_);
auto listener = GetListenerInMap(domainAccountStr);
if (listener == nullptr) {
ACCOUNT_LOGE("userId listener does not exist.");
return;
}
auto callback = iface_cast<IDomainAccountCallback>(listener);
if (callback != nullptr) {
ACCOUNT_LOGI("callback execute");
std::string domainAccountStr =
GetDomainAccountStr(report.domainAccountInfo.domain_, report.domainAccountInfo.accountName_);
std::vector<sptr<IRemoteObject>> listeners;
std::lock_guard<std::mutex> lock(mutex_);
for (auto record : listenerAll_) {
auto callback = iface_cast<IDomainAccountCallback>(record);
if (callback == nullptr) {
ACCOUNT_LOGE("callback is nullptr!");
continue;
}
Parcel parcel;
DomainAccountEventParcel(report, parcel);
callback->OnResult(ERR_OK, parcel);
ACCOUNT_LOGI("The callback execution is complete");
}
auto domainSet = accountToListener_.find(domainAccountStr);
if (domainSet == accountToListener_.end()) {
ACCOUNT_LOGI("not exist listenter");
return;
}
ACCOUNT_LOGE("callback is null.");
return;
for (auto listener : domainSet->second) {
auto callback = iface_cast<IDomainAccountCallback>(listener);
if (callback == nullptr) {
ACCOUNT_LOGE("callback is nullptr!");
continue;
}
Parcel parcel;
DomainAccountEventParcel(report, parcel);
callback->OnResult(ERR_OK, parcel);
}
}
} // namespace AccountSA
} // namespace OHOS

View File

@ -362,8 +362,10 @@ ErrCode IInnerOsAccountManager::RemoveOsAccountOperate(const int id, OsAccountIn
return errCode;
}
CheckAndRefreshLocalIdRecord(id);
InnerDomainAccountManager::GetInstance().NotifyDomainAccountEvent(
id, DomainAccountEvent::LOG_OUT, DomainAccountStatus::LOGOUT, domainAccountInfo);
if (!domainAccountInfo.accountId_.empty()) {
InnerDomainAccountManager::GetInstance().NotifyDomainAccountEvent(
id, DomainAccountEvent::LOG_OUT, DomainAccountStatus::LOGOUT, domainAccountInfo);
}
return errCode;
}
@ -814,14 +816,12 @@ void IInnerOsAccountManager::CleanGarbageAccounts()
ErrCode IInnerOsAccountManager::GetOsAccountLocalIdFromDomain(const DomainAccountInfo &domainInfo, int &id)
{
if (domainInfo.domain_.empty() ||
domainInfo.domain_.size() > Constants::DOMAIN_NAME_MAX_SIZE) {
if (domainInfo.domain_.size() > Constants::DOMAIN_NAME_MAX_SIZE) {
ACCOUNT_LOGE("invalid domain name length %{public}zu.", domainInfo.domain_.size());
return ERR_OSACCOUNT_SERVICE_INNER_DOMAIN_NAME_LEN_ERROR;
}
if (domainInfo.accountName_.empty() ||
domainInfo.accountName_.size() > Constants::DOMAIN_ACCOUNT_NAME_MAX_SIZE) {
if (domainInfo.accountName_.size() > Constants::DOMAIN_ACCOUNT_NAME_MAX_SIZE) {
ACCOUNT_LOGE("invalid domain account name length %{public}zu.", domainInfo.accountName_.size());
return ERR_OSACCOUNT_SERVICE_INNER_DOMAIN_ACCOUNT_NAME_LEN_ERROR;
}
@ -838,8 +838,8 @@ ErrCode IInnerOsAccountManager::GetOsAccountLocalIdFromDomain(const DomainAccoun
++osAccountInfosPtr) {
osAccountInfosPtr->GetDomainInfo(curDomainInfo);
if (((!domainInfo.accountId_.empty()) && (domainInfo.accountId_ == curDomainInfo.accountId_)) ||
((curDomainInfo.accountName_ == domainInfo.accountName_) &&
(curDomainInfo.domain_ == domainInfo.domain_))) {
((!domainInfo.accountName_.empty()) && (curDomainInfo.accountName_ == domainInfo.accountName_) &&
(!domainInfo.domain_.empty()) && (curDomainInfo.domain_ == domainInfo.domain_))) {
id = osAccountInfosPtr->GetLocalId();
return ERR_OK;
}