Update framework struct and add new function

Signed-off-by: chensi10 <chen.s@neusoft.com>
This commit is contained in:
chensi10 2021-07-15 10:58:26 +08:00
parent d7757e057f
commit 54504c4c0e
455 changed files with 83872 additions and 27642 deletions

View File

@ -13,8 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
Notes:
This is project config file for OpenHarmony OSS Audit Tool, if you have any questions or concerns, please email chenyaxun@huawei.com.
-->
<!-- OAT(OSS Audit Tool) configuration guide:
basedir: Root dir, the basedir + project path is the real source file location.

View File

@ -25,3 +25,4 @@ tools_path = "${appexecfwk_path}/tools"
test_hap_common_path = "${appexecfwk_path}/test/common"
system_test_app_path =
"${appexecfwk_path}/test/resource/amssystemtestability/abilitySrc"
dispatcher_path = "${appexecfwk_path}/interfaces/innerkits/task_dispatcher"

View File

@ -20,5 +20,6 @@ group("innerkits_target") {
"appexecfwk_core:appexecfwk_core",
"eventhandler_native:eventhandler_native",
"libeventhandler:libeventhandler",
"task_dispatcher:appkit_dispatcher_td",
]
}

View File

@ -24,10 +24,10 @@ ohos_shared_library("appexecfwk_base") {
sources = [
"src/ability_info.cpp",
"src/app_process_info.cpp",
"src/application_info.cpp",
"src/bundle_info.cpp",
"src/element_name.cpp",
"src/form_info.cpp",
"src/hap_module_info.cpp",
"src/install_param.cpp",
"src/module_info.cpp",

View File

@ -22,7 +22,6 @@ appexecfwk_base_headers = {
"install_param.h",
"module_info.h",
"permission_def.h",
"app_process_info.h",
"running_process_info.h",
]

View File

@ -40,8 +40,16 @@ enum class DisplayOrientation {
enum class LaunchMode {
SINGLETON = 0,
SINGLETOP,
STANDARD, // support more than one instance
SINGLETOP,
};
struct Form {
std::vector<std::string> formEntity;
int32_t minHeight = 0;
int32_t defaultHeight = 0;
int32_t minWidth = 0;
int32_t defaultWidth = 0;
};
// configuration information about an ability
@ -50,6 +58,7 @@ struct AbilityInfo : public Parcelable {
std::string label;
std::string description;
std::string iconPath;
std::string theme;
bool visible = false;
std::string kind; // ability category
AbilityType type = AbilityType::UNKNOWN;
@ -61,9 +70,14 @@ struct AbilityInfo : public Parcelable {
std::vector<std::string> deviceTypes;
std::vector<std::string> deviceCapabilities;
std::string uri;
std::string targetAbility;
ApplicationInfo applicationInfo;
bool isLauncherAbility = false;
bool isNativeAbility = false;
bool enabled = false;
std::string readPermission;
std::string writePermission;
Form form;
// set when install
std::string package; // the "module.package" in config.json

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_APP_PROCESS_INFO_H
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_APP_PROCESS_INFO_H
#include <string>
#include "parcel.h"
namespace OHOS {
namespace AppExecFwk {
enum class AppProcessState {
APP_STATE_BEGIN = 0,
APP_STATE_CREATE = APP_STATE_BEGIN,
APP_STATE_READY,
APP_STATE_FOREGROUND,
APP_STATE_BACKGROUND,
APP_STATE_SUSPENDED,
APP_STATE_TERMINATED,
APP_STATE_END,
};
enum class WeightReasonCode {
REASON_UNKNOWN = 0,
WEIGHT_FOREGROUND = 100,
WEIGHT_FOREGROUND_SERVICE = 125,
WEIGHT_VISIBLE = 200,
WEIGHT_PERCEPTIBLE = 230,
WEIGHT_SERVICE = 300,
WEIGHT_TOP_SLEEPING = 325,
WEIGHT_CANT_SAVE_STATE = 350,
WEIGHT_CACHED = 400,
WEIGHT_GONE = 1000,
};
struct AppProcessInfo : public Parcelable {
std::string processName_;
std::int32_t pid_;
std::int32_t uid_;
AppProcessState state_;
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
static AppProcessInfo *Unmarshalling(Parcel &parcel);
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_APP_PROCESS_INFO_H

View File

@ -24,6 +24,7 @@ enum {
APPEXECFWK_MODULE_COMMON = 0x00,
APPEXECFWK_MODULE_APPMGR = 0x01,
APPEXECFWK_MODULE_BUNDLEMGR = 0x02,
APPEXECFWK_MODULE_APPEXECFWK = 0x08,
// Reserved 0x03 ~ 0x0f for new modules, Event related modules start from 0x10
APPEXECFWK_MODULE_EVENTMGR = 0x10
};
@ -67,6 +68,7 @@ enum {
ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID,
ERR_APPEXECFWK_INSTALL_INVALID_HAP_NAME,
ERR_APPEXECFWK_INSTALL_INVALID_BUNDLE_FILE,
ERR_APPEXECFWK_INSTALL_INVALID_HAP_SIZE,
ERR_APPEXECFWK_INSTALL_GENERATE_UID_ERROR,
ERR_APPEXECFWK_INSTALL_INSTALLD_SERVICE_ERROR,
ERR_APPEXECFWK_INSTALL_BUNDLE_MGR_SERVICE_ERROR,
@ -80,6 +82,7 @@ enum {
ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR,
ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP,
ERR_APPEXECFWK_PARSE_PERMISSION_ERROR,
ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR,
ERR_APPEXECFWK_INSTALLD_PARAM_ERROR,
ERR_APPEXECFWK_INSTALLD_GET_PROXY_ERROR,
@ -100,6 +103,11 @@ enum {
ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE,
ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_MODULE
};
constexpr ErrCode APPEXECFWK_APPEXECFWK_ERR_OFFSET = ErrCodeOffset(SUBSYS_APPEXECFWK, APPEXECFWK_MODULE_APPEXECFWK);
enum {
ERR_APPEXECFWK_CHECK_FAILED = APPEXECFWK_APPEXECFWK_ERR_OFFSET + 1,
ERR_APPEXECFWK_INTERCEPT_TASK_EXECUTE_SUCCESS
};
} // namespace OHOS

View File

@ -57,6 +57,8 @@ struct ApplicationInfo : public Parcelable {
std::string dataDir;
std::string dataBaseDir;
std::string cacheDir;
int flags = 0;
bool enabled = false;
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;

View File

@ -92,7 +92,7 @@ enum class AppType {
const std::string INTENT_ACTION_HOME = "action.system.home";
const std::string INTENT_ENTITY_HOME = "entity.system.home";
const std::string FLAG_HW_HOME_INTENT_FROM_SYSTEM = "flag.home.intent.from.system";
const std::string FLAG_HOME_INTENT_FROM_SYSTEM = "flag.home.intent.from.system";
// the ability file folder name.
const std::string LIB_FOLDER_NAME = "libs";
@ -109,6 +109,12 @@ constexpr uint8_t MAX_MODULE_ABILITIES_READPERMISSION = 255;
constexpr uint8_t MAX_MODULE_ABILITIES_WRITEPERMISSION = 255;
constexpr uint8_t MAX_MODULE_SHORTCUTID = 63;
constexpr uint8_t MAX_MODULE_LABEL = 63;
// distributed database
const std::string APP_ID = "bundle_manager_service";
const std::string STORE_ID = "installed_bundle_datas";
// single max hap size
constexpr int32_t MAX_HAP_SIZE = 50 * 1024 * 1024;
} // namespace Constants
} // namespace AppExecFwk

View File

@ -57,6 +57,7 @@ struct BundleInfo : public Parcelable {
std::string entryModuleName;
bool isKeepAlive = false;
bool isNativeApp = false;
bool isDifferentName = false;
int64_t installTime = 0; // the installation time is the number of seconds elapsed since January 1,
// 1970 00:00:00 UTC. The time will be recalculated if the application is reinstalled
// after being uninstalled.

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_FORM_INFO_H
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_FORM_INFO_H
#include <string>
#include "parcel.h"
namespace OHOS {
namespace AppExecFwk {
enum class FormsColorMode {
AUTO_MODE = -1,
DARK_MODE = 0,
LIGHT_MODE = 1,
};
enum class FormType {
JAVA = 0,
JS = 1,
};
struct CustomizeData {
std::string name;
std::string value;
};
struct FormInfo : public Parcelable {
std::string package;
std::string bundleName;
std::string originalBundleName;
std::string relatedBundleName;
std::string moduleName; // the "module.distro.moduleName" in config.json
std::string abilityName;
std::string name;
std::string description;
std::string jsComponentName;
std::string deepLink;
std::string formConfigAbility;
std::string scheduledUpateTime = "0:0";
int32_t descriptionId = 0;
int32_t updateDuration = 0;
int32_t defaultDimension = 0;
bool defaultFlag = false;
bool formVisibleNotify = false;
bool updateEnabled = false;
FormType type = FormType::JS;
std::vector<int32_t> supportDimensions;
FormsColorMode colorMode = FormsColorMode::AUTO_MODE;
std::vector<std::string> landscapeLayouts;
std::vector<std::string> portraitLayouts;
std::vector<CustomizeData> customizeDatas;
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
static FormInfo *Unmarshalling(Parcel &parcel);
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_FORM_H

View File

@ -24,6 +24,12 @@
namespace OHOS {
namespace AppExecFwk {
enum class ModuleColorMode{
AUTO = -1,
DARK,
LIGHT,
};
// configuration information about an module
struct HapModuleInfo : public Parcelable {
std::string name; // module.package in config.json
@ -37,6 +43,7 @@ struct HapModuleInfo : public Parcelable {
std::vector<std::string> reqCapabilities;
std::vector<std::string> deviceTypes;
std::vector<AbilityInfo> abilityInfos;
ModuleColorMode colorMode = ModuleColorMode::AUTO;
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;

View File

@ -18,6 +18,7 @@
#include "nlohmann/json.hpp"
#include "bundle_info.h"
#include "form_info.h"
namespace OHOS {
namespace AppExecFwk {
@ -28,12 +29,18 @@ namespace AppExecFwk {
*/
void to_json(nlohmann::json &jsonObject, const AbilityInfo &abilityInfo);
void from_json(const nlohmann::json &jsonObject, AbilityInfo &abilityInfo);
void to_json(nlohmann::json &jsonObject, const Form &form);
void from_json(const nlohmann::json &jsonObject, Form &form);
void to_json(nlohmann::json &jsonObject, const ApplicationInfo &applicationInfo);
void from_json(const nlohmann::json &jsonObject, ApplicationInfo &applicationInfo);
void to_json(nlohmann::json &jsonObject, const BundleInfo &bundleInfo);
void from_json(const nlohmann::json &jsonObject, BundleInfo &bundleInfo);
void to_json(nlohmann::json &jsonObject, const ModuleInfo &moduleInfo);
void from_json(const nlohmann::json &jsonObject, ModuleInfo &moduleInfo);
void to_json(nlohmann::json &jsonObject, const CustomizeData &customizeDatas);
void from_json(const nlohmann::json &jsonObject, CustomizeData &customizeDatas);
void to_json(nlohmann::json &jsonObject, const FormInfo &formInfo);
void from_json(const nlohmann::json &jsonObject, FormInfo &formInfo);
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -20,14 +20,40 @@
#include <vector>
#include "parcel.h"
#include "app_process_info.h"
namespace OHOS {
namespace AppExecFwk {
enum class AppProcessState {
APP_STATE_BEGIN = 0,
APP_STATE_CREATE = APP_STATE_BEGIN,
APP_STATE_READY,
APP_STATE_FOREGROUND,
APP_STATE_BACKGROUND,
APP_STATE_SUSPENDED,
APP_STATE_TERMINATED,
APP_STATE_END,
};
enum class WeightReasonCode {
REASON_UNKNOWN = 0,
WEIGHT_FOREGROUND = 100,
WEIGHT_FOREGROUND_SERVICE = 125,
WEIGHT_VISIBLE = 200,
WEIGHT_PERCEPTIBLE = 230,
WEIGHT_SERVICE = 300,
WEIGHT_TOP_SLEEPING = 325,
WEIGHT_CANT_SAVE_STATE = 350,
WEIGHT_CACHED = 400,
WEIGHT_GONE = 1000,
};
struct RunningProcessInfo : public Parcelable {
std::vector<AppProcessInfo> appProcessInfos;
std::string processName_;
std::int32_t pid_;
std::int32_t uid_;
AppProcessState state_;
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
@ -37,4 +63,4 @@ struct RunningProcessInfo : public Parcelable {
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_RUNNING_PROCESS_INFO_H
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_RUNNING_PROCESS_INFO_H

View File

@ -39,6 +39,7 @@ const std::string JSON_KEY_APPLICATION_NAME = "applicationName";
const std::string JSON_KEY_LABEL = "label";
const std::string JSON_KEY_DESCRIPTION = "description";
const std::string JSON_KEY_ICON_PATH = "iconPath";
const std::string JSON_KEY_THEME = "theme";
const std::string JSON_KEY_VISIBLE = "visible";
const std::string JSON_KEY_KIND = "kind";
const std::string JSON_KEY_TYPE = "type";
@ -56,6 +57,16 @@ const std::string JSON_KEY_MODULE_NAME = "moduleName";
const std::string JSON_KEY_DEVICE_ID = "deviceId";
const std::string JSON_KEY_IS_LAUNCHER_ABILITY = "isLauncherAbility";
const std::string JSON_KEY_IS_NATIVE_ABILITY = "isNativeAbility";
const std::string JSON_KEY_ENABLED = "enabled";
const std::string JSON_KEY_TARGET_ABILITY = "targetAbility";
const std::string JSON_KEY_READ_PERMISSION = "readPermission";
const std::string JSON_KEY_WRITE_PERMISSION = "writePermission";
const std::string JSON_KEY_FORM = "form";
const std::string JSON_KEY_FORM_ENTITY = "formEntity";
const std::string JSON_KEY_FORM_MIN_HEIGHT = "minHeight";
const std::string JSON_KEY_FORM_DEFAULT_HEIGHT = "defaultHeight";
const std::string JSON_KEY_FORM_MIN_WIDTH = "minWidth";
const std::string JSON_KEY_FORM_DEFAULT_WIDTH = "defaultWidth";
} // namespace
@ -65,6 +76,7 @@ bool AbilityInfo::ReadFromParcel(Parcel &parcel)
label = Str16ToStr8(parcel.ReadString16());
description = Str16ToStr8(parcel.ReadString16());
iconPath = Str16ToStr8(parcel.ReadString16());
theme = Str16ToStr8(parcel.ReadString16());
kind = Str16ToStr8(parcel.ReadString16());
uri = Str16ToStr8(parcel.ReadString16());
package = Str16ToStr8(parcel.ReadString16());
@ -76,9 +88,23 @@ bool AbilityInfo::ReadFromParcel(Parcel &parcel)
codePath = Str16ToStr8(parcel.ReadString16());
resourcePath = Str16ToStr8(parcel.ReadString16());
libPath = Str16ToStr8(parcel.ReadString16());
targetAbility = Str16ToStr8(parcel.ReadString16());
readPermission = Str16ToStr8(parcel.ReadString16());
writePermission = Str16ToStr8(parcel.ReadString16());
visible = parcel.ReadBool();
isLauncherAbility = parcel.ReadBool();
isNativeAbility = parcel.ReadBool();
enabled = parcel.ReadBool();
int32_t formEntitySize;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, formEntitySize);
for (int32_t i = 0; i < formEntitySize; i++) {
form.formEntity.emplace_back(Str16ToStr8(parcel.ReadString16()));
}
form.minHeight = parcel.ReadInt32();
form.defaultHeight = parcel.ReadInt32();
form.minWidth = parcel.ReadInt32();
form.defaultWidth = parcel.ReadInt32();
int32_t typeData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, typeData);
@ -136,6 +162,7 @@ bool AbilityInfo::Marshalling(Parcel &parcel) const
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(label));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(description));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(iconPath));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(theme));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(kind));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(package));
@ -147,9 +174,21 @@ bool AbilityInfo::Marshalling(Parcel &parcel) const
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(codePath));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(resourcePath));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(libPath));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(targetAbility));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(readPermission));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(writePermission));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, visible);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isLauncherAbility);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isNativeAbility);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, enabled);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, form.formEntity.size());
for (auto &item : form.formEntity) {
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(item));
}
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, form.minHeight);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, form.defaultHeight);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, form.minWidth);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, form.defaultWidth);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(type));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(orientation));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(launchMode));
@ -199,45 +238,70 @@ void AbilityInfo::Dump(std::string prefix, int fd)
return;
}
void to_json(nlohmann::json &jsonObject, const Form &form)
{
jsonObject = nlohmann::json{{JSON_KEY_FORM_ENTITY, form.formEntity},
{JSON_KEY_FORM_MIN_HEIGHT, form.minHeight},
{JSON_KEY_FORM_DEFAULT_HEIGHT, form.defaultHeight},
{JSON_KEY_FORM_MIN_WIDTH, form.minWidth},
{JSON_KEY_FORM_DEFAULT_WIDTH, form.defaultWidth}};
}
void to_json(nlohmann::json &jsonObject, const AbilityInfo &abilityInfo)
{
jsonObject = nlohmann::json{
{"name", abilityInfo.name},
{"label", abilityInfo.label},
{"description", abilityInfo.description},
{"iconPath", abilityInfo.iconPath},
{"visible", abilityInfo.visible},
{"isLauncherAbility", abilityInfo.isLauncherAbility},
{"isNativeAbility", abilityInfo.isNativeAbility},
{"kind", abilityInfo.kind},
{"type", abilityInfo.type},
{"orientation", abilityInfo.orientation},
{"launchMode", abilityInfo.launchMode},
{"permissions", abilityInfo.permissions},
{"process", abilityInfo.process},
{"deviceTypes", abilityInfo.deviceTypes},
{"deviceCapabilities", abilityInfo.deviceCapabilities},
{"uri", abilityInfo.uri},
{"package", abilityInfo.package},
{"bundleName", abilityInfo.bundleName},
{"moduleName", abilityInfo.moduleName},
{"applicationName", abilityInfo.applicationName},
{"deviceId", abilityInfo.deviceId},
{"codePath", abilityInfo.codePath},
{"resourcePath", abilityInfo.resourcePath},
{"libPath", abilityInfo.libPath}
};
jsonObject = nlohmann::json{{JSON_KEY_NAME, abilityInfo.name},
{JSON_KEY_LABEL, abilityInfo.label},
{JSON_KEY_DESCRIPTION, abilityInfo.description},
{JSON_KEY_ICON_PATH, abilityInfo.iconPath},
{JSON_KEY_THEME, abilityInfo.theme},
{JSON_KEY_VISIBLE, abilityInfo.visible},
{JSON_KEY_IS_LAUNCHER_ABILITY, abilityInfo.isLauncherAbility},
{JSON_KEY_IS_NATIVE_ABILITY, abilityInfo.isNativeAbility},
{JSON_KEY_ENABLED, abilityInfo.enabled},
{JSON_KEY_READ_PERMISSION, abilityInfo.readPermission},
{JSON_KEY_WRITE_PERMISSION, abilityInfo.writePermission},
{JSON_KEY_FORM, abilityInfo.form},
{JSON_KEY_KIND, abilityInfo.kind},
{JSON_KEY_TYPE, abilityInfo.type},
{JSON_KEY_ORIENTATION, abilityInfo.orientation},
{JSON_KEY_LAUNCH_MODE, abilityInfo.launchMode},
{JSON_KEY_PERMISSIONS, abilityInfo.permissions},
{JSON_KEY_PROCESS, abilityInfo.process},
{JSON_KEY_DEVICE_TYPES, abilityInfo.deviceTypes},
{JSON_KEY_DEVICE_CAPABILITIES, abilityInfo.deviceCapabilities},
{JSON_KEY_URI, abilityInfo.uri},
{JSON_KEY_TARGET_ABILITY, abilityInfo.targetAbility},
{JSON_KEY_PACKAGE, abilityInfo.package},
{JSON_KEY_BUNDLE_NAME, abilityInfo.bundleName},
{JSON_KEY_MODULE_NAME, abilityInfo.moduleName},
{JSON_KEY_APPLICATION_NAME, abilityInfo.applicationName},
{JSON_KEY_DEVICE_ID, abilityInfo.deviceId},
{JSON_KEY_CODE_PATH, abilityInfo.codePath},
{JSON_KEY_RESOURCE_PATH, abilityInfo.resourcePath},
{JSON_KEY_LIB_PATH, abilityInfo.libPath}};
}
void from_json(const nlohmann::json &jsonObject, Form &form)
{
form.formEntity = jsonObject.at(JSON_KEY_FORM_ENTITY).get<std::vector<std::string>>();
form.minHeight = jsonObject.at(JSON_KEY_FORM_MIN_HEIGHT).get<int32_t>();
form.defaultHeight = jsonObject.at(JSON_KEY_FORM_DEFAULT_HEIGHT).get<int32_t>();
form.minWidth = jsonObject.at(JSON_KEY_FORM_MIN_WIDTH).get<int32_t>();
form.defaultWidth = jsonObject.at(JSON_KEY_FORM_DEFAULT_WIDTH).get<int32_t>();
}
void from_json(const nlohmann::json &jsonObject, AbilityInfo &abilityInfo)
{
abilityInfo.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
abilityInfo.label = jsonObject.at(JSON_KEY_LABEL).get<std::string>();
abilityInfo.description = jsonObject.at(JSON_KEY_DESCRIPTION).get<std::string>();
abilityInfo.iconPath = jsonObject.at(JSON_KEY_ICON_PATH).get<std::string>();
abilityInfo.theme = jsonObject.at(JSON_KEY_THEME).get<std::string>();
abilityInfo.visible = jsonObject.at(JSON_KEY_VISIBLE).get<bool>();
abilityInfo.isLauncherAbility = jsonObject.at(JSON_KEY_IS_LAUNCHER_ABILITY).get<bool>();
abilityInfo.isNativeAbility = jsonObject.at(JSON_KEY_IS_NATIVE_ABILITY).get<bool>();
abilityInfo.enabled = jsonObject.at(JSON_KEY_ENABLED).get<bool>();
abilityInfo.readPermission = jsonObject.at(JSON_KEY_READ_PERMISSION).get<std::string>();
abilityInfo.writePermission = jsonObject.at(JSON_KEY_WRITE_PERMISSION).get<std::string>();
abilityInfo.form = jsonObject.at(JSON_KEY_FORM).get<Form>();
abilityInfo.kind = jsonObject.at(JSON_KEY_KIND).get<std::string>();
abilityInfo.type = jsonObject.at(JSON_KEY_TYPE).get<AbilityType>();
abilityInfo.orientation = jsonObject.at(JSON_KEY_ORIENTATION).get<DisplayOrientation>();
@ -247,6 +311,7 @@ void from_json(const nlohmann::json &jsonObject, AbilityInfo &abilityInfo)
abilityInfo.deviceTypes = jsonObject.at(JSON_KEY_DEVICE_TYPES).get<std::vector<std::string>>();
abilityInfo.deviceCapabilities = jsonObject.at(JSON_KEY_DEVICE_CAPABILITIES).get<std::vector<std::string>>();
abilityInfo.uri = jsonObject.at(JSON_KEY_URI).get<std::string>();
abilityInfo.targetAbility = jsonObject.at(JSON_KEY_TARGET_ABILITY).get<std::string>();
abilityInfo.package = jsonObject.at(JSON_KEY_PACKAGE).get<std::string>();
abilityInfo.bundleName = jsonObject.at(JSON_KEY_BUNDLE_NAME).get<std::string>();
abilityInfo.moduleName = jsonObject.at(JSON_KEY_MODULE_NAME).get<std::string>();

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 2021 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 "app_process_info.h"
#include "nlohmann/json.hpp"
#include "string_ex.h"
#include "app_log_wrapper.h"
#include "parcel_macro.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string JSON_KEY_PROCESSNAME = "processName";
const std::string JSON_KEY_PID = "pid";
const std::string JSON_KEY_STATE = "state";
} // namespace
bool AppProcessInfo::ReadFromParcel(Parcel &parcel)
{
processName_ = Str16ToStr8(parcel.ReadString16());
int32_t typeData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, typeData);
pid_ = static_cast<int32_t>(typeData);
int32_t uidData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uidData);
uid_ = static_cast<int32_t>(uidData);
int32_t stateData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, stateData);
state_ = static_cast<AppProcessState>(stateData);
return true;
}
AppProcessInfo *AppProcessInfo::Unmarshalling(Parcel &parcel)
{
AppProcessInfo *info = new (std::nothrow) AppProcessInfo();
if (info && !info->ReadFromParcel(parcel)) {
APP_LOGW("read from parcel failed");
delete info;
info = nullptr;
}
return info;
}
bool AppProcessInfo::Marshalling(Parcel &parcel) const
{
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(processName_));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(pid_));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(uid_));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(state_));
return true;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -47,10 +47,12 @@ bool ApplicationInfo::ReadFromParcel(Parcel &parcel)
cacheDir = Str16ToStr8(parcel.ReadString16());
isSystemApp = parcel.ReadBool();
isLauncherApp = parcel.ReadBool();
enabled = parcel.ReadBool();
supportedModes = parcel.ReadInt32();
labelId = parcel.ReadInt32();
iconId = parcel.ReadInt32();
descriptionId = parcel.ReadInt32();
flags = parcel.ReadInt32();
int32_t permissionsSize;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissionsSize);
@ -104,10 +106,12 @@ bool ApplicationInfo::Marshalling(Parcel &parcel) const
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(cacheDir));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isSystemApp);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isLauncherApp);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, enabled);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportedModes);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, labelId);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, iconId);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, descriptionId);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, flags);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissions.size());
for (auto &permission : permissions) {
@ -167,6 +171,7 @@ void to_json(nlohmann::json &jsonObject, const ApplicationInfo &applicationInfo)
{"signatureKey", applicationInfo.signatureKey},
{"isSystemApp", applicationInfo.isSystemApp},
{"isLauncherApp", applicationInfo.isLauncherApp},
{"enabled", applicationInfo.enabled},
{"supportedModes", applicationInfo.supportedModes},
{"process", applicationInfo.process},
{"permissions", applicationInfo.permissions},
@ -176,7 +181,8 @@ void to_json(nlohmann::json &jsonObject, const ApplicationInfo &applicationInfo)
{"codePath", applicationInfo.codePath},
{"dataDir", applicationInfo.dataDir},
{"dataBaseDir", applicationInfo.dataBaseDir},
{"cacheDir", applicationInfo.cacheDir}
{"cacheDir", applicationInfo.cacheDir},
{"flags", applicationInfo.flags}
};
}
@ -194,6 +200,7 @@ void from_json(const nlohmann::json &jsonObject, ApplicationInfo &applicationInf
applicationInfo.signatureKey = jsonObject.at("signatureKey").get<std::string>();
applicationInfo.isSystemApp = jsonObject.at("isSystemApp").get<bool>();
applicationInfo.isLauncherApp = jsonObject.at("isLauncherApp").get<bool>();
applicationInfo.enabled = jsonObject.at("enabled").get<bool>();
applicationInfo.supportedModes = jsonObject.at("supportedModes").get<int>();
applicationInfo.process = jsonObject.at("process").get<std::string>();
applicationInfo.permissions = jsonObject.at("permissions").get<std::vector<std::string>>();
@ -204,6 +211,7 @@ void from_json(const nlohmann::json &jsonObject, ApplicationInfo &applicationInf
applicationInfo.dataDir = jsonObject.at("dataDir").get<std::string>();
applicationInfo.dataBaseDir = jsonObject.at("dataBaseDir").get<std::string>();
applicationInfo.cacheDir = jsonObject.at("cacheDir").get<std::string>();
applicationInfo.flags = jsonObject.at("flags").get<int>();
}
} // namespace AppExecFwk

View File

@ -47,6 +47,7 @@ bool BundleInfo::ReadFromParcel(Parcel &parcel)
gid = parcel.ReadInt32();
isKeepAlive = parcel.ReadBool();
isNativeApp = parcel.ReadBool();
isDifferentName = parcel.ReadBool();
installTime = parcel.ReadInt64();
updateTime = parcel.ReadInt64();
@ -134,6 +135,7 @@ bool BundleInfo::Marshalling(Parcel &parcel) const
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, gid);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isKeepAlive);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isNativeApp);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isDifferentName);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int64, parcel, installTime);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int64, parcel, updateTime);
@ -201,6 +203,7 @@ void to_json(nlohmann::json &jsonObject, const BundleInfo &bundleInfo)
{"vendor", bundleInfo.vendor},
{"isKeepAlive", bundleInfo.isKeepAlive},
{"isNativeApp", bundleInfo.isNativeApp},
{"isDifferentName", bundleInfo.isDifferentName},
{"applicationInfo", bundleInfo.applicationInfo},
{"abilityInfos", bundleInfo.abilityInfos},
{"jointUserId", bundleInfo.jointUserId},
@ -238,6 +241,7 @@ void from_json(const nlohmann::json &jsonObject, BundleInfo &bundleInfo)
bundleInfo.vendor = jsonObject.at("vendor").get<std::string>();
bundleInfo.isKeepAlive = jsonObject.at("isKeepAlive").get<bool>();
bundleInfo.isNativeApp = jsonObject.at("isNativeApp").get<bool>();
bundleInfo.isDifferentName = jsonObject.at("isDifferentName").get<bool>();
bundleInfo.applicationInfo = jsonObject.at("applicationInfo").get<ApplicationInfo>();
bundleInfo.abilityInfos = jsonObject.at("abilityInfos").get<std::vector<AbilityInfo>>();
bundleInfo.versionCode = jsonObject.at("versionCode").get<uint32_t>();

View File

