* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ctime>
#include <utility>
#include <type_traits>
#include "system_event_wrapper.h"
#include "bundle_constants.h"
#include "common_event_manager.h"
#include "common_event_subscriber.h"
#include "common_event_support.h"
#include "net_supplier_info.h"
#include "asset_log.h"
namespace {
using namespace OHOS::AppExecFwk::Constants;
using namespace OHOS::EventFwk;
const char * const APP_ID = "appId";
const char * const APP_INDEX = "appIndex";
const char * const COMMON_EVENT_USER_PIN_CREATED = "USER_PIN_CREATED_EVENT";
const char * const BUNDLE_NAME = "bundleName";
const char * const PERMISSION_MANAGE_USER_IDM = "ohos.permission.MANAGE_USER_IDM";
const char * const DEVELOPER_ID = "developerId";
const char * const GROUP_IDS = "assetAccessGroups";
const char * const OWNER_INFO_SEPARATOR = "_";
const char * const GROUP_SEPARATOR = ",";
void ParseGroupIds(const std::string &groupIds, std::vector<std::string> &groupIdStrs,
std::vector<ConstAssetBlob> &groupIdBlobs, ConstAssetBlobArray &groupIdBlobArray)
{
if (!groupIds.empty()) {
size_t start = 0;
size_t end;
while ((end = groupIds.find(GROUP_SEPARATOR, start)) != std::string::npos) {
groupIdStrs.push_back(groupIds.substr(start, end - start));
start = ++end;
}
groupIdStrs.push_back(groupIds.substr(start, end));
for (const std::string &groupIdStr : groupIdStrs) {
groupIdBlobs.push_back({ .size = groupIdStr.size(),
.data = reinterpret_cast<const uint8_t *>(groupIdStr.c_str()) });
}
groupIdBlobArray = { .size = groupIdBlobs.size(),
.blob = reinterpret_cast<const ConstAssetBlob *>(&groupIdBlobs[0]) };
} else {
groupIdBlobArray = { .size = 0, .blob = nullptr };
}
}
void HandlePackageRemoved(const OHOS::AAFwk::Want &want, bool isSandBoxApp, OnPackageRemoved onPackageRemoved)
{
int userId = want.GetIntParam(USER_ID, INVALID_USERID);
std::string appId = want.GetStringParam(APP_ID);
int appIndex = isSandBoxApp ? want.GetIntParam(SANDBOX_APP_INDEX, -1) : want.GetIntParam(APP_INDEX, -1);
if (appId.empty() || userId == INVALID_USERID || appIndex == -1) {
LOGE("[FATAL]Get removed owner info failed, userId=%{public}d, appId=%{public}s, appIndex=%{public}d",
userId, appId.c_str(), appIndex);
return;
}
std::string owner = appId + OWNER_INFO_SEPARATOR + std::to_string(appIndex);
ConstAssetBlob ownerBlob = { .size = owner.size(), .data = reinterpret_cast<const uint8_t *>(owner.c_str()) };
std::string bundleName = want.GetBundle();
ConstAssetBlob bundleNameBlob = { .size = bundleName.size(),
.data = reinterpret_cast<const uint8_t *>(bundleName.c_str()) };
std::string developerId = want.GetStringParam(DEVELOPER_ID);
ConstAssetBlob developerIdBlob = {
.size = developerId.size(), .data = reinterpret_cast<const uint8_t *>(developerId.c_str())
};
std::string groupIds = want.GetStringParam(GROUP_IDS);
std::vector<ConstAssetBlob> groupIdBlobs;
std::vector<std::string> groupIdStrs;
ConstAssetBlobArray groupIdBlobArray;
ParseGroupIds(groupIds, groupIdStrs, groupIdBlobs, groupIdBlobArray);
if (onPackageRemoved != nullptr) {
onPackageRemoved({ userId, appIndex, ownerBlob, developerIdBlob, groupIdBlobArray, bundleNameBlob });
}
LOGI("Receive event: PACKAGE_REMOVED, userId=%{public}d, appId=%{public}s, appIndex=%{public}d", userId,
appId.c_str(), appIndex);
}
void HandleAppRestore(const OHOS::AAFwk::Want &want, OnAppRestore onAppRestore)
{
if (onAppRestore != nullptr) {
int userId = want.GetIntParam(USER_ID, INVALID_USERID);
std::string bundleName = want.GetStringParam(BUNDLE_NAME);
int appIndex = want.GetIntParam(SANDBOX_APP_INDEX, -1);
if (appIndex == -1) {
LOGI("Get app restore info failed, default as index 0.");
appIndex = 0;
}
onAppRestore(userId, reinterpret_cast<const uint8_t *>(bundleName.c_str()), appIndex);
LOGI("Receive event: RESTORE_START.");
}
}
void HandleConnectivityChange(int code, OnConnectivityChange onConnectivityChange)
{
if (onConnectivityChange != nullptr) {
if (code != static_cast<int>(OHOS::NetManagerStandard::NetConnState::NET_CONN_STATE_CONNECTED)) {
return;
}
long startTime = std::clock();
onConnectivityChange();
LOGI("Receive event: CONNECTIVITY_CHANGE, start_time: %{public}ld", startTime);
}
}
template<typename CallbackType, typename... Args>
void HandleCallback(CallbackType callback, Args&&... args)
{
if (callback != nullptr) {
callback(std::forward<Args>(args)...);
}
}
class SystemEventHandler : public CommonEventSubscriber {
public:
explicit SystemEventHandler(const CommonEventSubscribeInfo &subscribeInfo, const EventCallBack eventCallBack)
: CommonEventSubscriber(subscribeInfo), eventCallBack(eventCallBack) {}
~SystemEventHandler() = default;
void OnReceiveEvent(const CommonEventData &data) override
{
long startTime = std::clock();
auto want = data.GetWant();
std::string action = want.GetAction();
if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
HandlePackageRemoved(want, false, this->eventCallBack.onPackageRemoved);
} else if (action == CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) {
HandlePackageRemoved(want, true, this->eventCallBack.onPackageRemoved);
} else if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) {
int userId = data.GetCode();
HandleCallback(this->eventCallBack.onUserRemoved, userId);
LOGI(" Receive event: USER_REMOVED, userId=%{public}d", userId);
} else if (action == CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
HandleCallback(this->eventCallBack.onScreenOff);
LOGI("Receive event: SCREEN_OFF, start_time: %{public}ld", startTime);
} else if (action == CommonEventSupport::COMMON_EVENT_CHARGING) {
HandleCallback(this->eventCallBack.onCharging);
LOGI("Receive event: CHARGING, start_time: %{public}ld", startTime);
} else if (action == CommonEventSupport::COMMON_EVENT_RESTORE_START) {
HandleAppRestore(want, this->eventCallBack.onAppRestore);
} else if (action == CommonEventSupport::COMMON_EVENT_USER_UNLOCKED) {
int userId = data.GetCode();
HandleCallback(this->eventCallBack.onUserUnlocked, userId);
LOGI("Receive event: USER_UNLOCKED, start_time: %{public}ld", startTime);
} else if (action == COMMON_EVENT_USER_PIN_CREATED) {
int userId = data.GetCode();
HandleCallback(this->eventCallBack.onUserUnlocked, userId);
LOGI("Receive event: USER_PIN_CREATED_EVENT, start_time: %{public}ld", startTime);
} else if (action == CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE) {
HandleConnectivityChange(data.GetCode(), this->eventCallBack.onConnectivityChange);
} else if (action == CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY) {
HandleCallback(this->eventCallBack.onDataShareReady);
LOGI("Receive event: COMMON_EVENT_DATA_SHARE_READY, start_time: %{public}ld", startTime);
} else if (action == CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
int userId = data.GetCode();
HandleCallback(this->eventCallBack.onUserSwitched, userId);
LOGI("Receive event: COMMON_EVENT_USER_SWITCHED, start_time: %{public}ld", startTime);
} else {
LOGW("[WARNING]Receive unknown event: %{public}s", action.c_str());
}
}
private:
const EventCallBack eventCallBack;
};
std::shared_ptr<SystemEventHandler> g_eventHandler = nullptr;
std::shared_ptr<SystemEventHandler> g_pinEventHandler = nullptr;
bool SubscribePinEvent(const EventCallBack eventCallBack)
{
MatchingSkills matchingSkills;
matchingSkills.AddEvent(COMMON_EVENT_USER_PIN_CREATED);
CommonEventSubscribeInfo info(matchingSkills);
info.SetPermission(PERMISSION_MANAGE_USER_IDM);
if (g_pinEventHandler == nullptr) {
g_pinEventHandler = std::shared_ptr<SystemEventHandler>(
new (std::nothrow) SystemEventHandler(info, eventCallBack));
if (g_pinEventHandler == nullptr) {
LOGE("[FATAL]Asset pin event handler is nullptr.");
return false;
}
}
return CommonEventManager::SubscribeCommonEvent(g_pinEventHandler);
}
bool UnSubscribePinEvent(void)
{
if (g_pinEventHandler == nullptr) {
LOGW("Asset pin event handler is nullptr, no need to unsubscribe.");
return false;
}
bool res = CommonEventManager::UnSubscribeCommonEvent(g_pinEventHandler);
g_pinEventHandler = nullptr;
return res;
}
}
bool SubscribeSystemEvent(const EventCallBack eventCallBack)
{
bool ret = SubscribePinEvent(eventCallBack);
LOGI("Subscribe pin event res: %{public}d", ret);
MatchingSkills matchingSkills;
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_CHARGING);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_RESTORE_START);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
CommonEventSubscribeInfo info(matchingSkills);
if (g_eventHandler == nullptr) {
g_eventHandler = std::shared_ptr<SystemEventHandler>(
new (std::nothrow) SystemEventHandler(info, eventCallBack));
if (g_eventHandler == nullptr) {
LOGE("[FATAL]Asset system event handler is nullptr.");
return false;
}
}
return CommonEventManager::SubscribeCommonEvent(g_eventHandler);
}
bool UnSubscribeSystemEvent(void)
{
bool ret = UnSubscribePinEvent();
LOGI("UnSubscribe pin event res: %{public}d", ret);
if (g_eventHandler == nullptr) {
LOGW("Asset system event handler is nullptr, no need to unsubscribe.");
return false;
}
bool res = CommonEventManager::UnSubscribeCommonEvent(g_eventHandler);
g_eventHandler = nullptr;
return res;
}