@ -0,0 +1,253 @@
/*
* Copyright (c) 2021 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 "form_info.h"
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "json_serializer.h"
#include "nlohmann/json.hpp"
#include "string_ex.h"
#include "parcel_macro.h"
#include "app_log_wrapper.h"
#include "nlohmann/json.hpp"
#include "bundle_constants.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string JSON_KEY_COLOR_MODE = "colorMode";
const std::string JSON_KEY_PACKAGE = "package";
const std::string JSON_KEY_SUPPORT_DIMENSIONS = "supportDimensions";
const std::string JSON_KEY_DEFAULT_DIMENSION = "defaultDimension";
const std::string JSON_KEY_UPDATE_ENABLED = "updateEnabled";
const std::string JSON_KEY_SCHEDULED_UPDATE_TIME = "scheduledUpateTime";
const std::string JSON_KEY_UPDATE_DURATION = "updateDuration";
const std::string JSON_KEY_DEEP_LINK = "deepLink";
const std::string JSON_KEY_JS_COMPONENT_NAME = "jsComponentName";
const std::string JSON_KEY_VALUE = "value";
const std::string JSON_KEY_NAME = "name";
const std::string JSON_KEY_ABILITY_NAME = "abilityName";
const std::string JSON_KEY_BUNDLE_NAME = "bundleName";
const std::string JSON_KEY_MODULE_NAME = "moduleName";
const std::string JSON_KEY_ORIGINAL_BUNDLE_NAME = "originalBundleName";
const std::string JSON_KEY_CUSTOMIZE_DATA = "customizeData";
const std::string JSON_KEY_DESCRIPTION = "description";
const std::string JSON_KEY_DESCRIPTION_ID = "descriptionId";
const std::string JSON_KEY_TYPE = "type";
const std::string JSON_KEY_LANDSCAPE_LAYOUTS = "landscapeLayouts";
const std::string JSON_KEY_FORMCONFIG_ABILITY = "formConfigAbility";
const std::string JSON_KEY_FORM_VISIBLE_NOTIFY = "formVisibleNotify";
const std::string JSON_KEY_RELATED_BUNDLE_NAME = "relatedBundleName";
const std::string JSON_KEY_DEFAULT_FLAG = "defaultFlag";
const std::string JSON_KEY_PORTRAIT_LAYOUTS = "portraitLayouts";
} // namespace
bool FormInfo::ReadFromParcel(Parcel &parcel)
{
name = Str16ToStr8(parcel.ReadString16());
package = Str16ToStr8(parcel.ReadString16());
bundleName = Str16ToStr8(parcel.ReadString16());
moduleName = Str16ToStr8(parcel.ReadString16());
abilityName = Str16ToStr8(parcel.ReadString16());
description = Str16ToStr8(parcel.ReadString16());
formConfigAbility = Str16ToStr8(parcel.ReadString16());
scheduledUpateTime = Str16ToStr8(parcel.ReadString16());
jsComponentName = Str16ToStr8(parcel.ReadString16());
relatedBundleName = Str16ToStr8(parcel.ReadString16());
originalBundleName = Str16ToStr8(parcel.ReadString16());
deepLink = Str16ToStr8(parcel.ReadString16());
updateEnabled = parcel.ReadBool();
defaultFlag = parcel.ReadBool();
formVisibleNotify = parcel.ReadBool();
defaultDimension = parcel.ReadInt32();
descriptionId = parcel.ReadInt32();
updateDuration = parcel.ReadInt32();
int32_t typeData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, typeData);
type = static_cast<FormType>(typeData);
int32_t colorModeData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, colorModeData);
colorMode = static_cast<FormsColorMode>(colorModeData);
int32_t supportDimensionSize;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensionSize);
for (int32_t i = 0; i < supportDimensionSize; i++) {
supportDimensions.emplace_back(parcel.ReadInt32());
}
int32_t landscapeLayoutsSize;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, landscapeLayoutsSize);
for (auto i = 0; i < landscapeLayoutsSize; i++) {
landscapeLayouts.emplace_back(Str16ToStr8(parcel.ReadString16()));
}
int32_t portraitLayoutsSize;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, portraitLayoutsSize);
for (auto i = 0; i < portraitLayoutsSize; i++) {
portraitLayouts.emplace_back(Str16ToStr8(parcel.ReadString16()));
}
int32_t customizeDataSize;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, customizeDataSize);
for (auto i = 0; i < customizeDataSize; i++) {
CustomizeData customizeData;
std::string customizeName = Str16ToStr8(parcel.ReadString16());
std::string customizeValue = Str16ToStr8(parcel.ReadString16());
customizeData.name = customizeName;
customizeData.value = customizeValue;
customizeDatas.emplace_back(customizeData);
}
return true;
}
FormInfo *FormInfo::Unmarshalling(Parcel &parcel)
{
FormInfo *info = new FormInfo();
if (!info->ReadFromParcel(parcel)) {
APP_LOGW("read from parcel failed");
delete info;
info = nullptr;
}
return info;
}
bool FormInfo::Marshalling(Parcel &parcel) const
{
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(name));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(package));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(abilityName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(description));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(formConfigAbility));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(scheduledUpateTime));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(jsComponentName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(relatedBundleName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(originalBundleName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(deepLink));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, updateEnabled);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, defaultFlag);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, formVisibleNotify);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, defaultDimension);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, descriptionId);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, updateDuration);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(type));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(colorMode));
const auto supportDimensionSize = static_cast<int32_t>(supportDimensions.size());
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensionSize);
for (auto i = 0; i < supportDimensionSize; i++) {
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensions[i]);
}
const auto landscapeLayoutsSize = static_cast<int32_t>(landscapeLayouts.size());
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, landscapeLayoutsSize);
for (auto i = 0; i < landscapeLayoutsSize; i++) {
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(landscapeLayouts[i]));
}
const auto portraitLayoutsSize = static_cast<int32_t>(portraitLayouts.size());
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, portraitLayoutsSize);
for (auto i = 0; i < portraitLayoutsSize; i++) {
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(portraitLayouts[i]));
}
const auto customizeDataSize = static_cast<int32_t>(customizeDatas.size());
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, customizeDataSize);
for (auto i = 0; i < customizeDataSize; i++) {
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customizeDatas[i].name));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customizeDatas[i].value));
}
return true;
}
void to_json(nlohmann::json &jsonObject, const CustomizeData &customizeDatas)
{
jsonObject = nlohmann::json{{JSON_KEY_NAME, customizeDatas.name}, {JSON_KEY_VALUE, customizeDatas.value}};
}
void to_json(nlohmann::json &jsonObject, const FormInfo &formInfo)
{
jsonObject = nlohmann::json{{JSON_KEY_NAME, formInfo.name},
{JSON_KEY_PACKAGE, formInfo.package},
{JSON_KEY_BUNDLE_NAME, formInfo.bundleName},
{JSON_KEY_MODULE_NAME, formInfo.moduleName},
{JSON_KEY_ABILITY_NAME, formInfo.abilityName},
{JSON_KEY_DESCRIPTION, formInfo.description},
{JSON_KEY_RELATED_BUNDLE_NAME, formInfo.relatedBundleName},
{JSON_KEY_JS_COMPONENT_NAME, formInfo.jsComponentName},
{JSON_KEY_DEEP_LINK, formInfo.deepLink},
{JSON_KEY_FORMCONFIG_ABILITY, formInfo.formConfigAbility},
{JSON_KEY_SCHEDULED_UPDATE_TIME, formInfo.scheduledUpateTime},
{JSON_KEY_ORIGINAL_BUNDLE_NAME, formInfo.originalBundleName},
{JSON_KEY_DESCRIPTION_ID, formInfo.descriptionId},
{JSON_KEY_UPDATE_DURATION, formInfo.updateDuration},
{JSON_KEY_DEFAULT_DIMENSION, formInfo.defaultDimension},
{JSON_KEY_DEFAULT_FLAG, formInfo.defaultFlag},
{JSON_KEY_FORM_VISIBLE_NOTIFY, formInfo.formVisibleNotify},
{JSON_KEY_UPDATE_ENABLED, formInfo.updateEnabled},
{JSON_KEY_TYPE, formInfo.type},
{JSON_KEY_COLOR_MODE, formInfo.colorMode},
{JSON_KEY_SUPPORT_DIMENSIONS, formInfo.supportDimensions},
{JSON_KEY_CUSTOMIZE_DATA, formInfo.customizeDatas},
{JSON_KEY_LANDSCAPE_LAYOUTS, formInfo.landscapeLayouts},
{JSON_KEY_PORTRAIT_LAYOUTS, formInfo.portraitLayouts}};
}
void from_json(const nlohmann::json &jsonObject, CustomizeData &customizeDatas)
{
customizeDatas.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
customizeDatas.value = jsonObject.at(JSON_KEY_VALUE).get<std::string>();
}
void from_json(const nlohmann::json &jsonObject, FormInfo &formInfo)
{
formInfo.bundleName = jsonObject.at(JSON_KEY_BUNDLE_NAME).get<std::string>();
formInfo.package = jsonObject.at(JSON_KEY_PACKAGE).get<std::string>();
formInfo.moduleName = jsonObject.at(JSON_KEY_MODULE_NAME).get<std::string>();
formInfo.abilityName = jsonObject.at(JSON_KEY_ABILITY_NAME).get<std::string>();
formInfo.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
formInfo.description = jsonObject.at(JSON_KEY_DESCRIPTION).get<std::string>();
formInfo.relatedBundleName = jsonObject.at(JSON_KEY_RELATED_BUNDLE_NAME).get<std::string>();
formInfo.jsComponentName = jsonObject.at(JSON_KEY_JS_COMPONENT_NAME).get<std::string>();
formInfo.deepLink = jsonObject.at(JSON_KEY_DEEP_LINK).get<std::string>();
formInfo.formConfigAbility = jsonObject.at(JSON_KEY_FORMCONFIG_ABILITY).get<std::string>();
formInfo.scheduledUpateTime = jsonObject.at(JSON_KEY_SCHEDULED_UPDATE_TIME).get<std::string>();
formInfo.originalBundleName = jsonObject.at(JSON_KEY_ORIGINAL_BUNDLE_NAME).get<std::string>();
formInfo.descriptionId = jsonObject.at(JSON_KEY_DESCRIPTION_ID).get<int32_t>();
formInfo.updateDuration = jsonObject.at(JSON_KEY_UPDATE_DURATION).get<int32_t>();
formInfo.defaultDimension = jsonObject.at(JSON_KEY_DEFAULT_DIMENSION).get<int32_t>();
formInfo.defaultFlag = jsonObject.at(JSON_KEY_DEFAULT_FLAG).get<bool>();
formInfo.formVisibleNotify = jsonObject.at(JSON_KEY_FORM_VISIBLE_NOTIFY).get<bool>();
formInfo.updateEnabled = jsonObject.at(JSON_KEY_UPDATE_ENABLED).get<bool>();
formInfo.type = jsonObject.at(JSON_KEY_TYPE).get<FormType>();
formInfo.colorMode = jsonObject.at(JSON_KEY_COLOR_MODE).get<FormsColorMode>();
formInfo.supportDimensions = jsonObject.at(JSON_KEY_SUPPORT_DIMENSIONS).get<std::vector<int32_t>>();
formInfo.customizeDatas = jsonObject.at(JSON_KEY_CUSTOMIZE_DATA).get<std::vector<CustomizeData>>();
formInfo.landscapeLayouts = jsonObject.at(JSON_KEY_LANDSCAPE_LAYOUTS).get<std::vector<std::string>>();
formInfo.portraitLayouts = jsonObject.at(JSON_KEY_PORTRAIT_LAYOUTS).get<std::vector<std::string>>();
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -55,6 +55,10 @@ bool HapModuleInfo::ReadFromParcel(Parcel &parcel)
}
abilityInfos.emplace_back(*abilityInfo);
}
int32_t colorModeData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, colorModeData);
colorMode = static_cast<ModuleColorMode>(colorModeData);
return true;
}
@ -90,6 +94,7 @@ bool HapModuleInfo::Marshalling(Parcel &parcel) const
for (auto &abilityInfo : abilityInfos) {
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &abilityInfo);
}
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(colorMode));
return true;
}

View File

@ -24,31 +24,25 @@
namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string JSON_KEY_PROCESSNAME = "processName";
const std::string JSON_KEY_PID = "pid";
const std::string JSON_KEY_STATE = "state";
} // namespace
bool RunningProcessInfo::ReadFromParcel(Parcel &parcel)
{
int32_t processInfoSize = parcel.ReadInt32();
for (int32_t i = 0; i < processInfoSize; i++) {
std::unique_ptr<AppProcessInfo> appProcessInfo(parcel.ReadParcelable<AppProcessInfo>());
if (!appProcessInfo) {
APP_LOGE("ReadParcelable<appProcessInfo> failed");
return false;
}
appProcessInfos.emplace_back(*appProcessInfo);
}
return true;
}
bool RunningProcessInfo::Marshalling(Parcel &parcel) const
{
size_t appProcessInfoSize = appProcessInfos.size();
if (!parcel.WriteInt32(appProcessInfoSize)) {
return false;
}
for (size_t i = 0; i < appProcessInfoSize; i++) {
if (!parcel.WriteParcelable(&appProcessInfos[i])) {
return false;
}
}
processName_ = Str16ToStr8(parcel.ReadString16());
int32_t typeData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, typeData);
pid_ = static_cast<int32_t>(typeData);
int32_t uidData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uidData);
uid_ = static_cast<int32_t>(uidData);
int32_t stateData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, stateData);
state_ = static_cast<AppProcessState>(stateData);
return true;
}
@ -63,5 +57,14 @@ RunningProcessInfo *RunningProcessInfo::Unmarshalling(Parcel &parcel)
return info;
}
bool RunningProcessInfo::Marshalling(Parcel &parcel) const
{
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(processName_));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(pid_));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(uid_));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(state_));
return true;
}
} // namespace AppExecFwk
} // namespace OHOS
} // namespace OHOS

View File

@ -63,6 +63,8 @@ ohos_shared_library("appexecfwk_core") {
"src/bundlemgr/bundle_status_callback_proxy.cpp",
"src/bundlemgr/clean_cache_callback_host.cpp",
"src/bundlemgr/clean_cache_callback_proxy.cpp",
"src/bundlemgr/on_permission_changed_callback_host.cpp",
"src/bundlemgr/on_permission_changed_callback_proxy.cpp",
"src/bundlemgr/status_receiver_host.cpp",
"src/bundlemgr/status_receiver_proxy.cpp",
]

View File

@ -22,6 +22,7 @@ appexecfwk_headers = {
"bundlemgr/bundle_status_callback_interface.h",
"bundlemgr/clean_cache_callback_interface.h",
"bundlemgr/status_receiver_interface.h",
"bundlemgr/on_permission_changed_callback_interface.h",
"appmgr/app_process_data.h",
]

View File

@ -106,6 +106,20 @@ public:
*/
virtual int KillApplication(const std::string &bundleName) = 0;
virtual void AbilityAttachTimeOut(const sptr<IRemoteObject> &token) = 0;
/**
* Checks whether a specified permission has been granted to the process identified by pid and uid
*
* @param permission Indicates the permission to check.
* @param pid Indicates the ID of the process to check.
* @param uid Indicates the UID of the process to check.
* @param message Describe success or failure
*
* @return Returns ERR_OK on success, others on failure.
*/
virtual int CompelVerifyPermission(const std::string &permission, int pid, int uid, std::string &message) = 0;
enum class Message {
AMS_LOAD_ABILITY = 0,
AMS_TERMINATE_ABILITY,
@ -115,6 +129,8 @@ public:
AMS_ABILITY_BEHAVIOR_ANALYSIS,
AMS_KILL_PEOCESS_BY_ABILITY_TOKEN,
AMS_KILL_APPLICATION,
AMS_ABILITY_ATTACH_TIMEOUT,
AMS_COMPEL_VERIFY_PERMISSION,
};
};

View File

@ -103,6 +103,20 @@ public:
*/
virtual int32_t KillApplication(const std::string &bundleName) override;
virtual void AbilityAttachTimeOut(const sptr<IRemoteObject> &token) override;
/**
* Checks whether a specified permission has been granted to the process identified by pid and uid
*
* @param permission Indicates the permission to check.
* @param pid Indicates the ID of the process to check.
* @param uid Indicates the UID of the process to check.
* @param message Describe success or failure
*
* @return Returns ERR_OK on success, others on failure.
*/
virtual int CompelVerifyPermission(const std::string &permission, int pid, int uid, std::string &message) override;
private:
bool WriteInterfaceToken(MessageParcel &data);

View File

@ -43,6 +43,8 @@ private:
int32_t HandleAbilityBehaviorAnalysis(MessageParcel &data, MessageParcel &reply);
int32_t HandleKillProcessByAbilityToken(MessageParcel &data, MessageParcel &reply);
int32_t HandleKillApplication(MessageParcel &data, MessageParcel &reply);
int32_t HandleAbilityAttachTimeOut(MessageParcel &data, MessageParcel &reply);
int32_t HandleCompelVerifyPermission(MessageParcel &data, MessageParcel &reply);
using AmsMgrFunc = int32_t (AmsMgrStub::*)(MessageParcel &data, MessageParcel &reply);
std::map<uint32_t, AmsMgrFunc> memberFuncMap_;

View File

@ -130,10 +130,41 @@ public:
* GetAllRunningProcesses, call GetAllRunningProcesses() through proxy project.
* Obtains information about application processes that are running on the device.
*
* @param runningProcessInfo, app name in Application record.
* @param info, app name in Application record.
* @return ERR_OK ,return back successothers fail.
*/
virtual AppMgrResultCode GetAllRunningProcesses(std::shared_ptr<RunningProcessInfo> &runningProcessInfo);
virtual AppMgrResultCode GetAllRunningProcesses(std::vector<RunningProcessInfo> &info);
/**
* SetAppSuspendTimes, Setting the Freezing Time of APP Background.
*
* @param time, The timeout recorded when the application enters the background .
*
* @return Success or Failure .
*/
virtual AppMgrResultCode SetAppFreezingTime(int time);
/**
* GetAppFreezingTime, Getting the Freezing Time of APP Background.
*
* @param time, The timeout recorded when the application enters the background .
*
* @return Success or Failure .
*/
virtual AppMgrResultCode GetAppFreezingTime(int &time);
virtual void AbilityAttachTimeOut(const sptr<IRemoteObject> &token);
/**
* Checks whether a specified permission has been granted to the process identified by pid and uid
*
* @param permission Indicates the permission to check.
* @param pid Indicates the ID of the process to check.
* @param uid Indicates the UID of the process to check.
* @param message Describe success or failure
*
* @return Returns ERR_OK on success, others on failure.
*/
virtual int CompelVerifyPermission(const std::string &permission, int pid, int uid, std::string &message);
private:
void SetServiceManager(std::unique_ptr<AppServiceManager> serviceMgr);
@ -145,4 +176,4 @@ private:
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_APP_MGR_CLIENT_H
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_APP_MGR_CLIENT_H

View File

@ -100,7 +100,7 @@ public:
* @param bundleName, bundle name in Application record.
* @return
*/
virtual void ClearUpApplicationData(const std::string &bundleName) = 0;
virtual int32_t ClearUpApplicationData(const std::string &bundleName) = 0;
/**
* IsBackgroundRunningRestricted, call IsBackgroundRunningRestricted() through proxy project,
@ -115,10 +115,28 @@ public:
* GetAllRunningProcesses, call GetAllRunningProcesses() through proxy project.
* Obtains information about application processes that are running on the device.
*
* @param runningProcessInfo, app name in Application record.
* @param info, app name in Application record.
* @return ERR_OK ,return back successothers fail.
*/
virtual int GetAllRunningProcesses(std::shared_ptr<RunningProcessInfo> &runningProcessInfo) = 0;
virtual int GetAllRunningProcesses(std::vector<RunningProcessInfo> &info) = 0;
/**
* SetAppSuspendTimes, Setting the Freezing Time of APP Background.
*
* @param time, The timeout recorded when the application enters the background .
*
* @return Success or Failure .
*/
virtual void SetAppFreezingTime(int time) = 0;
/**
* GetAppFreezingTime, Getting the Freezing Time of APP Background.
*
* @param time, The timeout recorded when the application enters the background .
*
* @return Success or Failure .
*/
virtual void GetAppFreezingTime(int &time) = 0;
enum class Message {
AMS_APP_ATTACH_APPLICATION = 0,
@ -131,6 +149,8 @@ public:
AMS_APP_CLEAR_UP_APPLICATION_DATA,
AMS_APP_IS_BACKGROUND_RUNNING_RESTRICTED,
AMS_APP_GET_ALL_RUNNING_PROCESSES,
AMS_APP_SET_APP_FREEZING_TIME,
AMS_APP_GET_APP_FREEZING_TIME,
};
};

View File

@ -95,7 +95,7 @@ public:
* @param bundleName, bundle name in Application record.
* @return
*/
virtual void ClearUpApplicationData(const std::string &bundleName) override;
virtual int32_t ClearUpApplicationData(const std::string &bundleName) override;
/**
* IsBackgroundRunningRestricted, call IsBackgroundRunningRestricted() through proxy project,
@ -110,14 +110,34 @@ public:
* GetAllRunningProcesses, call GetAllRunningProcesses() through proxy project.
* Obtains information about application processes that are running on the device.
*
* @param runningProcessInfo, app name in Application record.
* @param info, app name in Application record.
* @return ERR_OK ,return back successothers fail.
*/
virtual int32_t GetAllRunningProcesses(std::shared_ptr<RunningProcessInfo> &runningProcessInfo) override;
virtual int32_t GetAllRunningProcesses(std::vector<RunningProcessInfo> &info) override;
/**
* SetAppSuspendTimes, Setting the Freezing Time of APP Background.
*
* @param time, The timeout recorded when the application enters the background .
*
* @return Success or Failure .
*/
virtual void SetAppFreezingTime(int time) override;
/**
* GetAppFreezingTime, Getting the Freezing Time of APP Background.
*
* @param time, The timeout recorded when the application enters the background .
*
* @return Success or Failure .
*/
virtual void GetAppFreezingTime(int &time) override;
private:
bool SendTransactCmd(IAppMgr::Message code, MessageParcel &data, MessageParcel &reply);
bool WriteInterfaceToken(MessageParcel &data);
template <typename T>
int GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos);
static inline BrokerDelegator<AppMgrProxy> delegator_;
};

View File

@ -45,6 +45,8 @@ private:
int32_t HandleClearUpApplicationData(MessageParcel &data, MessageParcel &reply);
int32_t HandleIsBackgroundRunningRestricted(MessageParcel &data, MessageParcel &reply);
int32_t HandleGetAllRunningProcesses(MessageParcel &data, MessageParcel &reply);
int32_t HandleSetAppFreezingTime(MessageParcel &data, MessageParcel &reply);
int32_t HandleGetAppFreezingTime(MessageParcel &data, MessageParcel &reply);
using AppMgrFunc = int32_t (AppMgrStub::*)(MessageParcel &data, MessageParcel &reply);
std::map<uint32_t, AppMgrFunc> memberFuncMap_;

View File

@ -42,6 +42,10 @@ public:
* @attention This function is implement in the proxy side.
*/
virtual std::string GetAppType([[maybe_unused]] const std::string &bundleName) override;
/**
* @attention This function is implement in the proxy side.
*/
virtual std::string GetAppIdByBundleName([[maybe_unused]] const std::string &bundleName, const int userId) override;
private:
/**
@ -79,6 +83,20 @@ private:
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetBundleNameForUid(Parcel &data, Parcel &reply);
/**
* @brief Handles the GetBundlesForUid function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetBundlesForUid(Parcel &data, Parcel &reply);
/**
* @brief Handles the GetNameForUid function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetNameForUid(Parcel &data, Parcel &reply);
/**
* @brief Handles the GetBundleGids function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
@ -268,6 +286,27 @@ private:
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleSetApplicationEnabled(Parcel &data, Parcel &reply);
/**
* @brief Handles the IsAbilityEnabled function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleIsAbilityEnabled(Parcel &data, Parcel &reply);
/**
* @brief Handles the SetAbilityEnabled function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleSetAbilityEnabled(Parcel &data, Parcel &reply);
/**
* @brief Handles the GetAbilityIcon function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetAbilityIcon(Parcel &data, Parcel &reply);
/**
* @brief Handles the CanRequestPermission function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
@ -282,6 +321,48 @@ private:
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleRequestPermissionFromUser(Parcel &data, Parcel &reply);
/**
* @brief Handles the RegisterAllPermissionsChanged function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleRegisterAllPermissionsChanged(Parcel &data, Parcel &reply);
/**
* @brief Handles the RegisterPermissionsChanged function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleRegisterPermissionsChanged(Parcel &data, Parcel &reply);
/**
* @brief Handles the UnregisterPermissionsChanged function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleUnregisterPermissionsChanged(Parcel &data, Parcel &reply);
/**
* @brief Handles the GetAllFormsInfo function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetAllFormsInfo(Parcel &data, Parcel &reply);
/**
* @brief Handles the GetFormsInfoByApp function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetFormsInfoByApp(Parcel &data, Parcel &reply);
/**
* @brief Handles the HandleGetFormsInfoByModule function called from a IBundleMgr proxy object.
* @param data Indicates the data to be read.
* @param reply Indicates the reply to be sent;
* @return Returns ERR_OK if called successfully; returns error code otherwise.
*/
ErrCode HandleGetFormsInfoByModule(Parcel &data, Parcel &reply);
private:
/**

View File

@ -17,6 +17,7 @@
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_BUNDLEMGR_BUNDLE_MGR_INTERFACE_H
#include "ability_info.h"
#include "form_info.h"
#include "application_info.h"
#include "bundle_info.h"
#include "hap_module_info.h"
@ -24,6 +25,7 @@
#include "bundle_installer_interface.h"
#include "bundle_status_callback_interface.h"
#include "clean_cache_callback_interface.h"
#include "on_permission_changed_callback_interface.h"
#include "ohos/aafwk/content/want.h"
namespace OHOS {
@ -83,6 +85,13 @@ public:
* @return Returns the uid if successfully obtained; returns -1 otherwise.
*/
virtual int GetUidByBundleName(const std::string &bundleName, const int userId) = 0;
/**
* @brief Obtains the application ID based on the given bundle name and user ID.
* @param bundleName Indicates the bundle name of the application.
* @param userId Indicates the user ID.
* @return Returns the application ID if successfully obtained; returns empty string otherwise.
*/
virtual std::string GetAppIdByBundleName(const std::string &bundleName, const int userId) = 0;
/**
* @brief Obtains the bundle name of a specified application based on the given UID.
* @param uid Indicates the uid.
@ -90,6 +99,20 @@ public:
* @return Returns true if the bundle name is successfully obtained; returns false otherwise.
*/
virtual bool GetBundleNameForUid(const int uid, std::string &bundleName) = 0;
/**
* @brief Obtains all bundle names of a specified application based on the given application UID.
* @param uid Indicates the uid.
* @param bundleNames Indicates the obtained bundle names.
* @return Returns true if the bundle names is successfully obtained; returns false otherwise.
*/
virtual bool GetBundlesForUid(const int uid, std::vector<std::string> &bundleNames) = 0;
/**
* @brief Obtains the formal name associated with the given UID.
* @param uid Indicates the uid.
* @param name Indicates the obtained formal name.
* @return Returns true if the formal name is successfully obtained; returns false otherwise.
*/
virtual bool GetNameForUid(const int uid, std::string &name) = 0;
/**
* @brief Obtains an array of all group IDs associated with a specified bundle.
* @param bundleName Indicates the bundle name.
@ -273,6 +296,27 @@ public:
* @return Returns true if the application is enabled; returns false otherwise.
*/
virtual bool SetApplicationEnabled(const std::string &bundleName, bool isEnable) = 0;
/**
* @brief Sets whether to enable a specified ability.
* @param abilityInfo Indicates information about the ability to check.
* @return Returns true if the ability is enabled; returns false otherwise.
*/
virtual bool IsAbilityEnabled(const AbilityInfo &abilityInfo) = 0;
/**
* @brief Sets whether to enable a specified ability.
* @param abilityInfo Indicates information about the ability.
* @param isEnabled Specifies whether to enable the ability.
* The value true means to enable it, and the value false means to disable it.
* @return Returns true if the ability is enabled; returns false otherwise.
*/
virtual bool SetAbilityEnabled(const AbilityInfo &abilityInfo, bool isEnabled) = 0;
/**
* @brief Obtains the icon of a specified ability.
* @param bundleName Indicates the bundle name.
* @param className Indicates the ability class name.
* @return Returns the icon resource string of the ability if exist; returns empty string otherwise.
*/
virtual std::string GetAbilityIcon(const std::string &bundleName, const std::string &className) = 0;
/**
* @brief Confirms with the permission management module to check whether a request prompt is required for granting
* a certain permission.
@ -294,6 +338,51 @@ public:
*/
virtual bool RequestPermissionFromUser(
const std::string &bundleName, const std::string &permission, const int userId) = 0;
/**
* @brief Registers a callback for listening for permission changes of all UIDs.
* @param callback Indicates the callback method to register.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool RegisterAllPermissionsChanged(const sptr<OnPermissionChangedCallback> &callback) = 0;
/**
* @brief Registers a callback for listening for permission changes of specified UIDs.
* @param uids Indicates the list of UIDs whose permission changes will be monitored.
* @param callback Indicates the callback method to register.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool RegisterPermissionsChanged(
const std::vector<int> &uids, const sptr<OnPermissionChangedCallback> &callback) = 0;
/**
* @brief Unregisters a specified callback for listening for permission changes.
* @param callback Indicates the callback method to register.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool UnregisterPermissionsChanged(const sptr<OnPermissionChangedCallback> &callback) = 0;
/**
* @brief Obtains the FormInfo objects provided by all applications on the device.
* @param formInfo list of FormInfo objects if obtained; returns an empty List if no FormInfo is available on the
* device.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool GetAllFormsInfo(std::vector<FormInfo> &formInfos) = 0;
/**
* @brief Obtains the FormInfo objects provided by a specified application on the device.
* @param bundleName Indicates the bundle name of the application.
* @param formInfo list of FormInfo objects if obtained; returns an empty List if no FormInfo is available on the
* device.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool GetFormsInfoByApp(const std::string &bundleName, std::vector<FormInfo> &formInfos) = 0;
/**
* @brief Obtains the FormInfo objects provided by a specified.
* @param formInfo list of FormInfo objects if obtained; returns an empty List if no FormInfo is available on the
* device.
* @param moduleName Indicates the module name of the application.
* @param bundleName Indicates the bundle name of the application.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool GetFormsInfoByModule(
const std::string &bundleName, const std::string &moduleName, std::vector<FormInfo> &formInfos) = 0;
/**
* @brief Obtains the interface used to install and uninstall bundles.
* @return Returns a pointer to IBundleInstaller class if exist; returns nullptr otherwise.
@ -306,7 +395,10 @@ public:
GET_BUNDLE_INFO,
GET_BUNDLE_INFOS,
GET_UID_BY_BUNDLE_NAME,
GET_APPID_BY_BUNDLE_NAME,
GET_BUNDLE_NAME_FOR_UID,
GET_BUNDLES_FOR_UID,
GET_NAME_FOR_UID,
GET_BUNDLE_GIDS,
GET_APP_TYPE,
CHECK_IS_SYSTEM_APP_BY_UID,
@ -334,8 +426,17 @@ public:
DUMP_INFOS,
IS_APPLICATION_ENABLED,
SET_APPLICATION_ENABLED,
IS_ABILITY_ENABLED,
SET_ABILITY_ENABLED,
GET_ABILITY_ICON,
CAN_REQUEST_PERMISSION,
REQUEST_PERMISSION_FROM_USER,
REGISTER_ALL_PERMISSIONS_CHANGED,
REGISTER_PERMISSIONS_CHANGED,
UNREGISTER_PERMISSIONS_CHANGED,
GET_ALL_FORMS_INFO,
GET_FORMS_INFO_BY_APP,
GET_FORMS_INFO_BY_MODULE,
GET_BUNDLE_INSTALLER,
};
};

View File

@ -75,6 +75,13 @@ public:
* @return Returns the uid if successfully obtained; returns -1 otherwise.
*/
virtual int GetUidByBundleName(const std::string &bundleName, const int userId) override;
/**
* @brief Obtains the application ID based on the given bundle name and user ID.
* @param bundleName Indicates the bundle name of the application.
* @param userId Indicates the user ID.
* @return Returns the application ID if successfully obtained; returns empty string otherwise.
*/
virtual std::string GetAppIdByBundleName(const std::string &bundleName, const int userId) override;
/**
* @brief Obtains the bundle name of a specified application based on the given UID through the proxy object.
* @param uid Indicates the uid.
@ -82,6 +89,20 @@ public:
* @return Returns true if the bundle name is successfully obtained; returns false otherwise.
*/
virtual bool GetBundleNameForUid(const int uid, std::string &bundleName) override;
/**
* @brief Obtains all bundle names of a specified application based on the given application UID the proxy object.
* @param uid Indicates the uid.
* @param bundleNames Indicates the obtained bundle names.
* @return Returns true if the bundle names is successfully obtained; returns false otherwise.
*/
virtual bool GetBundlesForUid(const int uid, std::vector<std::string> &bundleNames) override;
/**
* @brief Obtains the formal name associated with the given UID.
* @param uid Indicates the uid.
* @param name Indicates the obtained formal name.
* @return Returns true if the formal name is successfully obtained; returns false otherwise.
*/
virtual bool GetNameForUid(const int uid, std::string &name) override;
/**
* @brief Obtains an array of all group IDs associated with a specified bundle through the proxy object.
* @param bundleName Indicates the bundle name.
@ -267,6 +288,27 @@ public:
* @return Returns true if the application is enabled; returns false otherwise.
*/
virtual bool SetApplicationEnabled(const std::string &bundleName, bool isEnable) override;
/**
* @brief Sets whether to enable a specified ability through the proxy object.
* @param abilityInfo Indicates information about the ability to check.
* @return Returns true if the ability is enabled; returns false otherwise.
*/
virtual bool IsAbilityEnabled(const AbilityInfo &abilityInfo) override;
/**
* @brief Sets whether to enable a specified ability through the proxy object.
* @param abilityInfo Indicates information about the ability.
* @param isEnabled Specifies whether to enable the ability.
* The value true means to enable it, and the value false means to disable it.
* @return Returns true if the ability is enabled; returns false otherwise.
*/
virtual bool SetAbilityEnabled(const AbilityInfo &abilityInfo, bool isEnabled) override;
/**
* @brief Obtains the icon of a specified ability through the proxy object.
* @param bundleName Indicates the bundle name.
* @param className Indicates the ability class name.
* @return Returns the icon resource string of the ability if exist; returns empty string otherwise.
*/
virtual std::string GetAbilityIcon(const std::string &bundleName, const std::string &className) override;
/**
* @brief Obtains the interface used to install and uninstall bundles through the proxy object.
* @return Returns a pointer to IBundleInstaller class if exist; returns nullptr otherwise.
@ -293,6 +335,51 @@ public:
*/
virtual bool RequestPermissionFromUser(
const std::string &bundleName, const std::string &permission, const int userId) override;
/**
* @brief Registers a callback for listening for permission changes of all UIDs through the proxy object.
* @param callback Indicates the callback method to register.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool RegisterAllPermissionsChanged(const sptr<OnPermissionChangedCallback> &callback) override;
/**
* @brief Registers a callback for listening for permission changes of specified UIDs through the proxy object.
* @param uids Indicates the list of UIDs whose permission changes will be monitored.
* @param callback Indicates the callback method to register.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool RegisterPermissionsChanged(
const std::vector<int> &uids, const sptr<OnPermissionChangedCallback> &callback) override;
/**
* @brief Unregisters a specified callback for listening for permission changes through the proxy object.
* @param callback Indicates the callback method to register.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool UnregisterPermissionsChanged(const sptr<OnPermissionChangedCallback> &callback) override;
/**
* @brief Obtains the FormInfo objects provided by all applications on the device.
* @param formInfos List of FormInfo objects if obtained; returns an empty List if no FormInfo is available on the
* device.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool GetAllFormsInfo(std::vector<FormInfo> &formInfos) override;
/**
* @brief Obtains the FormInfo objects provided by a specified application on the device.
* @param bundleName Indicates the bundle name of the application.
* @param formInfos List of FormInfo objects if obtained; returns an empty List if no FormInfo is available on the
* device.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool GetFormsInfoByApp(const std::string &bundleName, std::vector<FormInfo> &formInfos) override;
/**
* @brief Obtains the FormInfo objects provided by a specified module name.
* @param bundleName Indicates the bundle name of the application.
* @param moduleName Indicates the module name of the application.
* @param formInfos List of FormInfo objects if obtained; returns an empty List if no FormInfo is available on the
* device.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
virtual bool GetFormsInfoByModule(
const std::string &bundleName, const std::string &moduleName, std::vector<FormInfo> &formInfos) override;
private:
/**
@ -310,7 +397,7 @@ private:
* @param parcelableInfo Indicates the object to be got;
* @return Returns true if objects get successfully; returns false otherwise.
*/
template<typename T>
template <typename T>
bool GetParcelableInfo(IBundleMgr::Message code, MessageParcel &data, T &parcelableInfo);
/**
* @brief Send a command message and then get a vector of parcelable information objects from the reply.
@ -319,7 +406,7 @@ private:
* @param parcelableInfos Indicates the vector objects to be got;
* @return Returns true if the vector get successfully; returns false otherwise.
*/
template<typename T>
template <typename T>
bool GetParcelableInfos(IBundleMgr::Message code, MessageParcel &data, std::vector<T> &parcelableInfos);
static inline BrokerDelegator<BundleMgrProxy> delegator_;
};

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_HOST_H
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_HOST_H
#include "iremote_stub.h"
#include "nocopyable.h"
#include "on_permission_changed_callback_interface.h"
namespace OHOS {
namespace AppExecFwk {
class OnPermissionChangedCallbackHost : public IRemoteStub<OnPermissionChangedCallback> {
public:
OnPermissionChangedCallbackHost();
virtual ~OnPermissionChangedCallbackHost() override;
int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
DISALLOW_COPY_AND_MOVE(OnPermissionChangedCallbackHost);
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_HOST_H

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_INTERFACE_H
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_INTERFACE_H
#include "iremote_broker.h"
namespace OHOS {
namespace AppExecFwk {
class OnPermissionChangedCallback : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.appexecfwk.OnPermissionChangedCallback");
/**
* @brief Called when an application's permission changed.
* @param uid Indicates the uid of the application which permission changed.
*/
virtual void OnChanged(const int32_t uid) = 0;
enum class Message {
ON_CHANGED,
};
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_INTERFACE_H

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_PROXY_H
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_PROXY_H
#include "iremote_proxy.h"
#include "on_permission_changed_callback_interface.h"
namespace OHOS {
namespace AppExecFwk {
class OnPermissionChangedCallbackProxy : public IRemoteProxy<OnPermissionChangedCallback> {
public:
explicit OnPermissionChangedCallbackProxy(const sptr<IRemoteObject> &object);
virtual ~OnPermissionChangedCallbackProxy() override;
/**
* @brief Called when an application's permission changed.
* @param uid Indicates the uid of the application which permission changed.
*/
virtual void OnChanged(const int32_t uid) override;
private:
static inline BrokerDelegator<OnPermissionChangedCallbackProxy> delegator_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_ON_PERMISSION_CHANGED_CALLBACK_PROXY_H

View File

@ -59,6 +59,7 @@ public:
ERR_INSTALL_FILE_PATH_INVALID,
ERR_INSTALL_INVALID_HAP_NAME,
ERR_INSTALL_INVALID_BUNDLE_FILE,
ERR_INSTALL_INVALID_HAP_SIZE,
ERR_INSTALL_GENERATE_UID_ERROR,
ERR_INSTALL_INSTALLD_SERVICE_ERROR,
ERR_INSTALL_BUNDLE_MGR_SERVICE_ERROR,
@ -72,6 +73,7 @@ public:
ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR,
ERR_INSTALL_PARSE_PROFILE_MISSING_PROP,
ERR_INSTALL_PARSE_PERMISSION_ERROR,
ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR,
ERR_INSTALLD_PARAM_ERROR,
ERR_INSTALLD_GET_PROXY_ERROR,

View File

@ -14,7 +14,7 @@
*/
#include "ams_mgr_proxy.h"
#include "string_ex.h"
#include "ipc_types.h"
#include "iremote_object.h"
@ -239,8 +239,58 @@ int32_t AmsMgrProxy::KillApplication(const std::string &bundleName)
return ret;
}
return reply.ReadInt32();
}
void AmsMgrProxy::AbilityAttachTimeOut(const sptr<IRemoteObject> &token)
{
APP_LOGD("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!WriteInterfaceToken(data)) {
return;
}
data.WriteParcelable(token.GetRefPtr());
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
APP_LOGE("Remote() is NULL");
return;
}
int32_t ret =
remote->SendRequest(static_cast<uint32_t>(IAmsMgr::Message::AMS_ABILITY_ATTACH_TIMEOUT), data, reply, option);
if (ret != NO_ERROR) {
APP_LOGW("SendRequest is failed, error code: %{public}d", ret);
}
APP_LOGD("end");
}
int AmsMgrProxy::CompelVerifyPermission(const std::string &permission, int pid, int uid, std::string &message)
{
APP_LOGD("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!WriteInterfaceToken(data)) {
return ERR_INVALID_DATA;
}
if (!data.WriteString16(Str8ToStr16(permission)) || !data.WriteInt32(pid) || !data.WriteInt32(uid)) {
APP_LOGE("%{public}s, write failed", __func__);
return ERR_INVALID_DATA;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
APP_LOGE("Remote() is NULL");
return ERR_NULL_OBJECT;
}
auto ret =
remote->SendRequest(static_cast<uint32_t>(IAmsMgr::Message::AMS_COMPEL_VERIFY_PERMISSION), data, reply, option);
if (ret != NO_ERROR) {
APP_LOGW("SendRequest is failed, error code: %{public}d", ret);
return ERR_INVALID_DATA;
}
message = Str16ToStr8(reply.ReadString16());
return reply.ReadInt32();
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -44,6 +44,10 @@ AmsMgrStub::AmsMgrStub()
memberFuncMap_[static_cast<uint32_t>(IAmsMgr::Message::AMS_KILL_PEOCESS_BY_ABILITY_TOKEN)] =
&AmsMgrStub::HandleKillProcessByAbilityToken;
memberFuncMap_[static_cast<uint32_t>(IAmsMgr::Message::AMS_KILL_APPLICATION)] = &AmsMgrStub::HandleKillApplication;
memberFuncMap_[static_cast<uint32_t>(IAmsMgr::Message::AMS_ABILITY_ATTACH_TIMEOUT)] =
&AmsMgrStub::HandleAbilityAttachTimeOut;
memberFuncMap_[static_cast<uint32_t>(IAmsMgr::Message::AMS_COMPEL_VERIFY_PERMISSION)] =
&AmsMgrStub::HandleCompelVerifyPermission;
}
AmsMgrStub::~AmsMgrStub()
@ -148,5 +152,23 @@ ErrCode AmsMgrStub::HandleKillApplication(MessageParcel &data, MessageParcel &re
return NO_ERROR;
}
int32_t AmsMgrStub::HandleAbilityAttachTimeOut(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> token = data.ReadParcelable<IRemoteObject>();
AbilityAttachTimeOut(token);
return NO_ERROR;
}
int32_t AmsMgrStub::HandleCompelVerifyPermission(MessageParcel &data, MessageParcel &reply)
{
auto permission = Str16ToStr8(data.ReadString16());
auto pid = data.ReadInt32();
auto uid = data.ReadInt32();
std::string message;
auto result = CompelVerifyPermission(permission, pid, uid, message);
reply.WriteString16(Str8ToStr16(message));
reply.WriteInt32(result);
return NO_ERROR;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -153,17 +153,43 @@ AppMgrResultCode AppMgrClient::ClearUpApplicationData(const std::string &bundleN
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service != nullptr) {
service->ClearUpApplicationData(bundleName);
int32_t result = service->ClearUpApplicationData(bundleName);
if (result == ERR_OK) {
return AppMgrResultCode::RESULT_OK;
}
return AppMgrResultCode::ERROR_SERVICE_NOT_READY;
}
return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
}
AppMgrResultCode AppMgrClient::GetAllRunningProcesses(std::vector<RunningProcessInfo> &info)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service != nullptr) {
int32_t result = service->GetAllRunningProcesses(info);
if (result == ERR_OK) {
return AppMgrResultCode::RESULT_OK;
}
return AppMgrResultCode::ERROR_SERVICE_NOT_READY;
}
return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
}
AppMgrResultCode AppMgrClient::SetAppFreezingTime(int time)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service != nullptr) {
service->SetAppFreezingTime(time);
return AppMgrResultCode::RESULT_OK;
}
return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
}
AppMgrResultCode AppMgrClient::GetAllRunningProcesses(std::shared_ptr<RunningProcessInfo> &runningProcessInfo)
AppMgrResultCode AppMgrClient::GetAppFreezingTime(int &time)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service != nullptr) {
service->GetAllRunningProcesses(runningProcessInfo);
service->GetAppFreezingTime(time);
return AppMgrResultCode::RESULT_OK;
}
return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
@ -186,5 +212,34 @@ void AppMgrClient::SetServiceManager(std::unique_ptr<AppServiceManager> serviceM
serviceManager_ = std::move(serviceMgr);
}
void AppMgrClient::AbilityAttachTimeOut(const sptr<IRemoteObject> &token)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service == nullptr) {
return;
}
sptr<IAmsMgr> amsService = service->GetAmsMgr();
if (amsService == nullptr) {
return;
}
amsService->AbilityAttachTimeOut(token);
}
int AppMgrClient::CompelVerifyPermission(const std::string &permission, int pid, int uid, std::string &message)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service == nullptr) {
return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
}
sptr<IAmsMgr> amsService = service->GetAmsMgr();
if (amsService == nullptr) {
return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
}
auto result = amsService->CompelVerifyPermission(permission, pid, uid, message);
if (result != ERR_OK) {
return AppMgrResultCode::ERROR_SERVICE_NOT_READY;
}
return AppMgrResultCode::RESULT_OK;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -199,31 +199,32 @@ sptr<IAmsMgr> AppMgrProxy::GetAmsMgr()
return amsMgr;
}
void AppMgrProxy::ClearUpApplicationData(const std::string &bundleName)
int32_t AppMgrProxy::ClearUpApplicationData(const std::string &bundleName)
{
APP_LOGD("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!WriteInterfaceToken(data)) {
return;
return ERR_FLATTEN_OBJECT;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
APP_LOGE("Remote() is NULL");
return;
return ERR_NULL_OBJECT;
}
if (!data.WriteString(bundleName)) {
APP_LOGE("parcel WriteString failed");
return;
return ERR_FLATTEN_OBJECT;
}
int32_t ret = remote->SendRequest(
static_cast<uint32_t>(IAppMgr::Message::AMS_APP_CLEAR_UP_APPLICATION_DATA), data, reply, option);
if (ret != NO_ERROR) {
APP_LOGW("SendRequest is failed, error code: %{public}d", ret);
return;
return ret;
}
APP_LOGD("end");
return reply.ReadInt32();
}
int32_t AppMgrProxy::IsBackgroundRunningRestricted(const std::string &bundleName)
@ -254,7 +255,7 @@ int32_t AppMgrProxy::IsBackgroundRunningRestricted(const std::string &bundleName
return reply.ReadInt32();
}
int32_t AppMgrProxy::GetAllRunningProcesses(std::shared_ptr<RunningProcessInfo> &runningProcessInfo)
int32_t AppMgrProxy::GetAllRunningProcesses(std::vector<RunningProcessInfo> &info)
{
APP_LOGD("start");
MessageParcel data;
@ -268,20 +269,15 @@ int32_t AppMgrProxy::GetAllRunningProcesses(std::shared_ptr<RunningProcessInfo>
APP_LOGE("Remote() is NULL");
return ERR_NULL_OBJECT;
}
if (!data.WriteParcelable(runningProcessInfo.get())) {
APP_LOGE("parcel WriteString failed");
return ERR_FLATTEN_OBJECT;
}
if (!SendTransactCmd(IAppMgr::Message::AMS_APP_GET_ALL_RUNNING_PROCESSES, data, reply)) {
return ERR_NULL_OBJECT;
}
int result = reply.ReadInt32();
std::unique_ptr<RunningProcessInfo> info(reply.ReadParcelable<RunningProcessInfo>());
if (!info) {
APP_LOGE("readParcelableInfo failed");
return ERR_NULL_OBJECT;
auto error = GetParcelableInfos<RunningProcessInfo>(reply, info);
if (error != NO_ERROR) {
APP_LOGE("GetParcelableInfos fail, error: %{public}d", error);
return error;
}
runningProcessInfo = std::move(info);
int result = reply.ReadInt32();
APP_LOGD("end");
return result;
}
@ -302,5 +298,62 @@ bool AppMgrProxy::SendTransactCmd(IAppMgr::Message code, MessageParcel &data, Me
return true;
}
void AppMgrProxy::SetAppFreezingTime(int time)
{
APP_LOGD("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!WriteInterfaceToken(data)) {
return;
}
if (!data.WriteInt32(time)) {
APP_LOGE("parcel WriteInt32 failed");
return;
}
if (!SendTransactCmd(IAppMgr::Message::AMS_APP_SET_APP_FREEZING_TIME, data, reply)) {
APP_LOGE("SendTransactCmd faild");
return;
}
APP_LOGD("end");
}
void AppMgrProxy::GetAppFreezingTime(int &time)
{
APP_LOGD("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!WriteInterfaceToken(data)) {
APP_LOGE("WriteInterfaceToken faild");
return;
}
if (!SendTransactCmd(IAppMgr::Message::AMS_APP_GET_APP_FREEZING_TIME, data, reply)) {
APP_LOGE("SendTransactCmd faild");
return;
}
time = reply.ReadInt32();
APP_LOGE("get freeze time : %{public}d ", time);
}
template <typename T>
int AppMgrProxy::GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos)
{
int32_t infoSize = reply.ReadInt32();
for (int32_t i = 0; i < infoSize; i++) {
std::unique_ptr<T> info(reply.ReadParcelable<T>());
if (!info) {
APP_LOGE("Read Parcelable infos failed");
return ERR_INVALID_VALUE;
}
parcelableInfos.emplace_back(*info);
}
APP_LOGD("get parcelable infos success");
return NO_ERROR;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -50,6 +50,10 @@ AppMgrStub::AppMgrStub()
&AppMgrStub::HandleIsBackgroundRunningRestricted;
memberFuncMap_[static_cast<uint32_t>(IAppMgr::Message::AMS_APP_GET_ALL_RUNNING_PROCESSES)] =
&AppMgrStub::HandleGetAllRunningProcesses;
memberFuncMap_[static_cast<uint32_t>(IAppMgr::Message::AMS_APP_SET_APP_FREEZING_TIME)] =
&AppMgrStub::HandleSetAppFreezingTime;
memberFuncMap_[static_cast<uint32_t>(IAppMgr::Message::AMS_APP_GET_APP_FREEZING_TIME)] =
&AppMgrStub::HandleGetAppFreezingTime;
}
AppMgrStub::~AppMgrStub()
@ -138,7 +142,8 @@ int32_t AppMgrStub::HandleGetAmsMgr(MessageParcel &data, MessageParcel &reply)
int32_t AppMgrStub::HandleClearUpApplicationData(MessageParcel &data, MessageParcel &reply)
{
std::string bundleName = data.ReadString();
ClearUpApplicationData(bundleName);
int32_t result = ClearUpApplicationData(bundleName);
reply.WriteInt32(result);
return NO_ERROR;
}
@ -152,12 +157,33 @@ int32_t AppMgrStub::HandleIsBackgroundRunningRestricted(MessageParcel &data, Mes
int32_t AppMgrStub::HandleGetAllRunningProcesses(MessageParcel &data, MessageParcel &reply)
{
std::shared_ptr<RunningProcessInfo> runningProcessInfo(data.ReadParcelable<RunningProcessInfo>());
int32_t result = GetAllRunningProcesses(runningProcessInfo);
reply.WriteInt32(result);
reply.WriteParcelable(runningProcessInfo.get());
std::vector<RunningProcessInfo> info;
auto result = GetAllRunningProcesses(info);
reply.WriteInt32(info.size());
for (auto &it : info) {
if (!reply.WriteParcelable(&it)) {
return ERR_INVALID_VALUE;
}
}
if (!reply.WriteInt32(result)) {
return ERR_INVALID_VALUE;
}
return NO_ERROR;
}
int32_t AppMgrStub::HandleSetAppFreezingTime(MessageParcel &data, MessageParcel &reply)
{
SetAppFreezingTime(data.ReadInt32());
return NO_ERROR;
}
int32_t AppMgrStub::HandleGetAppFreezingTime(MessageParcel &data, MessageParcel &reply)
{
int time = 0;
GetAppFreezingTime(time);
reply.WriteInt32(time);
return NO_ERROR;
}
} // namespace AppExecFwk
} // namespace OHOS
} // namespace OHOS

View File

@ -71,6 +71,12 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa
case static_cast<uint32_t>(IBundleMgr::Message::GET_BUNDLE_NAME_FOR_UID):
errCode = HandleGetBundleNameForUid(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_BUNDLES_FOR_UID):
errCode = HandleGetBundlesForUid(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_NAME_FOR_UID):
errCode = HandleGetNameForUid(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_BUNDLE_GIDS):
errCode = HandleGetBundleGids(data, reply);
break;
@ -102,7 +108,7 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa
errCode = HandleGetLaunchWantForBundle(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::CHECK_PUBLICKEYS):
errCode = HandleGetApplicationInfo(data, reply);
errCode = HandleCheckPublicKeys(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::CHECK_PERMISSION):
errCode = HandleCheckPermission(data, reply);
@ -140,6 +146,21 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa
case static_cast<uint32_t>(IBundleMgr::Message::UNREGISTER_BUNDLE_STATUS_CALLBACK):
errCode = HandleUnregisterBundleStatusCallback(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::IS_APPLICATION_ENABLED):
errCode = HandleIsApplicationEnabled(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::SET_APPLICATION_ENABLED):
errCode = HandleSetApplicationEnabled(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::IS_ABILITY_ENABLED):
errCode = HandleIsAbilityEnabled(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::SET_ABILITY_ENABLED):
errCode = HandleSetAbilityEnabled(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_ABILITY_ICON):
errCode = HandleGetAbilityIcon(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::DUMP_INFOS):
errCode = HandleDumpInfos(data, reply);
break;
@ -152,6 +173,24 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa
case static_cast<uint32_t>(IBundleMgr::Message::REQUEST_PERMISSION_FROM_USER):
errCode = HandleRequestPermissionFromUser(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::REGISTER_ALL_PERMISSIONS_CHANGED):
errCode = HandleRegisterAllPermissionsChanged(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::REGISTER_PERMISSIONS_CHANGED):
errCode = HandleRegisterPermissionsChanged(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::UNREGISTER_PERMISSIONS_CHANGED):
errCode = HandleUnregisterPermissionsChanged(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_ALL_FORMS_INFO):
errCode = HandleGetAllFormsInfo(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_FORMS_INFO_BY_APP):
errCode = HandleGetFormsInfoByApp(data, reply);
break;
case static_cast<uint32_t>(IBundleMgr::Message::GET_FORMS_INFO_BY_MODULE):
errCode = HandleGetFormsInfoByModule(data, reply);
break;
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
@ -165,6 +204,12 @@ int BundleMgrHost::GetUidByBundleName([[maybe_unused]] const std::string &bundle
return Constants::INVALID_UID;
}
std::string BundleMgrHost::GetAppIdByBundleName([[maybe_unused]] const std::string &bundleName, const int userId)
{
APP_LOGD("need not impl for host interface");
return Constants::EMPTY_STRING;
}
std::string BundleMgrHost::GetAppType([[maybe_unused]] const std::string &bundleName)
{
APP_LOGD("need not impl for host interface");
@ -269,6 +314,42 @@ ErrCode BundleMgrHost::HandleGetBundleNameForUid(Parcel &data, Parcel &reply)
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetBundlesForUid(Parcel &data, Parcel &reply)
{
int uid = data.ReadInt32();
std::vector<std::string> names;
bool ret = GetBundlesForUid(uid, names);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
if (ret) {
if (!reply.WriteStringVector(names)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetNameForUid(Parcel &data, Parcel &reply)
{
int uid = data.ReadInt32();
std::string name;
bool ret = GetNameForUid(uid, name);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
if (ret) {
if (!reply.WriteString(name)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetBundleGids(Parcel &data, Parcel &reply)
{
std::string name = data.ReadString();
@ -373,7 +454,7 @@ ErrCode BundleMgrHost::HandleGetAbilityLabel(Parcel &data, Parcel &reply)
APP_LOGI("bundleName %{public}s, className %{public}s", bundleName.c_str(), className.c_str());
BundleInfo info;
std::string label = GetAbilityLabel(bundleName, className);
if (!reply.WriteString16(Str8ToStr16(label))) {
if (!reply.WriteString(label)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
@ -696,6 +777,52 @@ ErrCode BundleMgrHost::HandleSetApplicationEnabled(Parcel &data, Parcel &reply)
return ERR_OK;
}
ErrCode BundleMgrHost::HandleIsAbilityEnabled(Parcel &data, Parcel &reply)
{
std::unique_ptr<AbilityInfo> abilityInfo(data.ReadParcelable<AbilityInfo>());
if (!abilityInfo) {
APP_LOGE("ReadParcelable<abilityInfo> failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
bool ret = IsAbilityEnabled(*abilityInfo);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleSetAbilityEnabled(Parcel &data, Parcel &reply)
{
std::unique_ptr<AbilityInfo> abilityInfo(data.ReadParcelable<AbilityInfo>());
if (!abilityInfo) {
APP_LOGE("ReadParcelable<abilityInfo> failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
bool isEnabled = data.ReadBool();
bool ret = SetAbilityEnabled(*abilityInfo, isEnabled);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetAbilityIcon(Parcel &data, Parcel &reply)
{
std::string bundleName = data.ReadString();
std::string className = data.ReadString();
APP_LOGI("bundleName %{public}s, className %{public}s", bundleName.c_str(), className.c_str());
BundleInfo info;
std::string icon = GetAbilityIcon(bundleName, className);
if (!reply.WriteString(icon)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleCanRequestPermission(Parcel &data, Parcel &reply)
{
std::string bundleName = data.ReadString();
@ -726,6 +853,63 @@ ErrCode BundleMgrHost::HandleRequestPermissionFromUser(Parcel &data, Parcel &rep
return ERR_OK;
}
ErrCode BundleMgrHost::HandleRegisterAllPermissionsChanged(Parcel &data, Parcel &reply)
{
sptr<IRemoteObject> object = data.ReadParcelable<IRemoteObject>();
sptr<OnPermissionChangedCallback> callback = iface_cast<OnPermissionChangedCallback>(object);
bool ret = false;
if (!callback) {
APP_LOGE("Get OnPermissionChangedCallback failed");
} else {
ret = RegisterAllPermissionsChanged(callback);
}
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleRegisterPermissionsChanged(Parcel &data, Parcel &reply)
{
std::vector<int> uids;
if (!data.ReadInt32Vector(&uids)) {
APP_LOGE("read parcel failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
sptr<IRemoteObject> object = data.ReadParcelable<IRemoteObject>();
sptr<OnPermissionChangedCallback> callback = iface_cast<OnPermissionChangedCallback>(object);
bool ret = false;
if (!callback) {
APP_LOGE("Get OnPermissionChangedCallback failed");
} else {
ret = RegisterPermissionsChanged(uids, callback);
}
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleUnregisterPermissionsChanged(Parcel &data, Parcel &reply)
{
sptr<IRemoteObject> object = data.ReadParcelable<IRemoteObject>();
sptr<OnPermissionChangedCallback> callback = iface_cast<OnPermissionChangedCallback>(object);
bool ret = false;
if (!callback) {
APP_LOGE("Get OnPermissionChangedCallback failed");
} else {
ret = UnregisterPermissionsChanged(callback);
}
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetBundleInstaller(Parcel &data, Parcel &reply)
{
sptr<IBundleInstaller> installer = GetBundleInstaller();
@ -741,6 +925,63 @@ ErrCode BundleMgrHost::HandleGetBundleInstaller(Parcel &data, Parcel &reply)
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetAllFormsInfo(Parcel &data, Parcel &reply)
{
std::vector<FormInfo> infos;
bool ret = GetAllFormsInfo(infos);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
if (ret) {
if (!WriteParcelableVector(infos, reply)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetFormsInfoByApp(Parcel &data, Parcel &reply)
{
std::string bundlename = data.ReadString();
std::vector<FormInfo> infos;
bool ret = GetFormsInfoByApp(bundlename, infos);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
if (ret) {
if (!WriteParcelableVector(infos, reply)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
}
return ERR_OK;
}
ErrCode BundleMgrHost::HandleGetFormsInfoByModule(Parcel &data, Parcel &reply)
{
std::string bundlename = data.ReadString();
std::string modulename = data.ReadString();
std::vector<FormInfo> infos;
bool ret = GetFormsInfoByModule(bundlename, modulename, infos);
if (!reply.WriteBool(ret)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
if (ret) {
if (!WriteParcelableVector(infos, reply)) {
APP_LOGE("write failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
}
return ERR_OK;
}
template<typename T>
bool BundleMgrHost::WriteParcelableVector(std::vector<T> &parcelableVector, Parcel &reply)
{

View File

@ -159,6 +159,21 @@ int BundleMgrProxy::GetUidByBundleName(const std::string &bundleName, const int
return uid;
}
std::string BundleMgrProxy::GetAppIdByBundleName(const std::string &bundleName, const int userId)
{
APP_LOGI("begin to get uid of %{public}s", bundleName.c_str());
BundleInfo bundleInfo;
std::string appId = Constants::EMPTY_STRING;
bool ret = GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo);
if (ret) {
appId = bundleInfo.appId;
APP_LOGD("get bundle appId success");
} else {
APP_LOGE("can not get bundleInfo's appId");
}
return appId;
}
bool BundleMgrProxy::GetBundleNameForUid(const int uid, std::string &bundleName)
{
APP_LOGI("begin to GetBundleNameForUid of %{public}d", uid);
@ -185,6 +200,61 @@ bool BundleMgrProxy::GetBundleNameForUid(const int uid, std::string &bundleName)
return true;
}
bool BundleMgrProxy::GetBundlesForUid(const int uid, std::vector<std::string> &bundleNames)
{
APP_LOGI("begin to GetBundlesForUid of %{public}d", uid);
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to GetBundlesForUid due to write InterfaceToken fail");
return false;
}
if (!data.WriteInt32(uid)) {
APP_LOGE("fail to GetBundlesForUid due to write uid fail");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::GET_BUNDLES_FOR_UID, data, reply)) {
APP_LOGE("fail to GetBundlesForUid from server");
return false;
}
if (!reply.ReadBool()) {
APP_LOGE("reply result false");
return false;
}
if (!reply.ReadStringVector(&bundleNames)) {
APP_LOGE("fail to GetBundlesForUid from reply");
return false;
}
return true;
}
bool BundleMgrProxy::GetNameForUid(const int uid, std::string &name)
{
APP_LOGI("begin to GetNameForUid of %{public}d", uid);
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to GetNameForUid due to write InterfaceToken fail");
return false;
}
if (!data.WriteInt32(uid)) {
APP_LOGE("fail to GetNameForUid due to write uid fail");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::GET_NAME_FOR_UID, data, reply)) {
APP_LOGE("fail to GetNameForUid from server");
return false;
}
if (!reply.ReadBool()) {
APP_LOGE("reply result false");
return false;
}
name = reply.ReadString();
return true;
}
bool BundleMgrProxy::GetBundleGids(const std::string &bundleName, std::vector<int> &gids)
{
APP_LOGI("begin to GetBundleGids of %{public}s", bundleName.c_str());
@ -203,7 +273,10 @@ bool BundleMgrProxy::GetBundleGids(const std::string &bundleName, std::vector<in
APP_LOGE("fail to GetBundleGids from server");
return false;
}
if (!reply.ReadBool()) {
APP_LOGE("reply result false");
return false;
}
if (!reply.ReadInt32Vector(&gids)) {
APP_LOGE("fail to GetBundleGids from reply");
return false;
@ -859,6 +932,92 @@ bool BundleMgrProxy::SetApplicationEnabled(const std::string &bundleName, bool i
return reply.ReadBool();
}
bool BundleMgrProxy::IsAbilityEnabled(const AbilityInfo &abilityInfo)
{
APP_LOGI("begin to IsAbilityEnabled of %{public}s", abilityInfo.name.c_str());
if (abilityInfo.name.empty()) {
APP_LOGE("fail to IsAbilityEnabled due to params empty");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to IsAbilityEnabled due to write InterfaceToken fail");
return false;
}
if (!data.WriteParcelable(&abilityInfo)) {
APP_LOGE("fail to IsAbilityEnabled due to write abilityInfo fail");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::IS_ABILITY_ENABLED, data, reply)) {
APP_LOGE("fail to IsAbilityEnabled from server");
return false;
}
return reply.ReadBool();
}
bool BundleMgrProxy::SetAbilityEnabled(const AbilityInfo &abilityInfo, bool isEnabled)
{
APP_LOGI("begin to SetAbilityEnabled of %{public}s", abilityInfo.name.c_str());
if (abilityInfo.name.empty()) {
APP_LOGE("fail to SetAbilityEnabled due to params empty");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to SetAbilityEnabled due to write InterfaceToken fail");
return false;
}
if (!data.WriteParcelable(&abilityInfo)) {
APP_LOGE("fail to SetAbilityEnabled due to write abilityInfo fail");
return false;
}
if (!data.WriteBool(isEnabled)) {
APP_LOGE("fail to SetAbilityEnabled due to write isEnabled fail");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::SET_ABILITY_ENABLED, data, reply)) {
APP_LOGE("fail to SetAbilityEnabled from server");
return false;
}
return reply.ReadBool();
}
std::string BundleMgrProxy::GetAbilityIcon(const std::string &bundleName, const std::string &className)
{
APP_LOGI("begin to get bundle info of %{public}s", bundleName.c_str());
if (bundleName.empty()) {
APP_LOGE("fail to GetAbilityIcon due to params empty");
return Constants::EMPTY_STRING;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to GetAbilityIcon due to write InterfaceToken fail");
return Constants::EMPTY_STRING;
}
if (!data.WriteString(bundleName)) {
APP_LOGE("fail to GetAbilityIcon due to write bundleName fail");
return Constants::EMPTY_STRING;
}
if (!data.WriteString(className)) {
APP_LOGE("fail to GetAbilityIcon due to write className fail");
return Constants::EMPTY_STRING;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::GET_ABILITY_ICON, data, reply)) {
APP_LOGE("fail to GetAbilityIcon from server");
return Constants::EMPTY_STRING;
}
return reply.ReadString();
}
sptr<IBundleInstaller> BundleMgrProxy::GetBundleInstaller()
{
APP_LOGD("begin to get bundle installer");
@ -952,7 +1111,159 @@ bool BundleMgrProxy::RequestPermissionFromUser(
return reply.ReadBool();
}
template<typename T>
bool BundleMgrProxy::RegisterAllPermissionsChanged(const sptr<OnPermissionChangedCallback> &callback)
{
APP_LOGI("begin to RegisterAllPermissionsChanged");
if (!callback) {
APP_LOGE("fail to RegisterAllPermissionsChanged");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to RegisterAllPermissionsChanged due to write InterfaceToken fail");
return false;
}
if (!data.WriteParcelable(callback->AsObject())) {
APP_LOGE("fail to RegisterAllPermissionsChanged, for write parcel failed");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::REGISTER_ALL_PERMISSIONS_CHANGED, data, reply)) {
APP_LOGE("fail to RegisterAllPermissionsChanged from server");
return false;
}
return reply.ReadBool();
}
bool BundleMgrProxy::RegisterPermissionsChanged(
const std::vector<int> &uids, const sptr<OnPermissionChangedCallback> &callback)
{
APP_LOGI("begin to RegisterAllPermissionsChanged");
if (!callback || uids.empty()) {
APP_LOGE("fail to RegisterAllPermissionsChanged");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to RegisterAllPermissionsChanged due to write InterfaceToken fail");
return false;
}
if (!data.WriteInt32Vector(uids)) {
APP_LOGE("fail to RegisterAllPermissionsChanged due to write permissions fail");
return false;
}
if (!data.WriteParcelable(callback->AsObject())) {
APP_LOGE("fail to RegisterAllPermissionsChanged, for write parcel failed");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::REGISTER_PERMISSIONS_CHANGED, data, reply)) {
APP_LOGE("fail to RegisterAllPermissionsChanged from server");
return false;
}
return reply.ReadBool();
}
bool BundleMgrProxy::UnregisterPermissionsChanged(const sptr<OnPermissionChangedCallback> &callback)
{
APP_LOGI("begin to UnregisterPermissionsChanged");
if (!callback) {
APP_LOGE("fail to UnregisterPermissionsChanged, for callback is nullptr");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to UnregisterPermissionsChanged due to write InterfaceToken fail");
return false;
}
if (!data.WriteParcelable(callback->AsObject())) {
APP_LOGE("fail to UnregisterPermissionsChanged, for write parcel failed");
return false;
}
MessageParcel reply;
if (!SendTransactCmd(IBundleMgr::Message::UNREGISTER_PERMISSIONS_CHANGED, data, reply)) {
APP_LOGE("fail to UnregisterPermissionsChanged from server");
return false;
}
return reply.ReadBool();
}
bool BundleMgrProxy::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to GetAllFormsInfo due to write MessageParcel fail");
return false;
}
if (!GetParcelableInfos<FormInfo>(IBundleMgr::Message::GET_ALL_FORMS_INFO, data, formInfos)) {
APP_LOGE("fail to GetAllFormsInfo from server");
return false;
}
return true;
}
bool BundleMgrProxy::GetFormsInfoByApp(const std::string &bundleName, std::vector<FormInfo> &formInfos)
{
if (bundleName.empty()) {
APP_LOGE("fail to GetFormsInfoByApp due to params empty");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to GetFormsInfoByApp due to write MessageParcel fail");
return false;
}
if (!data.WriteString(bundleName)) {
APP_LOGE("fail to GetFormsInfoByApp due to write bundleName fail");
return false;
}
if (!GetParcelableInfos<FormInfo>(IBundleMgr::Message::GET_FORMS_INFO_BY_APP, data, formInfos)) {
APP_LOGE("fail to GetFormsInfoByApp from server");
return false;
}
return true;
}
bool BundleMgrProxy::GetFormsInfoByModule(
const std::string &bundleName, const std::string &moduleName, std::vector<FormInfo> &formInfos)
{
if (bundleName.empty() || moduleName.empty()) {
APP_LOGE("fail to GetFormsByModule due to params empty");
return false;
}
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
APP_LOGE("fail to GetFormsInfoByModule due to write MessageParcel fail");
return false;
}
if (!data.WriteString(bundleName)) {
APP_LOGE("fail to GetFormsInfoByModule due to write bundleName fail");
return false;
}
if (!data.WriteString(moduleName)) {
APP_LOGE("fail to GetFormsInfoByModule due to write moduleName fail");
return false;
}
if (!GetParcelableInfos<FormInfo>(IBundleMgr::Message::GET_FORMS_INFO_BY_MODULE, data, formInfos)) {
APP_LOGE("fail to GetFormsInfoByModule from server");
return false;
}
return true;
}
template <typename T>
bool BundleMgrProxy::GetParcelableInfo(IBundleMgr::Message code, MessageParcel &data, T &parcelableInfo)
{
MessageParcel reply;
@ -975,7 +1286,7 @@ bool BundleMgrProxy::GetParcelableInfo(IBundleMgr::Message code, MessageParcel &
return true;
}
template<typename T>
template <typename T>
bool BundleMgrProxy::GetParcelableInfos(IBundleMgr::Message code, MessageParcel &data, std::vector<T> &parcelableInfos)
{
MessageParcel reply;

View File

@ -59,6 +59,8 @@ std::string TransformResult(ErrCode resultCode)
return "ERR_APPEXECFWK_INSTALL_INVALID_HAP_NAME";
case ERR_APPEXECFWK_INSTALL_INVALID_BUNDLE_FILE:
return "ERR_APPEXECFWK_INSTALL_INVALID_BUNDLE_FILE";
case ERR_APPEXECFWK_INSTALL_INVALID_HAP_SIZE:
return "ERR_APPEXECFWK_INSTALL_INVALID_HAP_SIZE";
case ERR_APPEXECFWK_INSTALL_GENERATE_UID_ERROR:
return "ERR_APPEXECFWK_INSTALL_GENERATE_UID_ERROR";
case ERR_APPEXECFWK_INSTALL_INSTALLD_SERVICE_ERROR:
@ -83,6 +85,8 @@ std::string TransformResult(ErrCode resultCode)
return "ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP";
case ERR_APPEXECFWK_PARSE_PERMISSION_ERROR:
return "ERR_APPEXECFWK_PARSE_PERMISSION_ERROR";
case ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR:
return "ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR";
case ERR_APPEXECFWK_INSTALLD_PARAM_ERROR:
return "ERR_APPEXECFWK_INSTALLD_PARAM_ERROR";
case ERR_APPEXECFWK_INSTALLD_GET_PROXY_ERROR:

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 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 "on_permission_changed_callback_host.h"
#include "ipc_types.h"
#include "string_ex.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
OnPermissionChangedCallbackHost::OnPermissionChangedCallbackHost()
{
APP_LOGI("create on permission changed host instance");
}
OnPermissionChangedCallbackHost::~OnPermissionChangedCallbackHost()
{
APP_LOGI("destroy on permission changed host instance");
}
int OnPermissionChangedCallbackHost::OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
APP_LOGD("permission changed host onReceived message, the message code is %{public}u", code);
switch (code) {
case static_cast<uint32_t>(OnPermissionChangedCallback::Message::ON_CHANGED): {
int32_t uid = data.ReadInt32();
OnChanged(uid);
break;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return NO_ERROR;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 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 "on_permission_changed_callback_proxy.h"
#include "ipc_types.h"
#include "parcel.h"
#include "string_ex.h"
#include "appexecfwk_errors.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
OnPermissionChangedCallbackProxy::OnPermissionChangedCallbackProxy(const sptr<IRemoteObject> &object)
: IRemoteProxy<OnPermissionChangedCallback>(object)
{
APP_LOGI("create on permission changed callback proxy instance");
}
OnPermissionChangedCallbackProxy::~OnPermissionChangedCallbackProxy()
{
APP_LOGI("destroy on permission changed callback proxy instance");
}
void OnPermissionChangedCallbackProxy::OnChanged(const int32_t uid)
{
APP_LOGI("on permission changed %{public}d", uid);
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInt32(uid)) {
APP_LOGE("fail to call OnChanged, for write resultCode failed");
return;
}
sptr<IRemoteObject> remote = Remote();
if (!remote) {
APP_LOGE("fail to call OnChanged, for Remote() is nullptr");
return;
}
int32_t ret = remote->SendRequest(
static_cast<int32_t>(OnPermissionChangedCallback::Message::ON_CHANGED), data, reply, option);
if (ret != NO_ERROR) {
APP_LOGW("fail to call OnChanged, for transact is failed, error code is: %{public}d", ret);
}
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -48,6 +48,7 @@ const std::string MSG_ERR_INSTALL_ENTRY_ALREADY_EXIST = "[MSG_ERR_INSTALL_ENTRY_
const std::string MSG_ERR_INSTALL_STATE_ERROR = "[MSG_ERR_INSTALL_STATE_ERROR]";
const std::string MSG_ERR_INSTALL_FILE_PATH_INVALID = "[MSG_ERR_INSTALL_FILE_PATH_INVALID]";
const std::string MSG_ERR_INSTALL_INVALID_BUNDLE_FILE = "[ERR_INSTALL_INVALID_BUNDLE_FILE]";
const std::string MSG_ERR_INSTALL_INVALID_HAP_SIZE = "[ERR_INSTALL_INVALID_HAP_SIZE]";
const std::string MSG_ERR_INSTALL_GENERATE_UID_ERROR = "[ERR_INSTALL_GENERATE_UID_ERROR]";
const std::string MSG_ERR_INSTALL_INSTALLD_SERVICE_ERROR = "[ERR_INSTALL_INSTALLD_SERVICE_ERROR]";
const std::string MSG_ERR_INSTALL_BUNDLE_MGR_SERVICE_ERROR = "[ERR_INSTALL_BUNDLE_MGR_SERVICE_ERROR]";
@ -61,6 +62,7 @@ const std::string MSG_ERR_INSTALL_PARSE_BAD_PROFILE = "[ERR_INSTALL_PARSE_BAD_PR
const std::string MSG_ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR = "[ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR]";
const std::string MSG_ERR_INSTALL_PARSE_PROFILE_MISSING_PROP = "[ERR_INSTALL_PARSE_PROFILE_MISSING_PROP]";
const std::string MSG_ERR_INSTALL_PARSE_PERMISSION_ERROR = "[ERR_INSTALL_PARSE_PERMISSION_ERROR]";
const std::string MSG_ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR = "[ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR]";
const std::string MSG_ERR_INSTALLD_CLEAN_DIR_FAILED = "[MSG_ERR_INSTALLD_CLEAN_DIR_FAILED]";
const std::string MSG_ERR_INSTALLD_RNAME_DIR_FAILED = "[MSG_ERR_INSTALLD_RNAME_DIR_FAILED]";
@ -110,6 +112,8 @@ const std::map<int32_t, struct ReceivedResult> MAP_RECEIVED_RESULTS{
{IStatusReceiver::ERR_INSTALL_INVALID_HAP_NAME, MSG_ERR_INSTALL_INVALID_HAP_NAME}},
{ERR_APPEXECFWK_INSTALL_INVALID_BUNDLE_FILE,
{IStatusReceiver::ERR_INSTALL_INVALID_BUNDLE_FILE, MSG_ERR_INSTALL_INVALID_BUNDLE_FILE}},
{ERR_APPEXECFWK_INSTALL_INVALID_HAP_SIZE,
{IStatusReceiver::ERR_INSTALL_INVALID_HAP_SIZE, MSG_ERR_INSTALL_INVALID_HAP_SIZE}},
{ERR_APPEXECFWK_INSTALL_GENERATE_UID_ERROR,
{IStatusReceiver::ERR_INSTALL_GENERATE_UID_ERROR, MSG_ERR_INSTALL_GENERATE_UID_ERROR}},
{ERR_APPEXECFWK_INSTALL_INSTALLD_SERVICE_ERROR,
@ -134,6 +138,8 @@ const std::map<int32_t, struct ReceivedResult> MAP_RECEIVED_RESULTS{
{IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_MISSING_PROP, MSG_ERR_INSTALL_PARSE_PROFILE_MISSING_PROP}},
{ERR_APPEXECFWK_PARSE_PERMISSION_ERROR,
{IStatusReceiver::ERR_INSTALL_PARSE_PERMISSION_ERROR, MSG_ERR_INSTALL_PARSE_PERMISSION_ERROR}},
{ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR,
{IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR, MSG_ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR}},
{ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED,
{IStatusReceiver::ERR_INSTALLD_CLEAN_DIR_FAILED, MSG_ERR_INSTALLD_CLEAN_DIR_FAILED}},

View File

@ -0,0 +1,70 @@
# Copyright (c) 2021 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.
import("//build/ohos.gni")
SUBSYSTEM_DIR = "//foundation/appexecfwk/standard"
config("appkit_config") {
config("appkit_public_config") {
visibility = [ ":*" ]
include_dirs = []
}
include_dirs = []
}
ohos_shared_library("appkit_dispatcher_td") {
include_dirs = [
"$SUBSYSTEM_DIR/common/log/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/libeventhandler/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/include/dispatcher",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/include/task",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/include/threading",
"$SUBSYSTEM_DIR/kits/appkit/native/app/include/task",
"$SUBSYSTEM_DIR/kits/appkit/native/app/include",
]
configs = [ ":appkit_config" ]
public_configs = [ ":appkit_public_config" ]
sources = [
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/base_task_dispatcher.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/global_task_dispatcher.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/group_impl.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/parallel_task_dispatcher.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/parallel_task_dispatcher_base.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/serial_task_dispatcher.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/spec_task_dispatcher.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/dispatcher/task_dispatcher_context.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/task/barrier_handler.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/task/sync_task.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/task/task.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/threading/default_thread_factory.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/threading/default_worker_pool_config.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/threading/task_executor.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/threading/work_thread.cpp",
"$SUBSYSTEM_DIR/interfaces/innerkits/task_dispatcher/src/threading/worker_pool.cpp",
]
cflags = []
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
deps = [
"$SUBSYSTEM_DIR/common:libappexecfwk_common",
"$SUBSYSTEM_DIR/interfaces/innerkits/appexecfwk_base:appexecfwk_base",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
part_name = "appexecfwk_standard"
}

View File

@ -0,0 +1,188 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_BASE_TASK_DISPATCHER_H
#define OHOS_APP_DISPATCHER_BASE_TASK_DISPATCHER_H
#include <atomic>
#include <memory>
#include "revocable.h"
#include "runnable.h"
#include "task.h"
#include "group.h"
#include "group_impl.h"
#include "task_dispatcher.h"
#include "task_execute_interceptor.h"
namespace OHOS {
namespace AppExecFwk {
/**
*Base implementation for interface of TaskDispatcher.
*/
class BaseTaskDispatcher : public TaskDispatcher {
public:
BaseTaskDispatcher(const std::string &dispatcherName, const TaskPriority priority);
virtual ~BaseTaskDispatcher(){};
/**
* Called when post a task to the TaskDispatcher with waiting Attention: Call
* this function of Specific dispatcher on the corresponding thread will lock.
* @param runnable is the job to execute.
*/
virtual ErrCode SyncDispatch(const std::shared_ptr<Runnable> &runnable) override = 0;
/**
* Called when post a task to the TaskDispatcher without waiting.
*
* @param runnable is the job to execute.
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
virtual std::shared_ptr<Revocable> AsyncDispatch(const std::shared_ptr<Runnable> &runnable) override = 0;
/**
* Called when post a task group to the TaskDispatcher and without waiting.
* @param runnable is the job to execute.
* @param delayMs indicate the delay time to execute.
* @return an interface for revoke the task if it hasn't been invoked.
*/
virtual std::shared_ptr<Revocable> DelayDispatch(
const std::shared_ptr<Runnable> &runnable, long delayMs) override = 0;
/**
* Set a barrier and meanwhile a sync task that execute after all tasks finished.
* @param runnable is the job to execute after barrier.
*/
ErrCode SyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable) override;
/**
* Set a barrier and meanwhile an async task that execute after all tasks finished.
* @param runnable is the job to execute after jobs in group.
*/
ErrCode AsyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable) override;
/**
* Create a group.
* @return a new created group.
*/
std::shared_ptr<Group> CreateDispatchGroup() override;
/**
* Called when post a task to the TaskDispatcher and relates it to a group
* without waiting.
* @param group related by task.
* @param runnable is the job to execute.
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
virtual std::shared_ptr<Revocable> AsyncGroupDispatch(
const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &runnable) override;
/**
* Synchronously waiting all tasks in the group to be done.
* @param group contains a serial of jobs.
* @param timeout is the max waiting time for jobs in group execute, in ms.
* @return true if all jobs in group has finished or false if timeout occurs.
*
*/
bool GroupDispatchWait(const std::shared_ptr<Group> &group, long timeout) override;
/**
* Asynchronously waiting all tasks in the group to be done. |task| will be run after waiting.
*
* @param group contains a serial of jobs.
* @param runnable executes after all jobs in group finished.
*
*/
ErrCode GroupDispatchNotify(
const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &runnable) override;
/**
* Called to dispatch |task| |iterations| times and wait.
*
* @param task is the job to execute multi times.
* @param iterations indicates times the task should be executed.
*
*/
ErrCode ApplyDispatch(const std::shared_ptr<IteratableTask<long>> &task, long iterations) override;
/**
* Gets the priority.
* @return The priority.
*/
TaskPriority GetPriority() const;
/**
* Create span and set HiTraceId for task, and then tracePoint information
* @param task of which the information to tracePoint
* @param isAsyncTask whether the task is async
* @param dispatcherName the name of dispatcher which post the task
* @return valid HiTraceId if set successfully
*
*/
void TracePointBeforePost(std::shared_ptr<Task> &task, bool isAsyncTask, const std::string &dispatcherName) const;
/**
* TracePoint information after post task
*
* @param task of which the information to tracePoint
* @param isAsyncTask whether the task is async
* @param dispatcherName the name of dispatcher which post the task
*
*/
void TracePointAfterPost(std::shared_ptr<Task> &task, bool isAsyncTask, const std::string &dispatcherName) const;
protected:
/**
* Name of dispatcher.
*
*/
std::string dispatcherName_;
TaskPriority taskPriority_;
protected:
/**
* Check for the |task| argument.
*
* @param task The task to check
*
*/
ErrCode Check(const std::shared_ptr<Runnable> &task) const;
/**
* Check for the |group| argument.
*
* @param group The group to check.
* @return GroupImpl
*
*/
std::shared_ptr<GroupImpl> CastToGroupImpl(const std::shared_ptr<Group> &group);
/**
* Gets the task interceptor.
* Subclasses override this function to change the interceptor.
*
* @return The TaskExecuteInterceptor.
*
*/
std::shared_ptr<TaskExecuteInterceptor> GetInterceptor();
private:
static std::atomic<int> SEQUENCE_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_BLOCKING_QUEUE_H
#define OHOS_APPEXECFWK_BLOCKING_QUEUE_H
#include <atomic>
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <queue>
#include "app_log_wrapper.h"
#include "task.h"
#include "task_priority.h"
namespace OHOS {
namespace AppExecFwk {
struct PriorityTaskWrapper {
PriorityTaskWrapper(const TaskPriority &priority, std::shared_ptr<Task> task) : task_(task)
{
switch (priority) {
case TaskPriority::HIGH:
priorityWeight_ = HIGH_PRIORITY_WEIGHT;
break;
case TaskPriority::DEFAULT:
priorityWeight_ = DEFAULT_PRIORITY_WEIGHT;
break;
case TaskPriority::LOW:
priorityWeight_ = LOW_PRIORITY_WEIGHT;
break;
default:
priorityWeight_ = DEFAULT_PRIORITY_WEIGHT;
break;
}
}
PriorityTaskWrapper() = delete;
~PriorityTaskWrapper(){};
int priorityWeight_;
std::shared_ptr<Task> task_;
static constexpr int HIGH_PRIORITY_WEIGHT = 2;
static constexpr int DEFAULT_PRIORITY_WEIGHT = 1;
static constexpr int LOW_PRIORITY_WEIGHT = 0;
};
struct CompareTaskPriority {
bool operator()(const std::shared_ptr<PriorityTaskWrapper> &wrapper1,
const std::shared_ptr<PriorityTaskWrapper> &wrapper2) const
{
return wrapper1->priorityWeight_ < wrapper2->priorityWeight_;
}
};
class BlockingQueue {
public:
BlockingQueue() : mutex_(), empty_(), stopFlag_(false){};
~BlockingQueue(){};
bool Offer(const std::shared_ptr<PriorityTaskWrapper> &task)
{
std::unique_lock<std::mutex> lock(mutex_);
queue_.push(task);
empty_.notify_all();
return true;
}
std::shared_ptr<PriorityTaskWrapper> Take()
{
std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty() && !stopFlag_) {
APP_LOGD("BlockingQueue::Take empty_wait");
empty_.wait(lock);
}
std::shared_ptr<PriorityTaskWrapper> front = nullptr;
if (!queue_.empty()) {
front = queue_.top();
queue_.pop();
}
return front;
}
std::shared_ptr<PriorityTaskWrapper> Poll(long deleyedMs)
{
auto const timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(deleyedMs);
std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty() && !stopFlag_) {
if (empty_.wait_until(lock, timeout) == std::cv_status::timeout) {
APP_LOGD("BlockingQueue::Poll timeout");
break;
}
}
std::shared_ptr<PriorityTaskWrapper> front = nullptr;
if (!queue_.empty()) {
front = queue_.top();
queue_.pop();
}
return front;
}
size_t Size()
{
std::lock_guard<std::mutex> lock(mutex_);
return queue_.size();
}
bool Empty()
{
std::unique_lock<std::mutex> lock(mutex_);
return queue_.empty();
}
void Stop()
{
std::unique_lock<std::mutex> lock(mutex_);
stopFlag_.store(true);
empty_.notify_all();
}
BlockingQueue(const BlockingQueue &) = delete;
BlockingQueue &operator=(const BlockingQueue &) = delete;
private:
std::mutex mutex_;
std::condition_variable empty_;
std::priority_queue<std::shared_ptr<PriorityTaskWrapper>, std::deque<std::shared_ptr<PriorityTaskWrapper>>,
CompareTaskPriority>
queue_;
std::atomic<bool> stopFlag_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_GLOBAL_TASK_DISPATCHER_H
#define FOUNDATION_APPEXECFWK_OHOS_GLOBAL_TASK_DISPATCHER_H
#include <string>
#include "parallel_task_dispatcher_base.h"
#include "task_executor.h"
#include "task_priority.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Dispatcher for global thread model.
*
*
*/
class GlobalTaskDispatcher : public ParallelTaskDispatcherBase {
private:
static std::string DISPATCHER_NAME_;
public:
GlobalTaskDispatcher(TaskPriority priority, std::shared_ptr<TaskExecutor> &executor);
~GlobalTaskDispatcher(){};
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_GROUP_IMPL_H
#define OHOS_APP_DISPATCHER_GROUP_IMPL_H
#include <atomic>
#include <deque>
#include <mutex>
#include <condition_variable>
#include "group.h"
#include "runnable.h"
namespace OHOS {
namespace AppExecFwk {
/**
* A group used to associated with tasks.
*/
class GroupImpl : public Group {
public:
GroupImpl();
/**
* Wait all tasks associated to this group to be done.
* @param timeout is the max waiting time for jobs in group execute, in ms.
* @return true if successfully wait.
*/
bool AwaitAllTasks(long timeout);
/**
* Associates a task to this group.
*/
void Associate();
/**
* Notify group that a task is done or canceled.
*/
void NotifyTaskDone();
/**
* Adds the |notification| to notification list.
* If all tasks are already done, |notification| will immediately be called on current thread.
* Attention: If tasks are added just this time, it may not be considered.
* @param notification Called when all tasks done.
*/
bool AddNotification(const std::shared_ptr<Runnable> &notification);
private:
const static int MAX_TASK = 1000;
std::atomic<int> count_;
std::deque<std::shared_ptr<Runnable>> notifications_;
std::mutex dataMutex_;
std::condition_variable condition_;
private:
/**
* Notify all tasks and remove from queue.
* Attention: Notifications added after all tasks done is not guaranteed.
*/
void DrainNotifications();
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_PARALLEL_TASK_DISPATCHER_H
#define FOUNDATION_APPEXECFWK_OHOS_PARALLEL_TASK_DISPATCHER_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <assert.h>
#include "parallel_task_dispatcher_base.h"
#include "runnable.h"
#include "sync_task.h"
#include "task_priority.h"
#include "task_execute_interceptor.h"
#include "task_executor.h"
#include "barrier_handler.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Customed parallel TaskDispatcher which means it can be created multi times.
*
*
*/
class ParallelTaskDispatcher : public ParallelTaskDispatcherBase {
public:
// ParallelTaskDispatcher();
ParallelTaskDispatcher(const std::string &name, TaskPriority priority, std::shared_ptr<TaskExecutor> &executor);
~ParallelTaskDispatcher(){};
/**
* Set a barrier and meanwhile a sync task that execute after all tasks finished.
*
* @param runnable is the job to execute after barrier.
* @throws NullPointerException if |task| is null.
*
*/
ErrCode SyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable);
/**
* Set a barrier and meanwhile an async task that execute after all tasks finished.
*
* @param runnable is the job to execute after jobs in group.
* @throws NullPointerException if |task| is null.
*
*/
ErrCode AsyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable);
protected:
std::shared_ptr<TaskExecuteInterceptor> GetInterceptor();
private:
static const std::string DISPATCHER_TAG;
static const std::string ASYNC_DISPATCHER_BARRIER_TAG;
static const std::string SYNC_DISPATCHER_BARRIER_TAG;
std::shared_ptr<BarrierHandler> barrierHandler_ = nullptr;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_PARALLEL_TASK_DISPATCHER_BASE_H
#define FOUNDATION_APPEXECFWK_OHOS_PARALLEL_TASK_DISPATCHER_BASE_H
#include <assert.h>
#include <list>
#include <iostream>
#include <string>
#include <vector>
#include "base_task_dispatcher.h"
#include "group.h"
#include "revocable.h"
#include "runnable.h"
#include "sync_task.h"
#include "task.h"
#include "task_priority.h"
#include "task_executor.h"
#include "task_execute_interceptor.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Base implementation for parallel TaskDispatcher
*
*
*/
class ParallelTaskDispatcherBase : public BaseTaskDispatcher,
public std::enable_shared_from_this<ParallelTaskDispatcherBase> {
public:
// ParallelTaskDispatcherBase();
ParallelTaskDispatcherBase(
TaskPriority taskPriority, std::shared_ptr<TaskExecutor> &executor, const std::string &dispatcherName);
virtual ~ParallelTaskDispatcherBase() = default;
/**
* Called when post a task to the TaskDispatcher with waiting Attention: Call
* this function of Specific dispatcher on the corresponding thread will lock.
*
* @param runnable is the job to execute
*
*/
ErrCode SyncDispatch(const std::shared_ptr<Runnable> &runnable) override;
/**
* Called when post a task to the TaskDispatcher without waiting
*
* @param runnable is the job to execute
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> AsyncDispatch(const std::shared_ptr<Runnable> &runnable) override;
/**
* Called when post a task group to the TaskDispatcher and without waiting
*
* @param runnable is the job to execute
* @param delayMs indicate the delay time to execute
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> DelayDispatch(const std::shared_ptr<Runnable> &runnable, long delayMs) override;
/**
* Called when post a task to the TaskDispatcher and relates it to a group
* without waiting.
*
* @param group related by task.
* @param runnable is the job to execute.
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> AsyncGroupDispatch(
const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &runnable) override;
protected:
virtual std::shared_ptr<TaskExecuteInterceptor> GetInterceptor();
std::shared_ptr<TaskExecutor> executor_ = nullptr;
private:
static std::string DISPATCHER_TAG;
static std::string ASYNC_DISPATCHER_TAG;
static std::string SYNC_DISPATCHER_TAG;
static std::string DELAY_DISPATCHER_TAG;
static std::string ASYNC_GROUP_DISPATCHER_TAG;
ErrCode InterceptedExecute(std::shared_ptr<Task> &task);
class MyTaskListener : public TaskListener {
private:
std::function<void()> callback_;
public:
void OnChanged(const TaskStage &stage)
{
if (stage.IsDone()) {
APP_LOGD("task done.");
callback_();
}
}
// set callback function
void Callback(const std::function<void()> &callbackFunction)
{
callback_ = std::move(callbackFunction);
}
};
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_SERIAL_TASK_DISPATCHER_H
#define OHOS_APP_DISPATCHER_SERIAL_TASK_DISPATCHER_H
#include <string>
#include "base_task_dispatcher.h"
#include "task.h"
#include "sync_task.h"
#include "task_executor.h"
#include "task_priority.h"
#include "revocable.h"
#include "task_listener.h"
#include "concurrent_queue.h"
#include "runnable.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Dispatcher for serial thread model.
*
*
*/
class SerialTaskDispatcher : public BaseTaskDispatcher, public std::enable_shared_from_this<SerialTaskDispatcher> {
private:
static std::string DISPATCHER_TAG;
static std::string ASYNC_DISPATCHER_TAG;
static std::string SYNC_DISPATCHER_TAG;
static std::string DELAY_DISPATCHER_TAG;
std::atomic<bool> running_;
ConcurrentQueue<std::shared_ptr<Task>> workingTasks_;
std::shared_ptr<TaskExecutor> executor_;
std::mutex mutex_;
private:
ErrCode OnNewTaskIn(std::shared_ptr<Task> &task);
ErrCode Prepare(std::shared_ptr<Task> &task);
/**
* Callback for task when finish.
*
*/
void OnTaskDone();
bool Schedule();
/**
* Do task in turn, until the task queue is empty.
*
* @param isExhausted is an inaccurate judge indicate that the workingTasks is empty. If true, do double-check.
* @return true if has work remain to do else false.
*
*/
bool DoNext(bool isExhausted);
void DoWork(std::shared_ptr<Task> &task);
public:
/**
* Constructs a serial TaskDispatcher using priority.
*
* @param dispatcherName is the identity for dispatcher. It's for debug purpose.
* @param priority is the priority for tasks dispatched by this Dispatcher.
* @param executor contains thread pool(s) for executing tasks concurrently.
*
*/
SerialTaskDispatcher(
const std::string &dispatcherName, const TaskPriority priority, const std::shared_ptr<TaskExecutor> &executor);
~SerialTaskDispatcher(){};
/**
* Gets waiting tasks count of SerialTaskDispatcher.
*
* @return The waiting tasks count of SerialTaskDispatcher.
*
*/
int GetWorkingTasksSize();
/**
* Gets name of SerialTaskDispatcher.
*
* @return The name of SerialTaskDispatcher.
*
*/
std::string GetDispatcherName();
/**
* Called when post a task to the TaskDispatcher with waiting Attention: Call
* this function of Specific dispatcher on the corresponding thread will lock.
*
* @param runnable is the job to execute
*
*/
ErrCode SyncDispatch(const std::shared_ptr<Runnable> &runnable);
/**
* Called when post a task to the TaskDispatcher without waiting
*
* @param runnable is the job to execute
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> AsyncDispatch(const std::shared_ptr<Runnable> &runnable);
/**
* Called when post a task group to the TaskDispatcher and without waiting
*
* @param runnable is the job to execute
* @param delayMs indicate the delay time to execute
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> DelayDispatch(const std::shared_ptr<Runnable> &runnable, long delayMs);
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_SPEC_DISPATCHER_CONFIG_H
#define OHOS_APP_DISPATCHER_SPEC_DISPATCHER_CONFIG_H
#include <string>
#include "task_priority.h"
namespace OHOS {
namespace AppExecFwk {
class SpecDispatcherConfig {
public:
static constexpr const char *MAIN = "DispatcherMain";
static constexpr const char *UI = "DispatcherUI";
public:
SpecDispatcherConfig(std::string name, TaskPriority priority)
{
name_ = name;
priority_ = priority;
}
std::string GetName()
{
return name_;
}
TaskPriority GetPriority()
{
return priority_;
}
private:
std::string name_;
TaskPriority priority_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_SPEC_TASK_DISPATCHER_H
#define OHOS_APP_DISPATCHER_SPEC_TASK_DISPATCHER_H
#include <string>
#include "base_task_dispatcher.h"
#include "task.h"
#include "sync_task.h"
#include "revocable.h"
#include "runnable.h"
#include "task/task_dispatcher_handler.h"
#include "event_runner.h"
#include "spec_dispatcher_config.h"
namespace OHOS {
namespace AppExecFwk {
class EventRunner;
/**
* Dispatcher for specific thread model like UI / Main / IO and so on.
*
*
*/
class SpecTaskDispatcher : public BaseTaskDispatcher, public std::enable_shared_from_this<SpecTaskDispatcher> {
public:
/**
* constructor for special task dispatchers
*
* @param config which is the config of this dispatcher
* @param looper task looper
*
*/
SpecTaskDispatcher(std::shared_ptr<SpecDispatcherConfig> config, std::shared_ptr<EventRunner> runner);
~SpecTaskDispatcher(){};
/**
* Called when post a task to the TaskDispatcher with waiting Attention: Call
* this function of Specific dispatcher on the corresponding thread will lock.
*
* @param task is the job to execute
*
*/
ErrCode SyncDispatch(const std::shared_ptr<Runnable> &runnable);
/**
* Called when post a task to the TaskDispatcher without waiting
*
* @param task is the job to execute
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> AsyncDispatch(const std::shared_ptr<Runnable> &runnable);
/**
* Called when post a task group to the TaskDispatcher and without waiting
*
* @param task is the job to execute
* @param delayMs indicate the delay time in milliseconds to execute
* @return an interface for revoke the task if it hasn't been invoked.
*
*/
std::shared_ptr<Revocable> DelayDispatch(const std::shared_ptr<Runnable> &runnable, long delayMs);
private:
static std::string DISPATCHER_TAG;
static std::string ASYNC_DISPATCHER_TAG;
static std::string SYNC_DISPATCHER_TAG;
static std::string DELAY_DISPATCHER_TAG;
std::shared_ptr<TaskDispatcherHandler> handler_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_TASK_DISPATCHER_CONTEXT_H
#define FOUNDATION_APPEXECFWK_OHOS_TASK_DISPATCHER_CONTEXT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <assert.h>
#include <map>
#include "default_worker_pool_config.h"
#include "global_task_dispatcher.h"
#include "parallel_task_dispatcher.h"
#include "serial_task_dispatcher.h"
#include "task_dispatcher.h"
#include "task_executor.h"
#include "task_priority.h"
#include "worker_pool_config.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Dispatcher management for all kinds dispatchers and executor.
*
*
*/
class TaskDispatcherContext {
public:
/**
* Constructs the object.
*
*/
TaskDispatcherContext();
/**
* Constructs the object with parameter executor.
*
* @param executor the TaskExecutor to set.
*
*/
TaskDispatcherContext(const std::shared_ptr<TaskExecutor> &executor);
~TaskDispatcherContext();
/**
* Gets the worker pool configuration.
*
* @return The worker pool configuration.
*
*/
std::shared_ptr<WorkerPoolConfig> GetWorkerPoolConfig() const;
/**
* Gets WorkerThread information in WorkerPool.
*
* @return The WorkerThread information in WorkerPool.
*
*/
std::map<std::string, long> GetWorkerThreadsInfo() const;
/**
* Gets the serialDispatchers.
*
* @return The serialDispatchers.
*
*/
std::map<std::shared_ptr<SerialTaskDispatcher>, std::string> GetSerialDispatchers() const;
/**
* Gets waiting tasks count of TaskExecutor.
*
* @return The waiting tasks count of TaskExecutor.
*
*/
int GetWaitingTasksCount() const;
/**
* Gets finished tasks count of TaskExecutor.
*
* @return The finished tasks count of TaskExecutor.
*
*/
long GetTaskCounter() const;
/**
* Creates a serial dispatcher.
*
* @param name The dispatcher name
* @param priority The priority of tasks
*
* @return a new object of SerialTaskDispatcher
*
*/
std::shared_ptr<SerialTaskDispatcher> CreateSerialDispatcher(const std::string &name, TaskPriority priority);
/**
* Creates a parallel dispatcher.
*
* @param name The dispatcher name
* @param priority The priority of tasks
*
* @return a new object of ParallelTaskDispatcher
*
*/
std::shared_ptr<ParallelTaskDispatcher> CreateParallelDispatcher(const std::string &name, TaskPriority priority);
/**
* Gets the global task dispatcher.
*
* @param priority The priority
*
* @return A global task dispatcher which cannot be null.
*
*/
std::shared_ptr<TaskDispatcher> GetGlobalTaskDispatcher(TaskPriority priority);
/**
* Shutdown all about task dispatcher.
*
* @param force Indicate whether force close.
*
*/
ErrCode Shutdown(bool force);
private:
static constexpr int HIGH_PRIORITY_INDEX = 0;
static constexpr int DEFAULT_PRIORITY_INDEX = 1;
static constexpr int LOW_PRIORITY_INDEX = 2;
static constexpr int PRIORITY_COUNT = 3;
mutable std::mutex mtx_;
std::map<std::shared_ptr<SerialTaskDispatcher>, std::string> serialDispatchers_;
std::vector<std::shared_ptr<TaskDispatcher>> globalDispatchers_;
std::shared_ptr<WorkerPoolConfig> config_ = nullptr;
std::shared_ptr<TaskExecutor> executor_ = nullptr;
private:
int MapPriorityIndex(TaskPriority priority) const;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_BARRIER_HANDLER_H
#define OHOS_APP_DISPATCHER_BARRIER_HANDLER_H
#include <set>
#include "appexecfwk_errors.h"
#include "task.h"
#include "task_listener.h"
#include "task_executor.h"
#include "task_execute_interceptor.h"
#include "task_stage.h"
namespace OHOS {
namespace AppExecFwk {
class BarrierHandler : public TaskExecuteInterceptor {
public:
BarrierHandler(const std::shared_ptr<TaskExecutor> &executor);
/**
* Intercept executing a task.
*/
ErrCode Intercept(std::shared_ptr<Task> &task) override;
/**
* Adds a task with barrier semantics.
*/
ErrCode AddBarrier(std::shared_ptr<Task> &barrierTask);
private:
ErrCode ListenToTask(std::shared_ptr<Task> &task);
void OnTaskDone(std::shared_ptr<Task> &task);
bool AddTaskAfterBarrier(std::shared_ptr<Task> &task);
bool HasTask(const std::set<std::shared_ptr<Task>> &tasks);
std::set<std::shared_ptr<Task>> CreateTaskSet(std::shared_ptr<Task> &firstTask);
private:
class BarrierPair {
public:
std::set<std::shared_ptr<Task>> tasks_;
std::shared_ptr<Task> barrier_;
BarrierPair(const std::set<std::shared_ptr<Task>> &tasks, const std::shared_ptr<Task> &barrier)
{
tasks_ = tasks;
barrier_ = barrier;
};
};
class MyTaskListener : public TaskListener {
private:
std::function<void()> callback_;
public:
void OnChanged(const TaskStage &stage)
{
if (stage.IsDone()) {
APP_LOGI("task done.");
callback_();
}
};
// set callback function
void Callback(const std::function<void()> &callbackFunction)
{
callback_ = std::move(callbackFunction);
};
};
std::mutex barrierLock_;
std::shared_ptr<TaskExecutor> executor_;
std::deque<std::shared_ptr<BarrierPair>> barrierQueue_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_TASK_SYNC_TASK_H
#define OHOS_APP_DISPATCHER_TASK_SYNC_TASK_H
#include <condition_variable>
#include <mutex>
#include "runnable.h"
#include "task_priority.h"
#include "task.h"
#include "app_log_wrapper.h"
#include "base_task_dispatcher.h"
namespace OHOS {
namespace AppExecFwk {
/**
* SyncTask is the synchronized task which provide synchronized method.
*/
class SyncTask final : public Task {
public:
/**
*@brief Constructs the object.
*@param runnable The task.
*@param priority The priority
*@return -
*/
SyncTask(const std::shared_ptr<Runnable> &runnable, TaskPriority priority,
const std::shared_ptr<BaseTaskDispatcher> &baseTaskDispatcher);
/**
*@brief invoke the function to execute the task
*@param -
*@return void
*/
void Run() override;
/**
*@brief wait the task to run completely
*@param -
*@return void
*/
void WaitTask();
private:
std::atomic<bool> executed_;
std::mutex mutex_;
std::condition_variable condition_variable_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_TASK_H
#define OHOS_APP_DISPATCHER_TASK_H
#include <atomic>
#include <deque>
#include <memory>
#include <thread>
#include "concurrent_queue.h"
#include "revocable.h"
#include "runnable.h"
#include "task_listener.h"
#include "task_priority.h"
#include "task_stage.h"
namespace OHOS {
namespace AppExecFwk {
class BaseTaskDispatcher;
class Task : public Revocable {
public:
/**
* @brief Constructs the object.
* @param runnable The user task wrapped in.
* @param priority The priority
* @return -
*/
Task(const std::shared_ptr<Runnable> &runnable, const TaskPriority priority,
const std::shared_ptr<BaseTaskDispatcher> &baseTaskDispatcher);
virtual ~Task();
/**
*@brief invoke the function to execute the task
*@param -
*@return void
*/
virtual void Run();
/**
* @brief Gets the priority.
* @param -
* @return The priority.
*/
TaskPriority GetPriority() const;
/**
* @brief Sets the sequence.
* @param -
* @param sequence The sequence
* @return void
*/
void SetSequence(long sequence);
/**
*@brief Gets the sequence.
*@param -
*@return The sequence.
*/
long GetSequence() const;
/**
*@brief Revoke this task if hasn't run.
*@param -
*@return true if set revoked or already revoked. False if the task has start executing.
*/
bool Revoke() override;
/**
*@brief Adds a task listener.
*@param listener The listener
*@return void
*/
void AddTaskListener(const std::shared_ptr<TaskListener> &listener);
/**
*@brief Called when task is about to run.
*@param -
*@return void
*/
void BeforeTaskExecute();
/**
*@brief Called when task is done.
*@param -
*@return void
*/
void AfterTaskExecute();
/**
*@brief Called when task is canceled.
*@param -
*@return void
*/
void OnTaskCanceled();
/**
*@brief Save traceId for using on task running thread.
*@param hiTraceId The traceId.
*@return void
*/
// void SetTaskHiTraceId(HiTraceId &hiTraceId);
bool operator==(std::shared_ptr<Task> &rec) const;
protected:
/**
* The user task wrapped in.
*/
std::shared_ptr<Runnable> runnable_;
private:
using RevokeResult = enum {
// Maybe already run.
FAIL,
// Convert |revoked| flag from false to true.
SUCCESS,
// The |revoked| flag is already set to true.
ALREADY_REVOKED
};
/**
*@brief Return true if not executed or revoked, and if not executed or revoked, ensure |EXECUTED| to be set.
*@param -
*@return bool
*/
bool EnterExecute();
RevokeResult SetRevoked();
void ConcurrentQueueStatusUpdate(const TaskStage::TASKSTAGE taskstage);
private:
const static int EXECUTED = (1 << 0);
const static int REVOKED = (1 << 1);
long sequence_;
std::atomic<int> state_;
TaskPriority priority_;
std::shared_ptr<Revocable> revocable_ = nullptr;
ConcurrentQueue<std::shared_ptr<TaskListener>> taskListeners_;
std::shared_ptr<BaseTaskDispatcher> baseTaskDispatcher_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_APP_DISPATCHER_TASK_H

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_TASK_HANDLER_LIBEVENT_ADAPTER_H
#define OHOS_APP_DISPATCHER_TASK_HANDLER_LIBEVENT_ADAPTER_H
#include <string>
#include "task_dispatcher_handler.h"
#include "runnable.h"
#include "event_runner.h"
#include "event_handler.h"
#include "event_queue.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Dispatcher for serial thread model.
*
*
*/
class TaskHandlerLibeventAdapter final : public EventHandler, public TaskDispatcherHandler {
public:
TaskHandlerLibeventAdapter(const std::shared_ptr<EventRunner> &eventRunner) : EventHandler(eventRunner)
{}
virtual ~TaskHandlerLibeventAdapter(){};
bool Dispatch(const std::shared_ptr<Runnable> &runnable) override
{
return EventHandler::PostTask(*(runnable.get()), EventQueue::Priority::HIGH);
}
bool Dispatch(const std::shared_ptr<Runnable> &runnable, long delayMs) override
{
return EventHandler::PostTask(*(runnable.get()), delayMs, EventQueue::Priority::HIGH);
}
bool DispatchSync(const std::shared_ptr<Runnable> &runnable) override
{
return EventHandler::PostSyncTask(*(runnable.get()), EventQueue::Priority::HIGH);
}
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_TASK_TASK_LISTENER_H
#define OHOS_APP_DISPATCHER_TASK_TASK_LISTENER_H
#include "task_stage.h"
namespace OHOS {
namespace AppExecFwk {
/**
* Listen to events of task execution.
*/
class TaskListener {
public:
virtual ~TaskListener(){};
/**
*@brief Called when task stage changed.
*@param stage The stage
*@return void
*/
virtual void OnChanged(const TaskStage &stage) = 0;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_TASK_TASK_STAGE_H
#define OHOS_APP_DISPATCHER_TASK_TASK_STAGE_H
namespace OHOS {
namespace AppExecFwk {
/**
* Enumeration for task execute stage.
* Attention: |REVOKED| is conflict with |AFTER_EXECUTE| and |BEFORE_EXECUTE|, which means,
* once |REVOKED|, the other stage will not be notified. So use |isDone| for judging.
*/
class TaskStage {
public:
TaskStage() : index_(0)
{}
TaskStage(int index)
{
index_ = index;
}
enum TASKSTAGE { BEFORE_EXECUTE = 0, AFTER_EXECUTE = 1, REVOKED = 2 };
/**
* Gets the index.
* @return The index.
*/
int GetIndex() const
{
return index_;
}
/**
* Determines if done.
* @return True if the task has been finished(maybe canceled). False if it's going to execute.
*/
bool IsDone() const
{
return ((index_ == AFTER_EXECUTE) || (index_ == REVOKED));
}
private:
int index_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_CONCURRENT_QUEUE_H
#define OHOS_APPEXECFWK_CONCURRENT_QUEUE_H
#include <condition_variable>
#include <queue>
#include <vector>
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
template <typename T>
class ConcurrentQueue {
public:
ConcurrentQueue() : empty_()
{}
/**
* get data without block
* @param task
* @return true
*/
bool Offer(const T &task)
{
std::unique_lock<std::mutex> lock(mutex_);
queue_.push_back(task);
empty_.notify_all();
return true;
}
/**
* get data with block
* @param task
* @return data
*/
T Take()
{
std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty()) {
APP_LOGD("ConcurrentQueue::Take blocked");
empty_.wait(lock);
}
T front(queue_.front());
queue_.pop_front();
return front;
}
T Poll()
{
std::unique_lock<std::mutex> lock(mutex_);
if (queue_.empty()) {
APP_LOGD("ConcurrentQueue::Poll empty");
return nullptr;
}
T front(queue_.front());
queue_.pop_front();
return front;
}
size_t Size()
{
return queue_.size();
}
size_t Empty()
{
return queue_.empty();
}
auto Begin()
{
return queue_.begin();
}
auto End()
{
return queue_.end();
}
void clear()
{
std::unique_lock<std::mutex> lock(mutex_);
queue_.clear();
}
ConcurrentQueue(const ConcurrentQueue &) = delete;
ConcurrentQueue &operator=(const ConcurrentQueue &) = delete;
private:
mutable std::mutex mutex_;
std::condition_variable empty_;
std::deque<T> queue_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_THREADING_DEFAULT_THREAD_FACTORY_H
#define OHOS_APP_DISPATCHER_THREADING_DEFAULT_THREAD_FACTORY_H
#include <atomic>
#include "thread_factory.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
/**
* DefaultThreadFactory is a default thread producer.
*
*/
class DefaultThreadFactory : public ThreadFactory {
public:
DefaultThreadFactory();
virtual ~DefaultThreadFactory()
{}
virtual std::shared_ptr<Thread> Create() override;
private:
std::atomic_int index_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_DEFAULT_WORKER_POOL_CONFIG_H
#define OHOS_APPEXECFWK_DEFAULT_WORKER_POOL_CONFIG_H
#include "worker_pool_config.h"
namespace OHOS {
namespace AppExecFwk {
class DefaultWorkerPoolConfig final : public WorkerPoolConfig {
private:
static constexpr int DEFAULT_MAX_THREAD_COUNT = 32;
static constexpr int DEFAULT_CORE_THREAD_COUNT = 16;
static constexpr long DEFAULT_KEEP_ALIVE_TIME = 50;
public:
DefaultWorkerPoolConfig() = default;
virtual ~DefaultWorkerPoolConfig() = default;
int GetMaxThreadCount(void) const override;
int GetCoreThreadCount(void) const override;
long GetKeepAliveTime(void) const override;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_DELAY_EXECUTE_SERVICE_H
#define OHOS_APPEXECFWK_DELAY_EXECUTE_SERVICE_H
#include "runnable.h"
namespace OHOS {
namespace AppExecFwk {
class DelayExecuteService {
public:
virtual bool DelayExecute(const Runnable &runnable, long delayMs) = 0;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_DELAY_QUEUE_H
#define OHOS_APPEXECFWK_DELAY_QUEUE_H
#include <atomic>
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <queue>
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
struct DelayTaskWrapper {
DelayTaskWrapper(long delayMs, std::function<void()> runnable) : runnable_(std::move(runnable))
{
auto now = std::chrono::high_resolution_clock::now();
startTime_ = now + std::chrono::milliseconds(delayMs);
}
DelayTaskWrapper() = delete;
~DelayTaskWrapper(){};
std::chrono::high_resolution_clock::time_point startTime_;
std::function<void()> runnable_;
};
struct CompareTaskDelayMs {
bool operator()(
const std::shared_ptr<DelayTaskWrapper> &other1, const std::shared_ptr<DelayTaskWrapper> &other2) const
{
return other1->startTime_ > other2->startTime_;
}
};
class DelayQueue {
public:
DelayQueue() : stopFlag_(false){};
~DelayQueue(){};
bool Offer(const std::shared_ptr<DelayTaskWrapper> &task)
{
std::unique_lock<std::mutex> lock(mutex_);
taskQueue_.push(task);
emptyWait_.notify_all();
return true;
}
std::shared_ptr<DelayTaskWrapper> Take()
{
while (true) {
std::unique_lock<std::mutex> lock(mutex_);
while (taskQueue_.empty() && !stopFlag_) {
APP_LOGD("DelayQueue::taskQueue_ is empty");
emptyWait_.wait(lock);
}
if (taskQueue_.empty() && stopFlag_) {
return nullptr;
}
std::shared_ptr<DelayTaskWrapper> front = taskQueue_.top();
auto now = std::chrono::high_resolution_clock::now();
while (now < front->startTime_) {
emptyWait_.wait_until(lock, front->startTime_);
now = std::chrono::high_resolution_clock::now();
front = taskQueue_.top();
}
std::shared_ptr<DelayTaskWrapper> check = taskQueue_.top();
if (check->startTime_ == front->startTime_) {
taskQueue_.pop();
return front;
}
}
}
size_t Size()
{
std::unique_lock<std::mutex> lock(mutex_);
return taskQueue_.size();
}
bool Empty()
{
std::unique_lock<std::mutex> lock(mutex_);
return taskQueue_.empty();
}
void Stop()
{
std::unique_lock<std::mutex> lock(mutex_);
stopFlag_.store(true);
emptyWait_.notify_all();
}
DelayQueue(const DelayQueue &) = delete;
DelayQueue &operator=(const DelayQueue &) = delete;
private:
std::mutex mutex_;
std::condition_variable emptyWait_;
std::priority_queue<std::shared_ptr<DelayTaskWrapper>, std::vector<std::shared_ptr<DelayTaskWrapper>>,
CompareTaskDelayMs>
taskQueue_;
std::atomic<bool> stopFlag_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_THREADING_RUNNABLE_H
#define OHOS_APP_DISPATCHER_THREADING_RUNNABLE_H
#include <functional>
namespace OHOS {
namespace AppExecFwk {
using Runnable = std::function<void()>;
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_TASK_TaskExecuteInterceptor_H
#define OHOS_APP_DISPATCHER_TASK_TaskExecuteInterceptor_H
#include "task.h"
#include "appexecfwk_errors.h"
namespace OHOS {
namespace AppExecFwk {
class TaskExecuteInterceptor {
public:
virtual ~TaskExecuteInterceptor(){};
virtual ErrCode Intercept(std::shared_ptr<Task> &task) = 0;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_TASK_EXECUTOR_H
#define OHOS_APPEXECFWK_TASK_EXECUTOR_H
#include <atomic>
#include <mutex>
#include <thread>
#include "appexecfwk_errors.h"
#include "blocking_queue.h"
#include "delay_execute_service.h"
#include "delay_queue.h"
#include "task.h"
#include "work_thread.h"
#include "worker_pool.h"
namespace OHOS {
namespace AppExecFwk {
class TaskExecutor : public WorkerPool,
public DelayExecuteService,
public Delegate,
public std::enable_shared_from_this<TaskExecutor> {
public:
TaskExecutor(const std::shared_ptr<WorkerPoolConfig> &config);
virtual ~TaskExecutor();
void Execute(const std::shared_ptr<Task> &task);
ErrCode DoWorks(const std::shared_ptr<WorkerThread> &worker) override;
void Terminate(bool force);
bool DelayExecute(const Runnable &runnable, long delayMs) override;
int GetPendingTasksSize();
long GetTaskCounter();
protected:
void AfterRun(const std::shared_ptr<Task> &task) override;
void BeforeRun(const std::shared_ptr<Task> &task) override;
private:
std::shared_ptr<Task> GetTask(const std::shared_ptr<WorkerThread> &workerThread);
void TerminateConsumer();
bool EnsureConsumeStarted();
void Consume();
long GetAndIncrement(std::atomic<long> &atomiclong);
long IncrementAndGet(std::atomic<long> &atomiclong);
private:
static std::atomic<long> sequence;
std::shared_ptr<DelayQueue> delayTasks_;
std::shared_ptr<std::thread> consumer_;
std::shared_ptr<BlockingQueue> pendingTasks_;
std::atomic<bool> terminated_;
std::atomic<long> taskCounter_;
std::mutex dataMutex_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_THREADING_THREAD_FACTORY_H
#define OHOS_APP_DISPATCHER_THREADING_THREAD_FACTORY_H
#include "runnable.h"
#include <thread>
#include <memory>
namespace OHOS {
namespace AppExecFwk {
class Thread {
public:
Thread() : thread_name_("Thread_0"), thread_(){};
~Thread() = default;
Thread(const Thread &) = delete;
Thread &operator=(const Thread &) = delete;
public:
std::string thread_name_;
std::shared_ptr<std::thread> thread_;
};
/**
* ThreadFactory is an interface for producing thread.
*
*
*/
class ThreadFactory {
public:
ThreadFactory() = default;
virtual ~ThreadFactory(){};
/**
* Create a new Thread with |task| as the body of thread.
*
* @param task The run body of the thread to create.
*
* @return a new created thread. maybe null.
*
*/
virtual std::shared_ptr<Thread> Create() = 0;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APP_DISPATCHER_THREADING_WORKER_THREAD_H
#define OHOS_APP_DISPATCHER_THREADING_WORKER_THREAD_H
#include <atomic>
#include "thread_factory.h"
#include "task.h"
#include "app_log_wrapper.h"
#include "appexecfwk_errors.h"
namespace OHOS {
namespace AppExecFwk {
class WorkerThread;
/**
* Interface for a work delegate.
*
*/
class Delegate {
public:
/**
* Do works for WorkerThread.
*
* @param worker is the thread-holder.
*
*/
virtual ErrCode DoWorks(const std::shared_ptr<WorkerThread> &worker) = 0;
};
/**
* WorkerThread is a thread with a loop which can execute incoming tasks.
*
*/
class WorkerThread : public std::enable_shared_from_this<WorkerThread> {
public:
/**
* The construct function of the WorkerThread class.
*
* @param delegate delegates run works for this thread.
* @param firstTask if not null, take it as the first task in this thread. It can be null.
* @param factory can create a new thread which had some attributes set.
*/
WorkerThread(const std::shared_ptr<Delegate> &delegate, const std::shared_ptr<Task> &firstTask,
const std::shared_ptr<ThreadFactory> &factory);
virtual ~WorkerThread(){};
void CreateThread();
/**
* Increase the task counter of self.
*
*/
void IncTaskCount(void);
/**
* Gets the thread name.
*
* @return The thread name.
*
*/
std::string GetThreadName(void);
/**
* Get and remove |firstTask| of self.
*
* @return the |firstTask|.
*
*/
std::shared_ptr<Task> PollFirstTask(void);
/**
* Get count of tasks which were done.
*
* @return the count of tasks which were done.
*
*/
long GetTaskCounter(void);
std::shared_ptr<Thread> GetThread(void);
/**
* join thread
*
*/
void Join();
protected:
std::shared_ptr<Thread> thread_;
std::atomic_long task_counter_;
private:
std::shared_ptr<Task> first_task_;
std::shared_ptr<Delegate> delegate_;
std::shared_ptr<ThreadFactory> factory_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_WORKER_POOL_H
#define OHOS_APPEXECFWK_WORKER_POOL_H
#include <atomic>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "app_log_wrapper.h"
#include "runnable.h"
#include "task.h"
#include "thread_factory.h"
#include "worker_pool_config.h"
#include "work_thread.h"
namespace OHOS {
namespace AppExecFwk {
class WorkerPool {
public:
WorkerPool(const std::shared_ptr<WorkerPoolConfig> &config);
virtual ~WorkerPool();
long GetKeepAliveTime(void) const;
int GetCoreThreadCount(void) const;
int GetMaxThreadCount(void) const;
int GetWorkCount(void) const;
std::map<std::string, long> GetWorkerThreadsInfo(void);
bool AddWorker(const std::shared_ptr<Delegate> &delegate, const std::shared_ptr<Task> &task);
void CreateGuardThread();
protected:
void ClosePool(bool interrupt);
void OnWorkerExit(const std::shared_ptr<WorkerThread> &worker, bool isInterrupted);
virtual void AfterRun(const std::shared_ptr<Task> &task);
virtual void BeforeRun(const std::shared_ptr<Task> &task);
void DecrementThread(void);
bool CompareAndDecNum(int expectCount);
private:
bool Init(const std::shared_ptr<WorkerPoolConfig> &config);
bool CheckConfigParams(const std::shared_ptr<WorkerPoolConfig> &config);
bool CheckThreadCount(int maxThreadCount, int coreThreadCount);
bool CheckMaxThreadCount(int maxThreadCount);
bool CheckCoreThreadCount(int coreThreadCount);
void InterruptWorkers(void);
static int GetWorkingThreadNum(int ctl);
static bool IsRunning(int ctl);
static int GetStateFromControl(int ctl);
static int CombineToControl(int state, int count);
void AdvanceStateTo(int target);
bool CompareAndIncThreadNum(int expect);
bool CompareAndDecThreadNum(int expect);
bool CompareAndSet(std::atomic<int> &atomicInt, int left, int right);
private:
static const int THREAD_UPPER_LIMIT;
static const int MAX_THREAD_LOWER_LIMIT;
static const int CORE_THREAD_LOWER_LIMIT;
static const int COUNT_BITS;
static const int CAPACITY;
static const int RUNNING;
static const int CLOSING;
static const int INTERRUPT;
static const int CLEANED;
static const int CLOSED;
int thread_limit_ = 0;
int core_thread_limit_ = 0;
long alive_time_Limit_ = 0;
std::vector<std::shared_ptr<WorkerThread>> pool_;
std::atomic<int> control_;
std::mutex poolLock_;
std::shared_ptr<ThreadFactory> factory_;
std::atomic<bool> initFlag_;
std::vector<std::shared_ptr<WorkerThread>> exitPool_;
std::atomic<bool> stop_;
std::shared_ptr<std::thread> guardThread_;
std::mutex exitPoolLock_;
std::condition_variable exit_;
std::mutex exitGuardLock_;
std::condition_variable exitGuard_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_APPEXECFWK_WORKER_POOL_CONFIG_H
#define OHOS_APPEXECFWK_WORKER_POOL_CONFIG_H
namespace OHOS {
namespace AppExecFwk {
class WorkerPoolConfig {
public:
virtual int GetMaxThreadCount(void) const = 0;
virtual int GetCoreThreadCount(void) const = 0;
virtual long GetKeepAliveTime(void) const = 0;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif

View File

@ -0,0 +1,201 @@
/*
* Copyright (c) 2021 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 "base_task_dispatcher.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
std::atomic<int> BaseTaskDispatcher::SEQUENCE_(0);
BaseTaskDispatcher::BaseTaskDispatcher(const std::string &dispatcherName, const TaskPriority priority)
{
std::string name = dispatcherName;
if (name.size() == 0) {
name = "Dispatcher-" + std::to_string(SEQUENCE_.fetch_add(1, std::memory_order_relaxed));
}
dispatcherName_ = name;
taskPriority_ = priority;
}
ErrCode BaseTaskDispatcher::SyncDispatchBarrier(const std::shared_ptr<Runnable> &task)
{
return SyncDispatch(task);
}
ErrCode BaseTaskDispatcher::AsyncDispatchBarrier(const std::shared_ptr<Runnable> &task)
{
std::shared_ptr<Revocable> revocable = AsyncDispatch(task);
if (revocable != nullptr) {
return ERR_OK;
}
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Group> BaseTaskDispatcher::CreateDispatchGroup()
{
return std::make_shared<GroupImpl>();
}
std::shared_ptr<Revocable> BaseTaskDispatcher::AsyncGroupDispatch(
const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &task)
{
return AsyncDispatch(task);
}
bool BaseTaskDispatcher::GroupDispatchWait(const std::shared_ptr<Group> &group, long timeout)
{
if (group == nullptr) {
APP_LOGE("BaseTaskDispatcher::GroupDispatchWait group is nullptr");
return false;
}
std::shared_ptr<GroupImpl> groupImpl = CastToGroupImpl(group);
if (groupImpl == nullptr) {
APP_LOGE("BaseTaskDispatcher::GroupDispatchWait groupImpl is nullptr");
return false;
}
return groupImpl->AwaitAllTasks(timeout);
}
ErrCode BaseTaskDispatcher::GroupDispatchNotify(
const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &task)
{
bool flag = true;
if (group == nullptr) {
APP_LOGE("group cannot be null.");
flag = false;
}
if (task == nullptr) {
APP_LOGE("task cannot be null");
flag = false;
}
const std::function<void()> asyncDispatch = std::bind(&BaseTaskDispatcher::AsyncDispatch, this, task);
if (asyncDispatch == nullptr) {
APP_LOGE("BaseTaskDispatcher::GroupDispatchNotify asyncDispatch is nullptr");
}
std::shared_ptr<Runnable> ptrCallback = std::make_shared<Runnable>(asyncDispatch);
if (ptrCallback == nullptr) {
APP_LOGE("BaseTaskDispatcher::GroupDispatchNotify runnable is nullptr");
flag = false;
}
if (group == nullptr) {
APP_LOGE("BaseTaskDispatcher::GroupDispatchNotify group is nullptr");
flag = false;
}
std::shared_ptr<GroupImpl> groupImpl = CastToGroupImpl(group);
if (groupImpl == nullptr) {
APP_LOGE("BaseTaskDispatcher::GroupDispatchNotify groupImpl is nullptr");
flag = false;
}
if (!flag) {
return ERR_APPEXECFWK_CHECK_FAILED;
}
if (groupImpl->AddNotification(ptrCallback)) {
return ERR_OK;
};
return ERR_APPEXECFWK_CHECK_FAILED;
}
ErrCode BaseTaskDispatcher::ApplyDispatch(const std::shared_ptr<IteratableTask<long>> &task, long iterations)
{
if (task == nullptr) {
APP_LOGE("task object is not set");
return ERR_APPEXECFWK_CHECK_FAILED;
}
if (iterations <= 0) {
APP_LOGE("iterations must giant than 0");
return ERR_APPEXECFWK_CHECK_FAILED;
}
bool flag = true;
for (long i = 0L; i < iterations; ++i) {
std::shared_ptr<Runnable> ptrCallback = std::make_shared<Runnable>([task, i]() { (*task)(i); });
if (ptrCallback == nullptr) {
APP_LOGE("BaseTaskDispatcher::ApplyDispatch runnable is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Revocable> revocable = AsyncDispatch(ptrCallback);
if (revocable == nullptr) {
APP_LOGE("BaseTaskDispatcher::ApplyDispatch revocable is nullptr");
flag = false;
}
}
if (flag) {
return ERR_OK;
}
return ERR_APPEXECFWK_CHECK_FAILED;
}
ErrCode BaseTaskDispatcher::Check(const std::shared_ptr<Runnable> &task) const
{
if (task == nullptr) {
APP_LOGE("dispatch task cannot be null.");
return ERR_APPEXECFWK_CHECK_FAILED;
}
return ERR_OK;
}
std::shared_ptr<GroupImpl> BaseTaskDispatcher::CastToGroupImpl(const std::shared_ptr<Group> &group)
{
std::shared_ptr<GroupImpl> groupImpl_ptr = std::static_pointer_cast<GroupImpl>(group);
if (groupImpl_ptr != nullptr) {
return groupImpl_ptr;
}
APP_LOGE("group cannot instance of groupImpl ");
return nullptr;
}
std::shared_ptr<TaskExecuteInterceptor> BaseTaskDispatcher::GetInterceptor()
{
return nullptr;
}
TaskPriority BaseTaskDispatcher::GetPriority() const
{
return taskPriority_;
}
void BaseTaskDispatcher::TracePointBeforePost(
std::shared_ptr<Task> &task, bool isAsyncTask, const std::string &dispatcherName) const
{
if (task == nullptr) {
APP_LOGE("tracePointBeforePost the task is null");
return;
}
std::string taskType = isAsyncTask ? "ASYNC_TASK_STRING" : "SYNC_TASK_STRING";
long seq = task->GetSequence();
APP_LOGD("tracePointBeforePost log---TaskType:%{public}s,TaskSeq::%{public}ld,DispatcherName::%{public}s",
taskType.c_str(),
seq,
dispatcherName.c_str());
}
void BaseTaskDispatcher::TracePointAfterPost(
std::shared_ptr<Task> &task, bool isAsyncTask, const std::string &dispatcherName) const
{
if (task == nullptr) {
APP_LOGE("TracePointAfterPost the task is null");
return;
}
std::string taskType = isAsyncTask ? "ASYNC_TASK_STRING" : "SYNC_TASK_STRING";
long seq = task->GetSequence();
APP_LOGD("tracePointBeforePost log---TaskType:%{public}s,TaskSeq::%{public}ld,DispatcherName::%{public}s",
taskType.c_str(),
seq,
dispatcherName.c_str());
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2021 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 "global_task_dispatcher.h"
namespace OHOS {
namespace AppExecFwk {
std::string GlobalTaskDispatcher::DISPATCHER_NAME_ = "GlobalDispatcher";
GlobalTaskDispatcher::GlobalTaskDispatcher(TaskPriority priority, std::shared_ptr<TaskExecutor> &executor)
: ParallelTaskDispatcherBase(priority, executor, DISPATCHER_NAME_)
{}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2021 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 "group_impl.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
GroupImpl::GroupImpl()
{
count_.store(0);
}
/**
* Wait all tasks associated to this group to be done.
*
* @param timeout is the max waiting time for jobs in group execute, in ms.
*
* @return true if successfully wait.
*/
bool GroupImpl::AwaitAllTasks(long timeout)
{
if (count_.load() == 0) {
APP_LOGD("GroupImpl::AwaitAllTasks number of count_ is zero");
return true;
}
if (timeout <= 0L) {
return false;
}
bool success = true;
std::unique_lock<std::mutex> lock(dataMutex_);
while (count_.load() > 0) {
if (condition_.wait_for(lock, std::chrono::milliseconds(timeout)) == std::cv_status::timeout) {
success = false;
APP_LOGD("GroupImpl::awaitAllTasks timeout");
break;
}
APP_LOGD("GroupImpl::awaitAllTasks success");
}
return success;
}
/**
* @brief Associates a task to this group.
*
* @return None
*/
void GroupImpl::Associate()
{
APP_LOGD("GroupImpl::Associate called add a task");
// count_++;
count_.fetch_add(1);
}
/**
* @brief Notify group that a task is done or canceled.
*
* @return None
*/
void GroupImpl::NotifyTaskDone()
{
APP_LOGD("GroupImpl::NotifyTaskDone called notify a task to complete");
// int newValue = (--count_);
count_.fetch_sub(1);
int newValue = count_.load();
if (newValue > 0) {
return;
}
std::unique_lock<std::mutex> lock(dataMutex_);
condition_.notify_all();
DrainNotifications();
}
/**
* @brief Adds the |notification| to notification list.
* If all tasks are already done, |notification| will immediately be called on current thread.
* Attention: If tasks are added just this time, it may not be considered.
*
* @param notification Called when all tasks done.
*
* @return None
*/
bool GroupImpl::AddNotification(const std::shared_ptr<Runnable> &notification)
{
if (count_.load() != 0) {
std::unique_lock<std::mutex> lock(dataMutex_);
if (notifications_.size() == MAX_TASK) {
APP_LOGW("GroupImpl::AddNotification called maximun number of tasks exceeded");
return false;
}
if (count_.load() != 0) {
APP_LOGD("GroupImpl::AddNotification called add task");
notifications_.push_back(notification);
return true;
}
}
if (notification) {
(*notification)();
}
return true;
}
/**
*@brief Notify all tasks and remove from queue.
* Attention: Notifications added after all tasks done is not guaranteed.
*
* @return None
*/
void GroupImpl::DrainNotifications()
{
APP_LOGD("GroupImpl::DrainNotifications called task execution");
while (notifications_.size() > 0) {
std::shared_ptr<Runnable> notification = notifications_.front();
notifications_.pop_front();
(*notification)();
}
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 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 "parallel_task_dispatcher.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
const std::string ParallelTaskDispatcher::DISPATCHER_TAG = "ParallelTaskDispatcher";
const std::string ParallelTaskDispatcher::ASYNC_DISPATCHER_BARRIER_TAG = DISPATCHER_TAG + "::asyncDispatchBarrier";
const std::string ParallelTaskDispatcher::SYNC_DISPATCHER_BARRIER_TAG = DISPATCHER_TAG + "::syncDispatchBarrier";
ParallelTaskDispatcher::ParallelTaskDispatcher(
const std::string &name, TaskPriority priority, std::shared_ptr<TaskExecutor> &executor)
: ParallelTaskDispatcherBase(priority, executor, name)
{
barrierHandler_ = std::make_shared<BarrierHandler>(executor);
}
std::shared_ptr<TaskExecuteInterceptor> ParallelTaskDispatcher::GetInterceptor()
{
return barrierHandler_;
}
ErrCode ParallelTaskDispatcher::SyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable)
{
if (Check(runnable) != ERR_OK) {
APP_LOGE("ParallelTaskDispatcher::SyncDispatchBarrier Check failed");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<SyncTask> innerSyncTask = std::make_shared<SyncTask>(runnable, GetPriority(), shared_from_this());
if (innerSyncTask == nullptr) {
APP_LOGE("ParallelTaskDispatcher::SyncDispatchBarrier innerSyncTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Task> innerTask = std::static_pointer_cast<Task>(innerSyncTask);
if (innerTask == nullptr) {
APP_LOGE("ParallelTaskDispatcher::SyncDispatchBarrier innerTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
APP_LOGD("ParallelTaskDispatcher::SyncDispatchBarrier into new sync task");
if (barrierHandler_ == nullptr) {
APP_LOGE("ParallelTaskDispatcher::SyncDispatchBarrier barrierHandler_ is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
barrierHandler_->AddBarrier(innerTask);
innerSyncTask->WaitTask();
APP_LOGD("ParallelTaskDispatcher::SyncDispatchBarrier end");
return ERR_OK;
}
ErrCode ParallelTaskDispatcher::AsyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable)
{
if (Check(runnable) != ERR_OK) {
return ERR_APPEXECFWK_CHECK_FAILED;
}
if (barrierHandler_ == nullptr) {
APP_LOGE("ParallelTaskDispatcher::AsyncDispatchBarrier barrierHandler_ is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
APP_LOGD("ParallelTaskDispatcher::AsyncDispatchBarrier into new async task");
if (innerTask == nullptr) {
APP_LOGE("ParallelTaskDispatcher::AsyncDispatchBarrier innerTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
barrierHandler_->AddBarrier(innerTask);
return ERR_OK;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,173 @@
/*
* Copyright (c) 2021 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 "parallel_task_dispatcher_base.h"
#include "app_log_wrapper.h"
#include "appexecfwk_errors.h"
namespace OHOS {
namespace AppExecFwk {
std::string ParallelTaskDispatcherBase::DISPATCHER_TAG = "ParallelTaskDispatcherBase";
std::string ParallelTaskDispatcherBase::ASYNC_DISPATCHER_TAG = DISPATCHER_TAG + "::asyncDispatch";
std::string ParallelTaskDispatcherBase::SYNC_DISPATCHER_TAG = DISPATCHER_TAG + "::syncDispatch";
std::string ParallelTaskDispatcherBase::DELAY_DISPATCHER_TAG = DISPATCHER_TAG + "::delayDispatch";
std::string ParallelTaskDispatcherBase::ASYNC_GROUP_DISPATCHER_TAG = DISPATCHER_TAG + "::asyncGroupDispatch";
ParallelTaskDispatcherBase::ParallelTaskDispatcherBase(
TaskPriority taskPriority, std::shared_ptr<TaskExecutor> &executor, const std::string &dispatcherName)
: BaseTaskDispatcher(dispatcherName, taskPriority)
{
executor_ = executor;
}
ErrCode ParallelTaskDispatcherBase::InterceptedExecute(std::shared_ptr<Task> &task)
{
if (executor_ == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::InterceptedExecute executor_ is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
if ((GetInterceptor() != nullptr) &&
GetInterceptor()->Intercept(task) == ERR_APPEXECFWK_INTERCEPT_TASK_EXECUTE_SUCCESS) {
APP_LOGE("ParallelTaskDispatcherBase::InterceptedExecute intercept task execute success");
return ERR_APPEXECFWK_INTERCEPT_TASK_EXECUTE_SUCCESS;
}
executor_->Execute(task);
return ERR_OK;
}
ErrCode ParallelTaskDispatcherBase::SyncDispatch(const std::shared_ptr<Runnable> &runnable)
{
if (Check(runnable) != ERR_OK) {
APP_LOGE("ParallelTaskDispatcherBase::SyncDispatch check failed");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<SyncTask> innerSyncTask = std::make_shared<SyncTask>(runnable, GetPriority(), shared_from_this());
if (innerSyncTask == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::SyncDispatch innerSyncTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Task> innerTask = std::static_pointer_cast<Task>(innerSyncTask);
if (innerTask == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::SyncDispatch innerTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
APP_LOGD("ParallelTaskDispatcherBase::SyncDispatch into new sync task");
ErrCode execute = InterceptedExecute(innerTask);
if (execute != ERR_OK) {
APP_LOGE("ParallelTaskDispatcherBase::SyncDispatch execute failed");
return execute;
}
innerSyncTask->WaitTask();
APP_LOGD("ParallelTaskDispatcherBase::SyncDispatch end");
return ERR_OK;
}
std::shared_ptr<Revocable> ParallelTaskDispatcherBase::AsyncDispatch(const std::shared_ptr<Runnable> &runnable)
{
if (Check(runnable) != ERR_OK) {
return nullptr;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
return nullptr;
}
TracePointBeforePost(innerTask, true, ASYNC_DISPATCHER_TAG);
APP_LOGD("ParallelTaskDispatcherBase::AsyncDispatch into new async task");
ErrCode execute = InterceptedExecute(innerTask);
if (execute != ERR_OK) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncDispatch execute failed");
return nullptr;
}
return innerTask;
}
std::shared_ptr<Revocable> ParallelTaskDispatcherBase::DelayDispatch(
const std::shared_ptr<Runnable> &runnable, long delayMs)
{
if (Check(runnable) != ERR_OK) {
APP_LOGE("ParallelTaskDispatcherBase::DelayDispatch Check failed");
return nullptr;
}
if (executor_ == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::DelayDispatch executor_ is nullptr");
return nullptr;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
return nullptr;
}
TracePointBeforePost(innerTask, true, DELAY_DISPATCHER_TAG);
std::function<void()> callback =
std::bind(&ParallelTaskDispatcherBase::InterceptedExecute, shared_from_this(), innerTask);
bool executeFlag = executor_->DelayExecute(callback, delayMs);
if (!executeFlag) {
APP_LOGE("ParallelTaskDispatcherBase::DelayDispatch execute failed");
return nullptr;
}
return innerTask;
}
std::shared_ptr<Revocable> ParallelTaskDispatcherBase::AsyncGroupDispatch(
const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &runnable)
{
if (group == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncGroupDispatch group is nullptr");
return nullptr;
}
if (Check(runnable) != ERR_OK) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncGroupDispatch Check failed");
return nullptr;
}
std::shared_ptr<GroupImpl> groupImpl = CastToGroupImpl(group);
if (groupImpl == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncGroupDispatch groupImpl is nullptr");
return nullptr;
}
groupImpl->Associate();
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncGroupDispatch innerTask is nullptr");
return nullptr;
}
TracePointBeforePost(innerTask, true, ASYNC_GROUP_DISPATCHER_TAG);
std::shared_ptr<MyTaskListener> ptrlistener = std::make_shared<MyTaskListener>();
if (ptrlistener == nullptr) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncGroupDispatch ptrlistener is nullptr");
return nullptr;
}
const std::function<void()> onTaskDone = std::bind(&GroupImpl::NotifyTaskDone, groupImpl);
ptrlistener->Callback(onTaskDone);
innerTask->AddTaskListener(ptrlistener);
ErrCode execute = InterceptedExecute(innerTask);
if (execute != ERR_OK) {
APP_LOGE("ParallelTaskDispatcherBase::AsyncGroupDispatch execute failed");
return nullptr;
}
return innerTask;
}
std::shared_ptr<TaskExecuteInterceptor> ParallelTaskDispatcherBase::GetInterceptor()
{
return nullptr;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,219 @@
/*
* Copyright (c) 2021 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 "serial_task_dispatcher.h"
#include "app_log_wrapper.h"
#include "appexecfwk_errors.h"
namespace OHOS {
namespace AppExecFwk {
std::string SerialTaskDispatcher::DISPATCHER_TAG = "SerialTaskDispatcher";
std::string SerialTaskDispatcher::ASYNC_DISPATCHER_TAG = DISPATCHER_TAG + "::asyncDispatch";
std::string SerialTaskDispatcher::SYNC_DISPATCHER_TAG = DISPATCHER_TAG + "::syncDispatch";
std::string SerialTaskDispatcher::DELAY_DISPATCHER_TAG = DISPATCHER_TAG + "::delayDispatch";
SerialTaskDispatcher::SerialTaskDispatcher(
const std::string &dispatcherName, const TaskPriority priority, const std::shared_ptr<TaskExecutor> &executor)
: BaseTaskDispatcher(dispatcherName, priority)
{
running_ = false;
executor_ = executor;
}
int SerialTaskDispatcher::GetWorkingTasksSize()
{
return workingTasks_.Size();
}
std::string SerialTaskDispatcher::GetDispatcherName()
{
return dispatcherName_;
}
ErrCode SerialTaskDispatcher::SyncDispatch(const std::shared_ptr<Runnable> &runnable)
{
APP_LOGD("SerialTaskDispatcher::SyncDispatch begin");
if (Check(runnable) != ERR_OK) {
APP_LOGE("SerialTaskDispatcher::SyncDispatch check failed");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<SyncTask> innerSyncTask = std::make_shared<SyncTask>(runnable, GetPriority(), shared_from_this());
if (innerSyncTask == nullptr) {
APP_LOGE("SerialTaskDispatcher::SyncDispatch innerSyncTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Task> innerTask = std::static_pointer_cast<Task>(innerSyncTask);
if (innerTask == nullptr) {
APP_LOGE("SerialTaskDispatcher::SyncDispatch innerTask is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
TracePointBeforePost(innerTask, false, SYNC_DISPATCHER_TAG);
OnNewTaskIn(innerTask);
innerSyncTask->WaitTask();
TracePointAfterPost(innerTask, false, DISPATCHER_TAG);
APP_LOGD("SerialTaskDispatcher::SyncDispatch end");
return ERR_OK;
}
std::shared_ptr<Revocable> SerialTaskDispatcher::AsyncDispatch(const std::shared_ptr<Runnable> &runnable)
{
if (Check(runnable) != ERR_OK) {
APP_LOGE("SerialTaskDispatcher::AsyncDispatch Check failed");
return nullptr;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
APP_LOGE("SerialTaskDispatcher::AsyncDispatch innerTask is nullptr");
return nullptr;
}
TracePointBeforePost(innerTask, true, ASYNC_DISPATCHER_TAG);
APP_LOGD("SerialTaskDispatcher::AsyncDispatch into new async task");
OnNewTaskIn(innerTask);
return innerTask;
}
std::shared_ptr<Revocable> SerialTaskDispatcher::DelayDispatch(const std::shared_ptr<Runnable> &runnable, long delayMs)
{
if (executor_ == nullptr) {
APP_LOGE("SerialTaskDispatcher::DelayDispatch executor_ is nullptr");
return nullptr;
}
if (Check(runnable) != ERR_OK) {
APP_LOGE("SerialTaskDispatcher::DelayDispatch Check failed");
return nullptr;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
APP_LOGE("SerialTaskDispatcher::DelayDispatch innerTask is nullptr");
return nullptr;
}
TracePointBeforePost(innerTask, true, DELAY_DISPATCHER_TAG);
// bind parameter to avoid deconstruct.
std::function<void()> callback = std::bind(&SerialTaskDispatcher::OnNewTaskIn, this, innerTask);
bool executeFlag = executor_->DelayExecute(callback, delayMs);
if (!executeFlag) {
APP_LOGE("SerialTaskDispatcher::DelayDispatch execute failed");
return nullptr;
}
return innerTask;
}
ErrCode SerialTaskDispatcher::OnNewTaskIn(std::shared_ptr<Task> &task)
{
APP_LOGD("SerialTaskDispatcher::OnNewTaskIn begin");
ErrCode code = Prepare(task);
if (code != ERR_OK) {
APP_LOGE("SerialTaskDispatcher::OnNewTaskIn Prepare failed");
return ERR_APPEXECFWK_CHECK_FAILED;
}
{
std::unique_lock<std::mutex> lock(mutex_);
if (workingTasks_.Offer(task) == false) {
APP_LOGW("SerialTaskDispatcher.onNewTaskIn exceed the maximum capacity of Queue");
}
}
Schedule();
APP_LOGD("SerialTaskDispatcher::OnNewTaskIn end");
return ERR_OK;
}
ErrCode SerialTaskDispatcher::Prepare(std::shared_ptr<Task> &task)
{
if (task == nullptr) {
APP_LOGE("SerialTaskDispatcher::Prepare task is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
// inline class
class MyTaskListener : public TaskListener {
private:
std::function<void()> callback_;
public:
void OnChanged(const TaskStage &stage)
{
if (stage.IsDone()) {
callback_();
}
}
// set callback function
void Callback(const std::function<void()> &callbackFunction)
{
callback_ = std::move(callbackFunction);
}
};
// set inline listener
std::shared_ptr<MyTaskListener> ptrlistener = std::make_shared<MyTaskListener>();
if (ptrlistener == nullptr) {
APP_LOGE("SerialTaskDispatcher::Prepare MyTaskListener is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
const std::function<void()> onTaskDone = [&]() { OnTaskDone(); };
ptrlistener->Callback(onTaskDone);
task->AddTaskListener(ptrlistener);
return ERR_OK;
}
void SerialTaskDispatcher::OnTaskDone()
{
// isExhausted: is an inaccurate judge indicate that the workingTasks is empty.If true, do double - check.
bool isExhausted = workingTasks_.Empty();
DoNext(isExhausted);
// APP_LOGD("SerialTaskDispatcher::OnTaskDone end, running=%d", running.load());
}
bool SerialTaskDispatcher::Schedule()
{
bool init = false;
if (!running_.compare_exchange_strong(init, true)) {
APP_LOGD("SerialTaskDispatcher::schedule already running");
return false;
}
APP_LOGD("SerialTaskDispatcher::Schedule do next");
return DoNext(false);
}
bool SerialTaskDispatcher::DoNext(bool isExhausted)
{
std::shared_ptr<Task> nextptr = nullptr;
{
std::unique_lock<std::mutex> lock(mutex_);
nextptr = workingTasks_.Poll();
if (nextptr == nullptr) {
running_.store(false);
APP_LOGD("SerialTaskDispatcher::DoNext no more task");
return false;
}
}
DoWork(nextptr);
APP_LOGD("SerialTaskDispatcher::DoNext end");
return true;
}
void SerialTaskDispatcher::DoWork(std::shared_ptr<Task> &task)
{
// |task| mustn't be null
executor_->Execute(task);
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 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 "spec_task_dispatcher.h"
#include "task_handler_libevent_adapter.h"
namespace OHOS {
namespace AppExecFwk {
std::string SpecTaskDispatcher::DISPATCHER_TAG = "SpecTaskDispatcher";
std::string SpecTaskDispatcher::ASYNC_DISPATCHER_TAG = DISPATCHER_TAG + "::asyncDispatch";
std::string SpecTaskDispatcher::SYNC_DISPATCHER_TAG = DISPATCHER_TAG + "::syncDispatch";
std::string SpecTaskDispatcher::DELAY_DISPATCHER_TAG = DISPATCHER_TAG + "::delayDispatch";
SpecTaskDispatcher::SpecTaskDispatcher(
std::shared_ptr<SpecDispatcherConfig> config, std::shared_ptr<EventRunner> runner)
: BaseTaskDispatcher(config->GetName(), config->GetPriority())
{
handler_ = std::make_shared<TaskHandlerLibeventAdapter>(runner);
}
ErrCode SpecTaskDispatcher::SyncDispatch(const std::shared_ptr<Runnable> &runnable)
{
APP_LOGD("SpecTaskDispatcher::SyncDispatch begin");
if (Check(runnable) != ERR_OK || handler_ == nullptr) {
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
return ERR_APPEXECFWK_CHECK_FAILED;
}
TracePointBeforePost(innerTask, false, SYNC_DISPATCHER_TAG);
APP_LOGD("SpecTaskDispatcher::SyncDispatch into new sync task");
handler_->DispatchSync(runnable);
// innerSyncTask->WaitTask();
TracePointAfterPost(innerTask, false, DISPATCHER_TAG);
APP_LOGD("SpecTaskDispatcher::SyncDispatch end");
return ERR_OK;
}
std::shared_ptr<Revocable> SpecTaskDispatcher::AsyncDispatch(const std::shared_ptr<Runnable> &runnable)
{
if (Check(runnable) != ERR_OK || handler_ == nullptr) {
return nullptr;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
return nullptr;
}
TracePointBeforePost(innerTask, true, ASYNC_DISPATCHER_TAG);
APP_LOGD("SpecTaskDispatcher::AsyncDispatch into new async task");
handler_->Dispatch(runnable);
return innerTask;
}
std::shared_ptr<Revocable> SpecTaskDispatcher::DelayDispatch(const std::shared_ptr<Runnable> &runnable, long delayMs)
{
if (Check(runnable) != ERR_OK || handler_ == nullptr) {
return nullptr;
}
std::shared_ptr<Task> innerTask = std::make_shared<Task>(runnable, GetPriority(), shared_from_this());
if (innerTask == nullptr) {
return nullptr;
}
TracePointBeforePost(innerTask, true, DELAY_DISPATCHER_TAG);
handler_->Dispatch(runnable, delayMs);
return innerTask;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2021 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 "task_dispatcher_context.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
TaskDispatcherContext::TaskDispatcherContext()
{
globalDispatchers_.resize(PRIORITY_COUNT);
config_ = std::make_shared<DefaultWorkerPoolConfig>();
if (config_ == nullptr) {
executor_ = nullptr;
} else {
executor_ = std::make_shared<TaskExecutor>(config_);
if (executor_ != nullptr) {
executor_->CreateGuardThread();
}
}
}
TaskDispatcherContext::TaskDispatcherContext(const std::shared_ptr<TaskExecutor> &executor)
{
globalDispatchers_.resize(PRIORITY_COUNT);
config_ = std::make_shared<DefaultWorkerPoolConfig>();
executor_ = executor;
}
TaskDispatcherContext::~TaskDispatcherContext()
{
if (executor_) {
APP_LOGD("TaskDispatcherContext::~TaskDispatcherContext() terminate");
executor_->Terminate(false);
}
APP_LOGD("TaskDispatcherContext::~TaskDispatcherContext");
}
std::shared_ptr<WorkerPoolConfig> TaskDispatcherContext::GetWorkerPoolConfig() const
{
return config_;
}
std::map<std::string, long> TaskDispatcherContext::GetWorkerThreadsInfo() const
{
if (executor_ != nullptr) {
return executor_->GetWorkerThreadsInfo();
}
std::map<std::string, long> map;
return map;
}
std::map<std::shared_ptr<SerialTaskDispatcher>, std::string> TaskDispatcherContext::GetSerialDispatchers() const
{
return serialDispatchers_;
}
int TaskDispatcherContext::GetWaitingTasksCount() const
{
if (executor_ != nullptr) {
return executor_->GetPendingTasksSize();
}
return 0;
}
long TaskDispatcherContext::GetTaskCounter() const
{
if (executor_ != nullptr) {
return executor_->GetTaskCounter();
}
return 0;
}
std::shared_ptr<SerialTaskDispatcher> TaskDispatcherContext::CreateSerialDispatcher(
const std::string &name, TaskPriority priority)
{
if (executor_ == nullptr) {
return nullptr;
}
std::shared_ptr<SerialTaskDispatcher> serialDispatcher =
std::make_shared<SerialTaskDispatcher>(name, priority, executor_);
serialDispatchers_.insert(std::pair<std::shared_ptr<SerialTaskDispatcher>, std::string>(serialDispatcher, name));
return serialDispatcher;
}
std::shared_ptr<ParallelTaskDispatcher> TaskDispatcherContext::CreateParallelDispatcher(
const std::string &name, TaskPriority priority)
{
if (executor_ == nullptr) {
return nullptr;
}
std::shared_ptr<ParallelTaskDispatcher> parallelTaskDispatcher =
std::make_shared<ParallelTaskDispatcher>(name, priority, executor_);
return parallelTaskDispatcher;
}
int TaskDispatcherContext::MapPriorityIndex(TaskPriority priority) const
{
switch (priority) {
case TaskPriority::HIGH:
return HIGH_PRIORITY_INDEX;
case TaskPriority::DEFAULT:
return DEFAULT_PRIORITY_INDEX;
case TaskPriority::LOW:
return LOW_PRIORITY_INDEX;
}
APP_LOGE("TaskDispatcherContext.mapPriorityIndex unhandled priority=%{public}d", priority);
return DEFAULT_PRIORITY_INDEX;
}
std::shared_ptr<TaskDispatcher> TaskDispatcherContext::GetGlobalTaskDispatcher(TaskPriority priority)
{
std::unique_lock<std::mutex> lock(mtx_);
int index = MapPriorityIndex(priority);
std::shared_ptr<TaskDispatcher> dispatcher = globalDispatchers_[index];
if (dispatcher == nullptr) {
APP_LOGD("GetGlobalTaskDispatcher dispatcher is nullptr ");
if (executor_ == nullptr) {
APP_LOGE("GetGlobalTaskDispatcher executor_ is nullptr ");
return nullptr;
}
dispatcher = std::make_shared<GlobalTaskDispatcher>(priority, executor_);
if (globalDispatchers_[index] == nullptr) {
APP_LOGD("GetGlobalTaskDispatcher dispatcher compareAndSet ");
globalDispatchers_.insert((globalDispatchers_.begin() + index), dispatcher);
}
}
return dispatcher;
}
ErrCode TaskDispatcherContext::Shutdown(bool force)
{
if (executor_ == nullptr) {
APP_LOGE("TaskDispatcherContext::Shutdown executor_ is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
executor_->Terminate(force);
return ERR_OK;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2021 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 "barrier_handler.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
BarrierHandler::BarrierHandler(const std::shared_ptr<TaskExecutor> &executor)
{
executor_ = executor;
};
ErrCode BarrierHandler::AddBarrier(std::shared_ptr<Task> &barrierTask)
{
if (ListenToTask(barrierTask) != ERR_OK) {
APP_LOGE("BarrierHandler::addBarrier listenToTask failed");
return ERR_APPEXECFWK_CHECK_FAILED;
};
bool execNow = false;
{
std::unique_lock<std::mutex> lock(barrierLock_);
std::shared_ptr<BarrierPair> pair = barrierQueue_.size() == 0 ? nullptr : barrierQueue_.back();
if ((pair == nullptr) || ((!HasTask(pair->tasks_)) && (pair->barrier_ == nullptr))) {
execNow = true;
}
if ((pair == nullptr) || (pair->barrier_ != nullptr)) {
std::set<std::shared_ptr<Task>> tmp;
std::shared_ptr<BarrierPair> barrierPair = std::make_shared<BarrierPair>(tmp, barrierTask);
if (barrierPair == nullptr) {
return ERR_APPEXECFWK_CHECK_FAILED;
}
barrierQueue_.push_back(barrierPair);
} else {
pair->barrier_ = barrierTask;
}
}
APP_LOGD("Barrier.addBarrier need execute now: %{public}d", execNow);
if (execNow) {
executor_->Execute(barrierTask);
}
return ERR_OK;
}
ErrCode BarrierHandler::Intercept(std::shared_ptr<Task> &task)
{
if (ListenToTask(task) != ERR_OK) {
APP_LOGE("BarrierHandler::intercept listenToTask failed");
return ERR_APPEXECFWK_CHECK_FAILED;
};
// afterBarrier means is intercepted.
bool intercepted = AddTaskAfterBarrier(task);
if (intercepted) {
APP_LOGD("Barrier.intercept intercepted a task.");
}
return intercepted ? ERR_APPEXECFWK_INTERCEPT_TASK_EXECUTE_SUCCESS : ERR_APPEXECFWK_CHECK_FAILED;
}
ErrCode BarrierHandler::ListenToTask(std::shared_ptr<Task> &task)
{
std::shared_ptr<MyTaskListener> ptrlistener = std::make_shared<MyTaskListener>();
if (ptrlistener == nullptr) {
APP_LOGE("BarrierHandler::listenToTask make shared MyTaskListener is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
const std::function<void()> onTaskDone = std::bind(&BarrierHandler::OnTaskDone, this, task);
ptrlistener->Callback(onTaskDone);
task->AddTaskListener(ptrlistener);
return ERR_OK;
}
void BarrierHandler::OnTaskDone(std::shared_ptr<Task> &task)
{
// remove from head of queue.
// Under the premise that task cannot be reused.
bool removed = false;
{
std::unique_lock<std::mutex> lock(barrierLock_);
std::shared_ptr<BarrierPair> barrierPair = barrierQueue_.size() == 0 ? nullptr : barrierQueue_.front();
if (barrierPair != nullptr) {
if (HasTask(barrierPair->tasks_)) {
removed = barrierPair->tasks_.erase(task) == 0 ? false : true;
if (barrierPair->tasks_.empty() && (barrierPair->barrier_ != nullptr)) {
APP_LOGD("Barrier.onTaskDone execute barrier task after task done.");
executor_->Execute(barrierPair->barrier_);
}
} else if (task == (barrierPair->barrier_)) {
APP_LOGD("Barrier.onTaskDone remove a barrier.");
barrierPair->barrier_ = nullptr;
removed = true;
// Driven to next barrier.
// In one case (barrierQueue.size() == 1): call barrier, and no more task incoming.
if (barrierQueue_.size() > 1) {
barrierQueue_.pop_front();
std::shared_ptr<BarrierPair> nextPair = barrierQueue_.front();
if (HasTask(nextPair->tasks_)) {
for (std::set<std::shared_ptr<Task>>::iterator it = nextPair->tasks_.begin();
it != nextPair->tasks_.end();
it++) {
executor_->Execute(*it);
}
} else if (nextPair->barrier_ != nullptr) {
APP_LOGD("Barrier.onTaskDone execute barrier task after barrier done.");
executor_->Execute(nextPair->barrier_);
} else {
// NOTREACHED.
APP_LOGD("Barrier.onTaskDone: Detected an empty node.");
}
}
}
}
}
if (!removed) {
APP_LOGD("Barrier.onTaskDone: Task remove failed.");
}
}
bool BarrierHandler::AddTaskAfterBarrier(std::shared_ptr<Task> &task)
{
std::unique_lock<std::mutex> lock(barrierLock_);
std::shared_ptr<BarrierPair> pair = barrierQueue_.size() == 0 ? nullptr : barrierQueue_.back();
if ((pair == nullptr) || (pair->barrier_ != nullptr)) {
std::shared_ptr<BarrierPair> tmp = std::make_shared<BarrierPair>(CreateTaskSet(task), nullptr);
if (tmp == nullptr) {
APP_LOGE("BarrierHandler::addTaskAfterBarrier make shared BarrierPair is nullptr");
return false;
}
barrierQueue_.push_back(tmp);
} else if (pair->tasks_.empty()) {
pair->tasks_ = CreateTaskSet(task);
} else {
pair->tasks_.insert(task);
}
return (barrierQueue_.size() > 1);
}
bool BarrierHandler::HasTask(const std::set<std::shared_ptr<Task>> &tasks)
{
return ((tasks.size() != 0) && !tasks.empty());
}
std::set<std::shared_ptr<Task>> BarrierHandler::CreateTaskSet(std::shared_ptr<Task> &firstTask)
{
std::set<std::shared_ptr<Task>> newSet;
newSet.insert(firstTask);
return newSet;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 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 "sync_task.h"
#include <thread>
namespace OHOS {
namespace AppExecFwk {
// Help to calculate hash code of object.
template <typename T>
inline size_t CalculateHashCode(const T &obj)
{
std::hash<T> calculateHashCode;
return calculateHashCode(obj);
}
SyncTask::SyncTask(const std::shared_ptr<Runnable> &runnable, TaskPriority priority,
const std::shared_ptr<BaseTaskDispatcher> &baseTaskDispatcher)
: Task(runnable, priority, baseTaskDispatcher)
{
executed_.store(false);
}
void SyncTask::Run()
{
std::unique_lock<std::mutex> lock(mutex_);
auto threadId = std::this_thread::get_id();
APP_LOGD("SyncTask::Run begin thread=%{public}zu", CalculateHashCode(threadId));
Task::Run();
executed_.store(true);
// |waitTask| may have been multi invoked.
condition_variable_.notify_all();
APP_LOGD("SyncTask::Run end thread=%{public}zu", CalculateHashCode(threadId));
}
void SyncTask::WaitTask()
{
auto threadId = std::this_thread::get_id();
APP_LOGD("SyncTask::WaitTask begin thread=%{public}zu", CalculateHashCode(threadId));
std::unique_lock<std::mutex> lock(mutex_);
while (executed_ == false) {
condition_variable_.wait(lock);
}
APP_LOGD("SyncTask::WaitTask end thread=%{public}zu", CalculateHashCode(threadId));
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,218 @@
/*
* Copyright (c) 2021 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 "task.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
/**
* @brief Constructs the object.
* @param runnable The user task wrapped in.
* @param priority The priority
* @return None
*/
Task::Task(const std::shared_ptr<Runnable> &runnable, const TaskPriority priority,
const std::shared_ptr<BaseTaskDispatcher> &baseTaskDispatcher)
: taskListeners_()
{
runnable_ = runnable;
priority_ = priority;
baseTaskDispatcher_ = baseTaskDispatcher;
std::atomic_init(&state_, 0);
APP_LOGD("Task::Task init listener count=%{public}zu", taskListeners_.Size());
}
Task::~Task()
{}
/**
*@brief invoke the function to execute the task
*@param None
*@return None
*/
void Task::Run()
{
APP_LOGD("Task::Run task run called start");
if (runnable_ == nullptr) {
APP_LOGI("Task::Run called runnable_ is null");
return;
}
// Task cannot be reused.
if (EnterExecute()) {
APP_LOGD("Task::Run runnable_ Run called start");
(*runnable_.get())();
}
APP_LOGD("Task::Run runnable_ Run called end");
}
/**
* @brief Gets the priority.
* @param None
* @return The priority.
*/
TaskPriority Task::GetPriority() const
{
return priority_;
}
/**
* @brief Sets the sequence.
* @param None
* @param sequence The sequence
* @return None
*/
void Task::SetSequence(long sequence)
{
sequence_ = sequence;
}
/**
*@brief Gets the sequence.
*@param None
*@return The sequence.
*/
long Task::GetSequence() const
{
return sequence_;
}
/**
*@brief Revoke this task if hasn't run.
*@param None
*@return true if set revoked or already revoked. False if the task has start executing.
*/
bool Task::Revoke()
{
if (runnable_ == nullptr) {
APP_LOGI("Task.Revoke called runnable_ is null");
return false;
}
RevokeResult result = SetRevoked();
APP_LOGD("Task.Revoke result: %{public}u", result);
if (result == SUCCESS) {
OnTaskCanceled();
}
return (result == SUCCESS) || (result == ALREADY_REVOKED);
}
/**
*@brief Adds a task listener.
*@param listener The listener
*@return None
*/
void Task::AddTaskListener(const std::shared_ptr<TaskListener> &listener)
{
APP_LOGD("Task.AddTaskListener listener called start");
taskListeners_.Offer(listener);
}
/**
*@brief Called when task is about to run.
*@param None
*@return None
*/
void Task::BeforeTaskExecute()
{
if ((state_ & REVOKED) != REVOKED) {
ConcurrentQueueStatusUpdate(TaskStage::BEFORE_EXECUTE);
}
}
/**
*@brief Called when task is done.
*@param None
*@return None
*/
void Task::AfterTaskExecute()
{
if ((state_ & EXECUTED) == EXECUTED) {
APP_LOGD("Task.AfterTaskExecute taskStage called AFTER_EXECUTE");
ConcurrentQueueStatusUpdate(TaskStage::AFTER_EXECUTE);
}
}
/**
*@brief Called when task is canceled.
*@param None
*@return None
*/
void Task::OnTaskCanceled()
{
APP_LOGD("Task.OnTaskCanceled taskStage called REVOKED");
ConcurrentQueueStatusUpdate(TaskStage::REVOKED);
}
/**
*@brief Return true if not executed or revoked, and if not executed or revoked, ensure |EXECUTED| to be set.
*@param None
*@return bool
*/
bool Task::EnterExecute()
{
int stateNotIn = EXECUTED | REVOKED;
while (true) {
int value = state_.load();
if ((state_ & stateNotIn) == 0) {
// Not executed or revoked
if (state_.compare_exchange_strong(value, EXECUTED)) {
APP_LOGD("Task.EnterExecute return success");
return true;
}
} else {
APP_LOGD("Task.EnterExecute return fail, state=%{public}d, stateNotIn=%{public}d", value, stateNotIn);
return false;
}
}
}
Task::RevokeResult Task::SetRevoked()
{
while (true) {
int value = state_.load();
if ((value & REVOKED) == REVOKED) {
APP_LOGD("Task.SetRevoked return ALREADY_REVOKED");
return ALREADY_REVOKED;
}
if ((value & EXECUTED) == 0) {
if (state_.compare_exchange_strong(value, REVOKED)) {
APP_LOGD("Task.SetRevoked return SUCCESS");
return SUCCESS;
}
} else {
APP_LOGD("Task.SetRevoked return FAIL");
return FAIL;
}
}
}
void Task::ConcurrentQueueStatusUpdate(const TaskStage::TASKSTAGE taskstage)
{
APP_LOGD("Task.ConcurrentQueueStatusUpdate taskListeners_ called start");
for (auto iter = taskListeners_.Begin(); iter != taskListeners_.End(); iter++) {
(*iter)->OnChanged(taskstage);
}
if (taskstage == TaskStage::TASKSTAGE::AFTER_EXECUTE) {
taskListeners_.clear();
}
}
bool Task::operator==(std::shared_ptr<Task> &rec) const
{
return this->sequence_ == rec->sequence_ && this->state_ == rec->state_ && this->priority_ == rec->priority_ &&
this->revocable_ == rec->revocable_ && this->runnable_ == rec->runnable_ &&
this->baseTaskDispatcher_ == rec->baseTaskDispatcher_;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 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 "default_thread_factory.h"
namespace OHOS {
namespace AppExecFwk {
DefaultThreadFactory::DefaultThreadFactory() : index_(1)
{}
std::shared_ptr<Thread> DefaultThreadFactory::Create()
{
std::shared_ptr<Thread> pThread = std::make_shared<Thread>();
if (pThread != nullptr) {
int value = std::atomic_fetch_add(&index_, 1);
std::string name = std::string("PoolThread-") + std::to_string(value);
pThread->thread_name_ = name;
APP_LOGD("DefaultThreadFactory::Create thread name is %{public}s", name.c_str());
} else {
APP_LOGD("DefaultThreadFactory::Create error");
}
return pThread;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 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 "default_worker_pool_config.h"
namespace OHOS {
namespace AppExecFwk {
int DefaultWorkerPoolConfig::GetMaxThreadCount(void) const
{
return DEFAULT_MAX_THREAD_COUNT;
}
int DefaultWorkerPoolConfig::GetCoreThreadCount(void) const
{
return DEFAULT_CORE_THREAD_COUNT;
}
long DefaultWorkerPoolConfig::GetKeepAliveTime(void) const
{
return DEFAULT_KEEP_ALIVE_TIME;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,247 @@
/*
* Copyright (c) 2021 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 "task_executor.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
std::atomic<long> TaskExecutor::sequence(0);
TaskExecutor::TaskExecutor(const std::shared_ptr<WorkerPoolConfig> &config) : WorkerPool(config)
{
terminated_ = false;
taskCounter_ = 0;
delayTasks_ = std::make_shared<DelayQueue>();
pendingTasks_ = std::make_shared<BlockingQueue>();
}
TaskExecutor::~TaskExecutor()
{
if ((consumer_) && consumer_->joinable()) {
APP_LOGD("TaskExecutor::~TaskExecutor consumer is running");
consumer_->join();
}
APP_LOGD("TaskExecutor::~TaskExecutor");
}
void TaskExecutor::Execute(const std::shared_ptr<Task> &task)
{
APP_LOGD("TaskExecutor::Execute begin");
task->SetSequence(GetAndIncrement(sequence));
std::shared_ptr<TaskExecutor> executor = shared_from_this();
if (AddWorker(executor, task) == false) {
std::shared_ptr<PriorityTaskWrapper> priorityTaskWrapper =
std::make_shared<PriorityTaskWrapper>(task->GetPriority(), task);
if (pendingTasks_->Offer(priorityTaskWrapper) == false) {
APP_LOGW("TaskExecutor::Execute rejected a task");
}
}
APP_LOGD("TaskExecutor::Execute end");
}
ErrCode TaskExecutor::DoWorks(const std::shared_ptr<WorkerThread> &worker)
{
APP_LOGD("TaskExecutor::DoWorks begin");
if (worker == nullptr) {
APP_LOGE("TaskExecutor::DoWorks worker is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
if (worker->GetThread() == nullptr) {
APP_LOGE("TaskExecutor::DoWorks worker GetThread is nullptr");
return ERR_APPEXECFWK_CHECK_FAILED;
}
std::shared_ptr<Task> task = worker->PollFirstTask();
bool isInterrupted = false;
bool done = false;
while (((task != nullptr && done == false) || ((task = GetTask(worker)) != nullptr))) {
APP_LOGD("TaskExecutor::DoWorks loop tasks.");
BeforeRun(task);
task->Run();
AfterRun(task);
worker->IncTaskCount();
IncrementAndGet(taskCounter_);
// loop condition
done = true;
}
OnWorkerExit(worker, isInterrupted);
APP_LOGD("TaskExecutor::DoWorks end");
return ERR_OK;
}
std::shared_ptr<Task> TaskExecutor::GetTask(const std::shared_ptr<WorkerThread> &workerThread)
{
bool isTimeout = false;
std::shared_ptr<Task> nullRunnable = nullptr;
std::shared_ptr<Task> next = nullptr;
for (;;) {
if (terminated_.load() && pendingTasks_->Empty()) {
APP_LOGD("TaskExecutor::GetTask end: loop thread %{public}s is terminated",
workerThread->GetThreadName().c_str());
DecrementThread();
return nullRunnable;
}
int workerCount = GetWorkCount();
APP_LOGD("TaskExecutor::GetTask workerCount:%{public}d, GetCoreThreadCount: %{public}d",
workerCount,
GetCoreThreadCount());
bool needCheckTimeout = (workerCount > GetCoreThreadCount());
if (isTimeout && needCheckTimeout && pendingTasks_->Empty()) {
APP_LOGD("TaskExecutor::GetTask isTimeout is true");
if (CompareAndDecNum(workerCount)) {
APP_LOGD("TaskExecutor::GetTask end: loop thread %{public}s is timeout",
workerThread->GetThreadName().c_str());
return nullRunnable;
}
continue;
}
APP_LOGD("TaskExecutor::GetTask need timeout=%{public}d", needCheckTimeout);
std::shared_ptr<PriorityTaskWrapper> next =
needCheckTimeout ? pendingTasks_->Poll(GetKeepAliveTime()) : pendingTasks_->Take();
if (next != nullptr && next->task_ != nullptr) {
APP_LOGD("TaskExecutor::GetTask end: loop thread %{public}s get next task",
workerThread->GetThreadName().c_str());
return next->task_;
}
isTimeout = true;
}
}
void TaskExecutor::Terminate(bool force)
{
APP_LOGD("TaskExecutor::Terminate begin");
TerminateConsumer();
ClosePool(force);
APP_LOGD("TaskExecutor::Terminate end");
}
void TaskExecutor::AfterRun(const std::shared_ptr<Task> &task)
{
task->AfterTaskExecute();
}
void TaskExecutor::BeforeRun(const std::shared_ptr<Task> &task)
{
task->BeforeTaskExecute();
}
bool TaskExecutor::DelayExecute(const Runnable &task, long delayMs)
{
if (delayMs <= 0) {
task();
APP_LOGD("TaskExecutor::DelayExecute end and delayMs less than 0");
return true;
}
if (terminated_.load()) {
APP_LOGI("TaskExecutor::DelayExecute end and terminate");
return false;
}
std::shared_ptr<DelayTaskWrapper> delayTaskWrapper = std::make_shared<DelayTaskWrapper>(delayMs, task);
if (delayTaskWrapper == nullptr) {
APP_LOGI("TaskExecutor::DelayExecute end and delayTaskWrapper is nullptr");
return false;
}
delayTasks_->Offer(delayTaskWrapper);
return EnsureConsumeStarted();
}
void TaskExecutor::TerminateConsumer()
{
std::unique_lock<std::mutex> lock(dataMutex_);
terminated_.store(true);
pendingTasks_->Stop();
delayTasks_->Stop();
if (consumer_ != nullptr) {
if (consumer_->joinable()) {
consumer_->join();
}
consumer_ = nullptr;
}
}
bool TaskExecutor::EnsureConsumeStarted()
{
if (consumer_ == nullptr) {
{
std::unique_lock<std::mutex> lock(dataMutex_);
if (consumer_ == nullptr) {
consumer_ = std::make_shared<std::thread>(&TaskExecutor::Consume, this);
if (consumer_ == nullptr) {
APP_LOGD("TaskExecutor::EnsureConsumeStarted consumer_ is nullptr");
return false;
}
APP_LOGD("TaskExecutor::EnsureConsumeStarted start a delay task consumer");
}
}
}
return true;
}
void TaskExecutor::Consume()
{
for (;;) {
if (terminated_.load() && delayTasks_->Empty()) {
APP_LOGD("TaskExecutor::Consume delay task is empty");
break;
}
std::shared_ptr<DelayTaskWrapper> delayTaskWrapper = delayTasks_->Take();
if (delayTaskWrapper == nullptr || delayTaskWrapper->runnable_ == nullptr) {
APP_LOGD("TaskExecutor::Consume delayTaskWrapper is nullptr");
return;
};
(delayTaskWrapper->runnable_)();
APP_LOGD("TaskExecutor::Consume after run");
}
}
int TaskExecutor::GetPendingTasksSize()
{
return pendingTasks_->Size();
}
long TaskExecutor::GetTaskCounter()
{
return taskCounter_.load();
}
long TaskExecutor::GetAndIncrement(std::atomic<long> &atomiclong)
{
long ret = atomiclong.load();
atomiclong.fetch_add(1, std::memory_order_relaxed);
return ret;
}
long TaskExecutor::IncrementAndGet(std::atomic<long> &atomiclong)
{
atomiclong.fetch_add(1, std::memory_order_relaxed);
return atomiclong;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2021 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 "work_thread.h"
namespace OHOS {
namespace AppExecFwk {
WorkerThread::WorkerThread(const std::shared_ptr<Delegate> &delegate, const std::shared_ptr<Task> &firstTask,
const std::shared_ptr<ThreadFactory> &factory)
{
task_counter_.store(0);
first_task_ = firstTask;
delegate_ = delegate;
factory_ = factory;
}
void WorkerThread::Join()
{
if ((thread_) && (thread_->thread_) && thread_->thread_->joinable()) {
APP_LOGD("WorkerThread::Join joinable thread");
thread_->thread_->join();
}
APP_LOGD("WorkerThread::Join end");
}
void WorkerThread::CreateThread()
{
thread_ = factory_->Create();
auto task = [&]() {
if (delegate_ != nullptr) {
auto ptr = shared_from_this();
delegate_->DoWorks(ptr);
};
};
// start a thread to run task function.
thread_->thread_ = std::make_shared<std::thread>(task);
APP_LOGD("WorkerThread::CreateThread start thread. ");
}
void WorkerThread::IncTaskCount()
{
task_counter_.fetch_add(1, std::memory_order_relaxed);
}
std::string WorkerThread::GetThreadName()
{
if (thread_ != nullptr) {
return thread_->thread_name_;
} else {
return std::string("");
}
}
std::shared_ptr<Task> WorkerThread::PollFirstTask(void)
{
std::shared_ptr<Task> ret(nullptr);
if (first_task_ != nullptr) {
ret.swap(first_task_);
}
return ret;
}
long WorkerThread::GetTaskCounter(void)
{
long value = task_counter_;
return value;
}
std::shared_ptr<Thread> WorkerThread::GetThread(void)
{
return thread_;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,381 @@
/*
* Copyright (c) 2021 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 "worker_pool.h"
#include <memory>
#include "default_thread_factory.h"
namespace OHOS {
namespace AppExecFwk {
const int WorkerPool::THREAD_UPPER_LIMIT = 256;
const int WorkerPool::MAX_THREAD_LOWER_LIMIT = 1;
const int WorkerPool::CORE_THREAD_LOWER_LIMIT = 0;
const int WorkerPool::COUNT_BITS = sizeof(int) * __CHAR_BIT__ - 3;
const int WorkerPool::CAPACITY = (1 << COUNT_BITS) - 1;
const int WorkerPool::RUNNING = (-(1 << COUNT_BITS));
const int WorkerPool::CLOSING = (0 << COUNT_BITS);
const int WorkerPool::INTERRUPT = (1 << COUNT_BITS);
const int WorkerPool::CLEANED = (2 << COUNT_BITS);
const int WorkerPool::CLOSED = (3 << COUNT_BITS);
WorkerPool::WorkerPool(const std::shared_ptr<WorkerPoolConfig> &config)
{
control_ = CombineToControl(RUNNING, 0);
pool_.clear();
exitPool_.clear();
WorkerPool::factory_ = std::make_shared<DefaultThreadFactory>();
initFlag_.store(Init(config));
stop_.store(false);
}
WorkerPool::~WorkerPool()
{
control_ = 0;
APP_LOGD("WorkerPool::~WorkerPool");
}
bool WorkerPool::Init(const std::shared_ptr<WorkerPoolConfig> &config)
{
if (CheckConfigParams(config) == false) {
APP_LOGE("WorkerPool::checkConfigParams parameters are illegal");
return false;
}
thread_limit_ = config->GetMaxThreadCount();
core_thread_limit_ = config->GetCoreThreadCount();
long keepAliveTime = config->GetKeepAliveTime();
alive_time_Limit_ = keepAliveTime > 0 ? keepAliveTime : 0;
return true;
}
bool WorkerPool::CheckConfigParams(const std::shared_ptr<WorkerPoolConfig> &config)
{
if (config == nullptr) {
APP_LOGE("WorkerPool::CheckConfigParams config is nullptr");
return false;
}
int maxThreadCount = config->GetMaxThreadCount();
int coreThreadCount = config->GetCoreThreadCount();
if (!CheckThreadCount(maxThreadCount, coreThreadCount)) {
APP_LOGE("WorkerPool::CheckConfigParams parameters are illegal, maxThreadCount %{public}d is less than "
"coreThreadCount %{public}d",
maxThreadCount,
coreThreadCount);
return false;
}
if (!CheckMaxThreadCount(maxThreadCount)) {
APP_LOGE("WorkerPool::CheckConfigParams maxThreadCount %{public}d is illegal", maxThreadCount);
return false;
}
if (!CheckCoreThreadCount(coreThreadCount)) {
APP_LOGE("WorkerPool::CheckConfigParams coreThreadCount %{public}d is illegal", coreThreadCount);
return false;
}
return true;
}
bool WorkerPool::CheckThreadCount(int maxThreadCount, int coreThreadCount)
{
return maxThreadCount >= coreThreadCount;
}
bool WorkerPool::CheckMaxThreadCount(int maxThreadCount)
{
if ((maxThreadCount > THREAD_UPPER_LIMIT) || (maxThreadCount < MAX_THREAD_LOWER_LIMIT)) {
return false;
}
return true;
}
bool WorkerPool::CheckCoreThreadCount(int coreThreadCount)
{
if ((coreThreadCount > THREAD_UPPER_LIMIT) || (coreThreadCount < CORE_THREAD_LOWER_LIMIT)) {
return false;
}
return true;
}
long WorkerPool::GetKeepAliveTime(void) const
{
return alive_time_Limit_;
}
int WorkerPool::GetCoreThreadCount(void) const
{
return core_thread_limit_;
}
int WorkerPool::GetMaxThreadCount(void) const
{
return thread_limit_;
}
int WorkerPool::GetWorkCount(void) const
{
int value = control_.load();
return GetWorkingThreadNum(value);
}
std::map<std::string, long> WorkerPool::GetWorkerThreadsInfo(void)
{
std::unique_lock<std::mutex> mLock(poolLock_);
std::map<std::string, long> workerThreadsInfo;
for (auto it = pool_.begin(); it != pool_.end(); it++) {
if ((*it) != nullptr) {
workerThreadsInfo.emplace((*it)->GetThreadName(), (*it)->GetTaskCounter());
}
}
return workerThreadsInfo;
}
void WorkerPool::ClosePool(bool interrupt)
{
APP_LOGD("WorkerPool::ClosePool begin interrupt=%{public}d", interrupt);
std::unique_lock<std::mutex> mLock(poolLock_);
AdvanceStateTo(CLOSING);
InterruptWorkers();
APP_LOGD("WorkerPool::ClosePool end");
}
void WorkerPool::InterruptWorkers(void)
{
APP_LOGD("WorkerPool::InterruptWorkers begin");
if (guardThread_ == nullptr) {
return;
}
poolLock_.unlock();
{
std::unique_lock<std::mutex> lock(exitPoolLock_);
stop_.store(true);
exit_.notify_all();
}
{
std::unique_lock<std::mutex> lock(exitPoolLock_);
exitGuard_.wait(lock);
if (guardThread_->joinable()) {
APP_LOGD("WorkerPool::InterruptWorkers guardThread_ joinable");
guardThread_->join();
guardThread_ = nullptr; // 防止再次手动调用
}
}
APP_LOGD("WorkerPool::InterruptWorkers end");
}
void WorkerPool::CreateGuardThread()
{
APP_LOGD("WorkerPool::CreateGuardThread START");
if (guardThread_ != nullptr) {
APP_LOGW("WorkerPool::CreateGuardThread guardThread_ is not nullptr");
return;
}
auto guardTask = [&]() {
while (true) {
{
std::unique_lock<std::mutex> lock(exitPoolLock_);
if (!exitPool_.empty()) {
exitPool_.front()->Join();
exitPool_.erase(exitPool_.begin());
} else {
exit_.wait(lock, [this] {
return this->stop_.load() || !this->exitPool_.empty();
}); // return 防止先notify 后wait
}
}
if (stop_.load() && exitPool_.empty() && pool_.empty()) {
exitGuard_.notify_all();
APP_LOGD("WorkerPool::CreateGuardThread break while");
break;
}
}
APP_LOGD("WorkerPool::CreateGuardThread STOP");
};
guardThread_ = std::make_shared<std::thread>(guardTask);
}
bool WorkerPool::AddWorker(const std::shared_ptr<Delegate> &delegate, const std::shared_ptr<Task> &task)
{
bool added = false;
if (!initFlag_.load()) {
APP_LOGE("WorkerPool::AddWorker workPool init failed");
return added;
}
if (factory_ == nullptr) {
APP_LOGE("WorkerPool::AddWorker factory_ is nullptr");
return added;
}
if (task == nullptr) {
APP_LOGE("WorkerPool::AddWorker task is nullptr");
return added;
}
if (delegate == nullptr) {
APP_LOGE("WorkerPool::AddWorker delegate is nullptr");
return added;
}
std::unique_lock<std::mutex> mLock(poolLock_);
std::shared_ptr<WorkerThread> newThread = nullptr;
for (;;) {
int value = control_.load();
int num = GetWorkingThreadNum(value);
if (num >= thread_limit_) {
APP_LOGD("WorkerPool::AddWorker thread count exceed limits, num=%{public}d, limits=%{public}d",
num,
thread_limit_);
break;
}
if (!IsRunning(value)) {
APP_LOGD("WorkerPool::AddWorker thread pool is not running. value=%{public}d, closing=%{public}d, "
"count_bits=%{public}d",
value,
CLOSING,
COUNT_BITS);
break;
}
if (CompareAndIncThreadNum(num)) {
newThread = std::make_shared<WorkerThread>(delegate, task, factory_);
if (newThread == nullptr) {
APP_LOGE("WorkerPool::AddWorker create thread fail");
break;
}
newThread->CreateThread();
APP_LOGD("WorkerPool::AddWorker create new thread");
pool_.emplace_back(newThread);
APP_LOGD("POOL SIZE: %{public}d", pool_.size());
APP_LOGD("pool_ add end");
added = true;
break;
}
APP_LOGD("WorkerPool::AddWorker set thread state error. retry. ");
}
return added;
}
void WorkerPool::OnWorkerExit(const std::shared_ptr<WorkerThread> &worker, bool isInterrupted)
{
std::unique_lock<std::mutex> mLock(poolLock_);
APP_LOGD("WorkerPool::OnWorkerExit start");
APP_LOGD("size:%{public}d", pool_.size());
for (auto it = pool_.begin(); it != pool_.end(); it++) {
if ((*it).get() == worker.get()) {
APP_LOGD("WorkerPool::OnWorkerExit erase current, size=%{public}d, threads=%{public}d",
pool_.size(),
GetWorkingThreadNum(control_.load()));
{
std::unique_lock<std::mutex> lock(exitPoolLock_);
exitPool_.emplace_back(worker);
exit_.notify_all();
}
pool_.erase(it);
break;
}
}
APP_LOGD("WorkerPool::OnWorkerExit end");
}
void WorkerPool::AfterRun(const std::shared_ptr<Task> &task)
{}
void WorkerPool::BeforeRun(const std::shared_ptr<Task> &task)
{}
int WorkerPool::GetWorkingThreadNum(int ctl)
{
return ctl & CAPACITY;
}
bool WorkerPool::IsRunning(int ctl)
{
return ctl < CLOSING;
}
int WorkerPool::GetStateFromControl(int ctl)
{
return ctl & ~CAPACITY;
}
void WorkerPool::AdvanceStateTo(int target)
{
APP_LOGD("WorkerPool::AdvanceStateTo begin");
for (;;) {
int current = control_.load();
if ((current >= target) ||
CompareAndSet(control_, current, CombineToControl(target, GetWorkingThreadNum(current)))) {
APP_LOGD("WorkerPool::AdvanceStateTo break");
break;
}
}
APP_LOGD("WorkerPool::AdvanceStateTo end");
}
int WorkerPool::CombineToControl(int state, int count)
{
return state | count;
}
bool WorkerPool::CompareAndIncThreadNum(int expect)
{
int ctl = control_.load();
int state = GetStateFromControl(ctl);
return CompareAndSet(control_, ctl, CombineToControl(state, expect + 1));
}
void WorkerPool::DecrementThread(void)
{
APP_LOGD("WorkerPool::DecrementThread begin");
int curr = control_.load();
while (!CompareAndDecThreadNum(curr)) {
curr = control_.load();
}
APP_LOGD("WorkerPool::DecrementThread end");
}
bool WorkerPool::CompareAndDecThreadNum(int expect)
{
return CompareAndSet(control_, expect, expect - 1);
}
bool WorkerPool::CompareAndDecNum(int expectCount)
{
int curr = control_.load();
int state = GetStateFromControl(curr);
int expectControl = CombineToControl(state, expectCount);
return CompareAndDecThreadNum(expectControl);
}
bool WorkerPool::CompareAndSet(std::atomic<int> &atomicInt, int expect, int desire)
{
return atomicInt.compare_exchange_strong(expect, desire);
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,81 @@
# Copyright (C) 2021 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.
import("//build/test.gni")
import("//foundation/appexecfwk/standard/appexecfwk.gni")
SUBSYSTEM_DIR = "//foundation/appexecfwk/standard"
group("unittest") {
testonly = true
deps = [
"unittest/barrier_handler_test:unittest",
"unittest/base_task_dispatcher_test:unittest",
"unittest/global_task_dispatcher_test:unittest",
"unittest/groupImpl_test:unittest",
"unittest/parallel_task_dispatcher_base_test:unittest",
"unittest/parallel_task_dispatcher_test:unittest",
"unittest/serial_task_dispatcher_test:unittest",
"unittest/spec_dispatcher_config_test:unittest",
"unittest/spec_task_dispatcher_test:unittest",
"unittest/sync_task_test:unittest",
"unittest/task_dispatcher_context_test:unittest",
"unittest/task_executor_test:unittest",
"unittest/task_handler_libevent_adapter_test:unittest",
"unittest/task_test:unittest",
"unittest/work_thread_test:unittest",
"unittest/worker_pool_test:unittest",
]
}
config("dispatcher_test_config") {
configs = []
defines = []
include_dirs = [
"${appexecfwk_path}/common/log/include",
"$SUBSYSTEM_DIR/interfaces/innerkits/libeventhandler/include",
"${dispatcher_path}/include/dispatcher",
"${dispatcher_path}/include/threading",
"${dispatcher_path}/include/task",
"${appexecfwk_path}/kits/appkit/native/app/include",
"${appexecfwk_path}/kits/appkit/native/app/include/task",
"$SUBSYSTEM_DIR/interfaces/innerkits/appexecfwk_base/include",
]
}
ohos_source_set("dispatcher_test_source") {
testonly = true
sources = []
include_dirs = [ "//third_party/json/include" ]
public_configs = [
"//utils/native/base:utils_config",
":dispatcher_test_config",
]
public_deps = [
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
deps = [ "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler" ]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}

View File

@ -0,0 +1,55 @@
# Copyright (c) 2021 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.
import("//build/test.gni")
import("//foundation/appexecfwk/standard/appexecfwk.gni")
ohos_unittest("BarrierHandlerTest") {
module_out_path = "appexecfwk_standard/dispatcher_test"
sources = [
"${dispatcher_path}/src/dispatcher/base_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/global_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/group_impl.cpp",
"${dispatcher_path}/src/dispatcher/parallel_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/parallel_task_dispatcher_base.cpp",
"${dispatcher_path}/src/dispatcher/serial_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/spec_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/task_dispatcher_context.cpp",
"${dispatcher_path}/src/task/barrier_handler.cpp",
"${dispatcher_path}/src/task/sync_task.cpp",
"${dispatcher_path}/src/task/task.cpp",
"${dispatcher_path}/src/threading/default_thread_factory.cpp",
"${dispatcher_path}/src/threading/default_worker_pool_config.cpp",
"${dispatcher_path}/src/threading/task_executor.cpp",
"${dispatcher_path}/src/threading/work_thread.cpp",
"${dispatcher_path}/src/threading/worker_pool.cpp",
]
sources += [ "barrier_handler_test.cpp" ]
configs = [ "${dispatcher_path}/test:dispatcher_test_config" ]
deps = [
"${appexecfwk_path}/common:libappexecfwk_common",
"${dispatcher_path}/test:dispatcher_test_source",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
group("unittest") {
testonly = true
deps = [ ":BarrierHandlerTest" ]
}

View File

@ -0,0 +1,182 @@
/*
* Copyright (c) 2021 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 <gtest/gtest.h>
#define private public
#include "barrier_handler.h"
#undef private
#include "appexecfwk_errors.h"
#include "default_worker_pool_config.h"
using namespace testing;
using namespace testing::ext;
using namespace OHOS::AppExecFwk;
using namespace OHOS;
class BarrierHandlerTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
};
void BarrierHandlerTest::SetUpTestCase()
{}
void BarrierHandlerTest::TearDownTestCase()
{}
void BarrierHandlerTest::SetUp()
{}
void BarrierHandlerTest::TearDown()
{}
std::shared_ptr<BarrierHandler> CreateBarrierHandler()
{
std::shared_ptr<DefaultWorkerPoolConfig> config_ = std::make_shared<DefaultWorkerPoolConfig>();
std::shared_ptr<TaskExecutor> executor = std::make_shared<TaskExecutor>(config_);
std::shared_ptr<BarrierHandler> barrierHandler = std::make_shared<BarrierHandler>(executor);
return barrierHandler;
}
/**
* @tc.number: BarrierHandler_ConstructorTest_001
* @tc.name: Constructor
* @tc.desc: Test BarrierHandlerTest Constructor.
*/
HWTEST(BarrierHandlerTest, BarrierHandler_ConstructorTest_001, TestSize.Level0)
{
auto name = std::string("BarrierHandler_ConstructorTest_001");
GTEST_LOG_(INFO) << name << " start";
std::shared_ptr<BarrierHandler> barrierHandler = CreateBarrierHandler();
EXPECT_NE(barrierHandler, nullptr);
GTEST_LOG_(INFO) << name << " end";
}
/**
* @tc.number: BarrierHandler_interceptTest_001
* @tc.name: intercept
* @tc.desc: Test BarrierHandler intercept.
*/
HWTEST(BarrierHandlerTest, BarrierHandler_interceptTest_001, TestSize.Level0)
{
auto name = std::string("BarrierHandler_interceptTest_001");
GTEST_LOG_(INFO) << name << " start";
std::shared_ptr<BarrierHandler> barrierHandler = CreateBarrierHandler();
//每次添加组任务, 给任务添加监听,当任务完成时候。。。。。判断任务是否应该执行(前面有屏障时候,不立即执行)。
std::shared_ptr<Runnable> runnable = std::make_shared<Runnable>([&]() { GTEST_LOG_(INFO) << name << " Runnable"; });
std::shared_ptr<Task> task = std::make_shared<Task>(runnable, TaskPriority::DEFAULT, nullptr);
ErrCode result = barrierHandler->Intercept(task);
task->Run();
task->AfterTaskExecute();
EXPECT_TRUE(result);
GTEST_LOG_(INFO) << name << " end";
}
/**
* @tc.number: BarrierHandler_interceptTest_002
* @tc.name: intercept
* @tc.desc: Test BarrierHandler intercept.
*/
HWTEST(BarrierHandlerTest, BarrierHandler_interceptTest_002, TestSize.Level0)
{
auto name = std::string("BarrierHandler_interceptTest_002");
GTEST_LOG_(INFO) << name << " start";
std::shared_ptr<BarrierHandler> barrierHandler = CreateBarrierHandler();
// add task
std::shared_ptr<Runnable> runnable = std::make_shared<Runnable>([&]() {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
GTEST_LOG_(INFO) << name << " Runnable";
});
std::shared_ptr<Task> task = std::make_shared<Task>(runnable, TaskPriority::DEFAULT, nullptr);
barrierHandler->Intercept(task);
// add barrier
std::shared_ptr<Runnable> barrierRunnable =
std::make_shared<Runnable>([&]() { GTEST_LOG_(INFO) << name << " barrierTask "; });
std::shared_ptr<Task> barrierTask = std::make_shared<Task>(barrierRunnable, TaskPriority::DEFAULT, nullptr);
barrierHandler->AddBarrier(barrierTask);
// add interceptTask
std::shared_ptr<Runnable> interceptRunnable =
std::make_shared<Runnable>([&]() { GTEST_LOG_(INFO) << name << " interceptRunnable"; });
std::shared_ptr<Task> interceptTask = std::make_shared<Task>(interceptRunnable, TaskPriority::DEFAULT, nullptr);
// intercept result
bool result = barrierHandler->Intercept(interceptTask);
EXPECT_TRUE(result);
GTEST_LOG_(INFO) << name << " end";
}
/**
* @tc.number: BarrierHandler_addBarrierTest_001
* @tc.name: addBarrier
* @tc.desc: Test BarrierHandler addBarrier.
*/
HWTEST(BarrierHandlerTest, BarrierHandler_addBarrierTest_001, TestSize.Level0)
{
auto name = std::string("BarrierHandler_interceptTest_002");
GTEST_LOG_(INFO) << name << " start";
std::shared_ptr<BarrierHandler> barrierHandler = CreateBarrierHandler();
std::atomic<int> count(0);
std::shared_ptr<Runnable> barrierRunnable = std::make_shared<Runnable>([&]() {
std::this_thread::sleep_for(std::chrono::milliseconds(300));
count.fetch_add(1);
GTEST_LOG_(INFO) << name << " add barrier Task ";
});
std::shared_ptr<Task> barrierTask = std::make_shared<Task>(barrierRunnable, TaskPriority::DEFAULT, nullptr);
barrierHandler->AddBarrier(barrierTask);
EXPECT_EQ(count.load(), 0);
std::this_thread::sleep_for(std::chrono::milliseconds(600));
EXPECT_EQ(count.load(), 1);
GTEST_LOG_(INFO) << name << " end";
}
/**
* @tc.number: BarrierHandler_addBarrierTest_002
* @tc.name: addBarrier
* @tc.desc: Test BarrierHandler barrier not execute now.
*/
HWTEST(BarrierHandlerTest, BarrierHandler_addBarrierTest_002, TestSize.Level0)
{
auto name = std::string("BarrierHandler_addBarrierTest_002");
GTEST_LOG_(INFO) << name << " start";
std::shared_ptr<BarrierHandler> barrierHandler = CreateBarrierHandler();
std::atomic<int> count(0);
std::shared_ptr<Runnable> taskRun1 = std::make_shared<Runnable>([&]() {
std::this_thread::sleep_for(std::chrono::milliseconds(300));
count.fetch_add(1);
GTEST_LOG_(INFO) << name << " add barrier Task ";
});
std::shared_ptr<Task> task1 = std::make_shared<Task>(taskRun1, TaskPriority::DEFAULT, nullptr);
barrierHandler->Intercept(task1);
std::shared_ptr<Runnable> taskRun2 = std::make_shared<Runnable>([&]() {
count.fetch_add(1);
GTEST_LOG_(INFO) << name << " add barrier Task ";
});
std::shared_ptr<Task> task2 = std::make_shared<Task>(taskRun2, TaskPriority::DEFAULT, nullptr);
barrierHandler->Intercept(task2);
std::shared_ptr<Runnable> barrierRunnable = std::make_shared<Runnable>([&]() {
std::this_thread::sleep_for(std::chrono::milliseconds(300));
EXPECT_EQ(count.load(), 2);
GTEST_LOG_(INFO) << name << " add barrier Task ";
});
std::shared_ptr<Task> barrierTask = std::make_shared<Task>(barrierRunnable, TaskPriority::DEFAULT, nullptr);
barrierHandler->AddBarrier(barrierTask);
GTEST_LOG_(INFO) << name << " end";
}

View File

@ -0,0 +1,55 @@
# Copyright (c) 2021 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.
import("//build/test.gni")
import("//foundation/appexecfwk/standard/appexecfwk.gni")
ohos_unittest("BaseTaskDispatcherTest") {
module_out_path = "appexecfwk_standard/dispatcher_test"
sources = [
"${dispatcher_path}/src/dispatcher/base_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/global_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/group_impl.cpp",
"${dispatcher_path}/src/dispatcher/parallel_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/parallel_task_dispatcher_base.cpp",
"${dispatcher_path}/src/dispatcher/serial_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/spec_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/task_dispatcher_context.cpp",
"${dispatcher_path}/src/task/barrier_handler.cpp",
"${dispatcher_path}/src/task/sync_task.cpp",
"${dispatcher_path}/src/task/task.cpp",
"${dispatcher_path}/src/threading/default_thread_factory.cpp",
"${dispatcher_path}/src/threading/default_worker_pool_config.cpp",
"${dispatcher_path}/src/threading/task_executor.cpp",
"${dispatcher_path}/src/threading/work_thread.cpp",
"${dispatcher_path}/src/threading/worker_pool.cpp",
]
sources += [ "base_task_dispatcher_test.cpp" ]
configs = [ "${dispatcher_path}/test:dispatcher_test_config" ]
deps = [
"${appexecfwk_path}/common:libappexecfwk_common",
"${dispatcher_path}/test:dispatcher_test_source",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
group("unittest") {
testonly = true
deps = [ ":BaseTaskDispatcherTest" ]
}

View File

@ -0,0 +1,411 @@
/*
* Copyright (c) 2021 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.
*/
#define private public
#undef private
#include "base_task_dispatcher.h"
#include <gtest/gtest.h>
#include <string>
#include <thread>
#include <unistd.h>
#include "task_dispatcher_context.h"
#include "task_dispatcher.h"
#include "serial_task_dispatcher.h"
#include "runnable.h"
using namespace testing;
using namespace testing::ext;
using namespace OHOS::AppExecFwk;
using OHOS::AppExecFwk ::BaseTaskDispatcher;
using OHOS::AppExecFwk::DefaultWorkerPoolConfig;
using OHOS::AppExecFwk::Group;
using OHOS::AppExecFwk::GroupImpl;
using OHOS::AppExecFwk::IteratableTask;
using OHOS::AppExecFwk::Revocable;
using OHOS::AppExecFwk::Runnable;
using OHOS::AppExecFwk ::SerialTaskDispatcher;
using OHOS::AppExecFwk::TaskDispatcher;
using OHOS::AppExecFwk::TaskDispatcherContext;
using OHOS::AppExecFwk::TaskExecutor;
using OHOS::AppExecFwk::TaskPriority;
using OHOS::AppExecFwk::WorkerPoolConfig;
class BaseTaskDispatcherTest : public testing::Test {
public:
void SetUp();
void TearDown();
std::shared_ptr<SerialTaskDispatcher> CreateSerialTaskDispatcher();
std::shared_ptr<TaskDispatcherContext> context;
std::shared_ptr<SerialTaskDispatcher> ptrSerialTaskDispatcher;
static void SetUpTestCase();
static void TearDownTestCase();
};
void BaseTaskDispatcherTest::SetUpTestCase()
{}
void BaseTaskDispatcherTest::TearDownTestCase()
{}
void BaseTaskDispatcherTest::SetUp()
{
context = std::make_shared<TaskDispatcherContext>();
std::string dispatcherName = "test-serial-dispatcher";
TaskPriority taskPriority = TaskPriority::DEFAULT;
ptrSerialTaskDispatcher = context->CreateSerialDispatcher(dispatcherName, taskPriority);
}
void BaseTaskDispatcherTest::TearDown()
{
context = nullptr;
ptrSerialTaskDispatcher = nullptr;
}
std::string Now()
{
time_t now = std::time(0);
char mbstr[10];
std::strftime(mbstr, sizeof(mbstr), "%T", std::localtime(&now));
return mbstr;
}
const std::string Prefix(const std::string &name)
{
return std::string(">>> ") + Now() + std::string(" ") + name + std::string(": ");
}
/**
* @tc.number: CreateBaseTaskDispatcherTest_0100
* @tc.name: test create BaseTaskDispatcher
* @tc.desc: 1.create BaseTaskDispatcher
* 2.get TaskPriority successfully
*/
HWTEST_F(BaseTaskDispatcherTest, CreateBaseTaskDispatcher_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "CreateBaseTaskDispatcher_0100 start";
int priority = ptrSerialTaskDispatcher->GetPriority();
EXPECT_EQ(priority, TaskPriority::DEFAULT);
GTEST_LOG_(INFO) << "CreateBaseTaskDispatcher_0100 end";
}
/**
* @tc.number: SyncDispatchBarrier_0100
* @tc.name: test SyncDispatchBarrier
* @tc.desc: 1.create SerialTaskDispatcher
* 2.SyncDispatchBarrier successfully
*/
HWTEST_F(BaseTaskDispatcherTest, SyncDispatchBarrier_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "SyncDispatchBarrier_0100 start";
const std::string name("SyncDispatchBarrier_0100");
GTEST_LOG_(INFO) << Prefix(name) << "begin thread " << std::this_thread::get_id();
// init
std::atomic<int> count(0);
EXPECT_EQ(count.load(), 0);
long sleep1 = 200;
ptrSerialTaskDispatcher->SyncDispatchBarrier(std::make_shared<Runnable>([&]() {
auto time = std::chrono::milliseconds(sleep1);
std::this_thread::sleep_for(time);
int index = count.fetch_add(1);
EXPECT_EQ(index, 0);
GTEST_LOG_(INFO) << Prefix(name) << "SyncDispatchBarrier-" << 1 << " thread " << std::this_thread::get_id()
<< ", sleep for " << sleep1 << " ms";
}));
// serial execute
EXPECT_EQ(count.load(), 1);
long sleep2 = 100;
ptrSerialTaskDispatcher->SyncDispatchBarrier(std::make_shared<Runnable>([&]() {
auto time = std::chrono::milliseconds(sleep2);
std::this_thread::sleep_for(time);
int index = count.fetch_add(1);
EXPECT_EQ(index, 1);
GTEST_LOG_(INFO) << Prefix(name) << "SyncDispatchBarrier-" << 2 << " thread " << std::this_thread::get_id()
<< ", sleep for " << sleep2 << " ms";
}));
// serial execute
EXPECT_EQ(count.load(), 2);
long wait = sleep1 + sleep2 + 100;
GTEST_LOG_(INFO) << Prefix(name) << "wait for " << (wait);
auto time = std::chrono::milliseconds(wait);
std::this_thread::sleep_for(time);
EXPECT_EQ(count.load(), 2);
GTEST_LOG_(INFO) << "sync thread end " << std::this_thread::get_id();
GTEST_LOG_(INFO) << Prefix(name) << "end ";
GTEST_LOG_(INFO) << "SyncDispatchBarrier_0100 end";
}
/**
* @tc.number: AsyncDispatchBarrier_0100
* @tc.name: test AsyncDispatchBarrier
* @tc.desc: 1.create SerialTaskDispatcher
* 2.AsyncDispatchBarrier successfully
*/
HWTEST_F(BaseTaskDispatcherTest, AsyncDispatchBarrier_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "AsyncDispatchBarrier_0100 start";
const std::string name("AsyncDispatchBarrier_0100");
GTEST_LOG_(INFO) << Prefix(name) << "begin thread " << std::this_thread::get_id();
std::atomic<int> count(0);
long sleep1 = 200;
ptrSerialTaskDispatcher->AsyncDispatchBarrier(std::make_shared<Runnable>([&]() {
auto time = std::chrono::milliseconds(sleep1);
std::this_thread::sleep_for(time);
int index = count.fetch_add(1);
EXPECT_EQ(index, 0);
GTEST_LOG_(INFO) << Prefix(name) << "AsyncDispatchBarrier-" << index << " thread " << std::this_thread::get_id()
<< ", sleep for " << sleep1 << " ms";
}));
// async execute
ASSERT_LT(count.load(), 1);
long sleep2 = 100;
ptrSerialTaskDispatcher->AsyncDispatchBarrier(std::make_shared<Runnable>([&]() {
auto time = std::chrono::milliseconds(sleep2);
std::this_thread::sleep_for(time);
int index = count.fetch_add(1);
EXPECT_EQ(index, 1);
GTEST_LOG_(INFO) << Prefix(name) << "AsyncDispatchBarrier-" << index << " thread " << std::this_thread::get_id()
<< ", sleep for " << sleep2 << " ms";
}));
ASSERT_LT(count.load(), 2);
long wait = sleep1 + sleep2 + 100;
GTEST_LOG_(INFO) << Prefix(name) << "wait for " << (wait);
auto time = std::chrono::milliseconds(wait);
std::this_thread::sleep_for(time);
EXPECT_EQ(count.load(), 2);
GTEST_LOG_(INFO) << Prefix(name) << "end ";
GTEST_LOG_(INFO) << "AsyncDispatchBarrier_0100 end";
}
/**
* @tc.number: CreateDispatchGroup_0100
* @tc.name: test CreateDispatchGroup
* @tc.desc: 1.create SerialTaskDispatcher
* 2.CreateDispatchGroup successfully
*/
HWTEST_F(BaseTaskDispatcherTest, CreateDispatchGroup_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "CreateDispatchGroup_0100 start";
std::shared_ptr<Group> gptr = ptrSerialTaskDispatcher->CreateDispatchGroup();
ASSERT_TRUE(ptrSerialTaskDispatcher->GroupDispatchWait(gptr, 10));
GTEST_LOG_(INFO) << "CreateDispatchGroup_0100 end";
}
/**
* @tc.number: AsyncGroupDispatch_0100
* @tc.name: test AsyncGroupDispatch
* @tc.desc: 1.create SerialTaskDispatcher
* 2.AsyncGroupDispatch successfully
*/
HWTEST_F(BaseTaskDispatcherTest, AsyncGroupDispatch_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "AsyncGroupDispatch_0100 start";
const std::string name("AsyncGroupDispatch_0100");
GTEST_LOG_(INFO) << Prefix(name) << "begin thread " << std::this_thread::get_id();
std::shared_ptr<Group> gptr = ptrSerialTaskDispatcher->CreateDispatchGroup();
std::atomic<int> count(0);
long sleep1 = 200;
ptrSerialTaskDispatcher->AsyncGroupDispatch(gptr, std::make_shared<Runnable>([&count, &sleep1, &name]() {
auto time = std::chrono::milliseconds(sleep1);
std::this_thread::sleep_for(time);
int index = count.fetch_add(1);
EXPECT_EQ(index, 0);
GTEST_LOG_(INFO) << Prefix(name) << "AsyncGroupDispatch-" << index << " thread " << std::this_thread::get_id()
<< ", sleep for " << sleep1 << " ms";
}));
// async execute
ASSERT_LT(count.load(), 1);
long sleep2 = 100;
ptrSerialTaskDispatcher->AsyncGroupDispatch(gptr, std::make_shared<Runnable>([&count, &sleep2, &name]() {
auto time = std::chrono::milliseconds(sleep2);
std::this_thread::sleep_for(time);
int index = count.fetch_add(1);
EXPECT_EQ(index, 1);
GTEST_LOG_(INFO) << Prefix(name) << "AsyncGroupDispatch-" << index << " thread " << std::this_thread::get_id()
<< ", sleep for " << sleep2 << " ms";
}));
ASSERT_LT(count.load(), 2);
long wait = sleep1 + sleep2 + 100;
GTEST_LOG_(INFO) << Prefix(name) << "wait for " << (wait);
auto time = std::chrono::milliseconds(wait);
std::this_thread::sleep_for(time);
EXPECT_EQ(count.load(), 2);
GTEST_LOG_(INFO) << Prefix(name) << "end ";
GTEST_LOG_(INFO) << "AsyncGroupDispatch_0100 end";
}
/**
* @tc.number: ApplyDispatch_0100
* @tc.name: test ApplyDispatch
* @tc.desc: 1.create SerialTaskDispatcher
* 2.ApplyDispatch successfully
*/
HWTEST_F(BaseTaskDispatcherTest, ApplyDispatch_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "ApplyDispatch_0100 start";
const std::string name("ApplyDispatch_0100");
GTEST_LOG_(INFO) << Prefix(name) << "begin thread " << std::this_thread::get_id();
std::atomic<int> count(0);
long sleep1 = 101;
auto repeats1 = std::make_shared<IteratableTask<long>>([&](long index) {
auto time = std::chrono::milliseconds(sleep1);
std::this_thread::sleep_for(time);
count.fetch_add(1);
GTEST_LOG_(INFO) << Prefix(name) << "repeat1-" << index << ", thread " << std::this_thread::get_id()
<< ", sleep for " << sleep1 << " ms";
});
ptrSerialTaskDispatcher->ApplyDispatch(repeats1, 10);
long sleep2 = 100;
auto repeats2 = std::make_shared<IteratableTask<long>>([&](long index) {
auto time = std::chrono::milliseconds(sleep2);
std::this_thread::sleep_for(time);
count.fetch_add(1);
GTEST_LOG_(INFO) << Prefix(name) << "repeat2-" << index << ", thread " << std::this_thread::get_id()
<< ", sleep for " << sleep2 << " ms";
});
ptrSerialTaskDispatcher->ApplyDispatch(repeats2, 10);
// async execute
ASSERT_LT(count.load(), 20);
long wait = sleep1 * 10 + sleep2 * 10 + 100 + 100;
GTEST_LOG_(INFO) << Prefix(name) << "wait for " << (wait);
auto time = std::chrono::milliseconds(wait);
std::this_thread::sleep_for(time);
EXPECT_EQ(count.load(), 20);
GTEST_LOG_(INFO) << Prefix(name) << "end ";
GTEST_LOG_(INFO) << "ApplyDispatch_0100 end";
}
/**
* @tc.number: ApplyDispatch_0200
* @tc.name: test ApplyDispatch
* @tc.desc: 1.create SerialTaskDispatcher
* 2.ApplyDispatch iterations <0
*/
HWTEST_F(BaseTaskDispatcherTest, ApplyDispatch_0200, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "ApplyDispatch_0200 start";
const std::string name("ApplyDispatch_0200");
GTEST_LOG_(INFO) << Prefix(name) << "begin thread " << std::this_thread::get_id();
ptrSerialTaskDispatcher->ApplyDispatch(nullptr, 10);
GTEST_LOG_(INFO) << Prefix(name) << "end ";
GTEST_LOG_(INFO) << "ApplyDispatch_0200 end";
}
/**
* @tc.number: ApplyDispatch_0300
* @tc.name: test ApplyDispatch
* @tc.desc: 1.create SerialTaskDispatcher
* 2.ApplyDispatch task is nullptr
*/
HWTEST_F(BaseTaskDispatcherTest, ApplyDispatch_0300, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "ApplyDispatch_0300 start";
const std::string name("ApplyDispatch_0300");
GTEST_LOG_(INFO) << Prefix(name) << "begin thread " << std::this_thread::get_id();
auto repeats1 = std::make_shared<IteratableTask<long>>(
[&](long index) { GTEST_LOG_(INFO) << "Error:ApplyDispatch_0300 is run "; });
ptrSerialTaskDispatcher->ApplyDispatch(repeats1, -1);
GTEST_LOG_(INFO) << Prefix(name) << "end ";
GTEST_LOG_(INFO) << "ApplyDispatch_0300 end";
}
/**
* @tc.number:GroupDispatchWait_0100
* @tc.name: test GroupDispatchWait
* @tc.desc: 1.create SerialTaskDispatcher
* 2.GroupDispatchWait successfully
*/
HWTEST_F(BaseTaskDispatcherTest, GroupDispatchWait_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "GroupDispatchWait_0100 start";
std::shared_ptr<Group> gptr = ptrSerialTaskDispatcher->CreateDispatchGroup();
ASSERT_TRUE(ptrSerialTaskDispatcher->GroupDispatchWait(gptr, 0));
GTEST_LOG_(INFO) << "GroupDispatchWait_0100 end";
}
/**
* @tc.number:GroupDispatchNotify_0100
* @tc.name: test GroupDispatchNotify
* @tc.desc: 1.create SerialTaskDispatcher
* 2.GroupDispatchNotify successfully
*/
HWTEST_F(BaseTaskDispatcherTest, GroupDispatchNotify_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "GroupDispatchNotify_0100 start";
std::atomic<int> count(0);
std::shared_ptr<Group> gptr = ptrSerialTaskDispatcher->CreateDispatchGroup();
count.fetch_add(1);
std::function<void()> task = [&]() {
count.fetch_add(1);
GTEST_LOG_(INFO) << "GroupDispatchNotify_0100 notify task is run";
};
std::shared_ptr<Runnable> rptr = std::make_shared<Runnable>(task);
EXPECT_EQ(count.load(), 1);
GTEST_LOG_(INFO) << "GroupDispatchNotify_0100 end";
}
/**
* @tc.number:GetPriority_0100
* @tc.name: test GetPriority
* @tc.desc: 1.create SerialTaskDispatcher
* 2.GetPriority successfully
*/
HWTEST_F(BaseTaskDispatcherTest, GetPriority_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "GetPriority_0100 start";
EXPECT_EQ(ptrSerialTaskDispatcher->GetPriority(), TaskPriority::DEFAULT);
GTEST_LOG_(INFO) << "GetPriority_0100 end";
}
/**
* @tc.number:TracePointBeforePost_0100
* @tc.name: TracePointBeforePost
* @tc.desc: 1.create SerialTaskDispatcher
* 2.TracePointBeforePost successfully
*/
HWTEST_F(BaseTaskDispatcherTest, TracePointBeforePost_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "TracePointBeforePost_0100 start";
Runnable TestTask([]() { GTEST_LOG_(INFO) << "TracePointBeforePost_0100 task"; });
std::shared_ptr<Runnable> runnable = std::make_shared<Runnable>(TestTask);
std::shared_ptr<Task> task = std::make_shared<Task>(runnable, TaskPriority::DEFAULT, ptrSerialTaskDispatcher);
std::string dispatcherName = "TracePointBeforePost_0100 ";
ptrSerialTaskDispatcher->TracePointBeforePost(task, true, dispatcherName);
GTEST_LOG_(INFO) << "TracePointBeforePost_0100 end";
}
/**
* @tc.number:TracePointAfterPost_0100
* @tc.name: TracePointAfterPost
* @tc.desc: 1.create SerialTaskDispatcher
* 2.TracePointAfterPost successfully
*/
HWTEST_F(BaseTaskDispatcherTest, TracePointAfterPost_0100, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "TracePointAfterPost_0100 start";
Runnable TestTask([]() { GTEST_LOG_(INFO) << "TracePointBeforePost_0100 task"; });
std::shared_ptr<Runnable> runnable = std::make_shared<Runnable>(TestTask);
std::shared_ptr<Task> task = std::make_shared<Task>(runnable, TaskPriority::DEFAULT, ptrSerialTaskDispatcher);
std::string dispatcherName = "TracePointAfterPost_0100 ";
ptrSerialTaskDispatcher->TracePointAfterPost(task, false, dispatcherName);
GTEST_LOG_(INFO) << "TracePointAfterPost_0100 end";
}

View File

@ -0,0 +1,55 @@
# Copyright (c) 2021 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.
import("//build/test.gni")
import("//foundation/appexecfwk/standard/appexecfwk.gni")
ohos_unittest("GlobalTaskDispatcherTest") {
module_out_path = "appexecfwk_standard/dispatcher_test"
sources = [
"${dispatcher_path}/src/dispatcher/base_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/global_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/group_impl.cpp",
"${dispatcher_path}/src/dispatcher/parallel_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/parallel_task_dispatcher_base.cpp",
"${dispatcher_path}/src/dispatcher/serial_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/spec_task_dispatcher.cpp",
"${dispatcher_path}/src/dispatcher/task_dispatcher_context.cpp",
"${dispatcher_path}/src/task/barrier_handler.cpp",
"${dispatcher_path}/src/task/sync_task.cpp",
"${dispatcher_path}/src/task/task.cpp",
"${dispatcher_path}/src/threading/default_thread_factory.cpp",
"${dispatcher_path}/src/threading/default_worker_pool_config.cpp",
"${dispatcher_path}/src/threading/task_executor.cpp",
"${dispatcher_path}/src/threading/work_thread.cpp",
"${dispatcher_path}/src/threading/worker_pool.cpp",
]
sources += [ "global_task_dispatcher_test.cpp" ]
configs = [ "${dispatcher_path}/test:dispatcher_test_config" ]
deps = [
"${appexecfwk_path}/common:libappexecfwk_common",
"${dispatcher_path}/test:dispatcher_test_source",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
group("unittest") {
testonly = true
deps = [ ":GlobalTaskDispatcherTest" ]
}

Some files were not shown because too many files have changed in this diff Show More