IssueNo:#I4VUGB

Description: Delete process_optimizer, lmks module
Sig:SIG_ApplicationFramework
Feature or Bugfix:Bugfix
Binary Source:No

Signed-off-by: jsj <jinsenjun@huawei.com>
Change-Id: I648be352504f1ab23ea42da0dfe69ac372de6934
This commit is contained in:
jsj
2022-03-01 11:50:27 +00:00
parent 221ce52184
commit b5f696da0b
41 changed files with 1 additions and 6432 deletions
-39
View File
@@ -31,46 +31,11 @@ config("appmgr_config") {
group("ams_target") {
deps = [
":libams",
":lmks",
":lmks.rc",
"examples:appmgrserviceregtest",
"examples:appspawnclienttest",
]
}
ohos_executable("lmks") {
include_dirs = [
"include/lmks",
"//utils/native/base/include",
]
sources = [
"src/lmks/lmks_main.cpp",
"src/lmks/lmks_server.cpp",
"src/lmks/lmks_utils.cpp",
]
cflags = []
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
deps = [ "//utils/native/base:utils" ]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
install_enable = true
subsystem_name = "aafwk"
part_name = "ability_runtime"
}
ohos_prebuilt_etc("lmks.rc") {
source = "lmks.cfg"
relative_install_dir = "init"
subsystem_name = "aafwk"
part_name = "ability_runtime"
}
ohos_shared_library("libams") {
sources = [
"src/ability_running_record.cpp",
@@ -86,11 +51,7 @@ ohos_shared_library("libams") {
"src/app_spawn_client.cpp",
"src/app_spawn_msg_wrapper.cpp",
"src/app_spawn_socket.cpp",
"src/cgroup_manager.cpp",
"src/lmks_client.cpp",
"src/module_running_record.cpp",
"src/process_optimizer.cpp",
"src/process_optimizer_uba.cpp",
"src/remote_client_manager.cpp",
"src/system_environment_information.cpp",
]
@@ -43,8 +43,6 @@
#include "bundle_info.h"
#include "istart_specified_ability_response.h"
#include "process_optimizer_uba.h"
#include "ohos/aafwk/content/want.h"
namespace OHOS {
@@ -405,34 +403,6 @@ public:
*/
virtual void AddAppDeathRecipient(const pid_t pid, const sptr<AppDeathRecipient> &appDeathRecipient) const;
/**
* ProcessOptimizerInit, Process Optimizer init.
*
* @param
* @return ERR_OK, return back success, others fail.
*/
virtual int32_t ProcessOptimizerInit();
/**
* OptimizerAbilityStateChanged, Optimizer processing ability state changes.
*
* @param ability, the ability info.
* @param state, the ability state before change.
*
* @return
*/
virtual void OptimizerAbilityStateChanged(
const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state);
/**
* OptimizerAppStateChanged, Optimizer processing app state changes.
*
* @param appRecord, the app information.
* @param state, the app before change.
* @return
*/
virtual void OptimizerAppStateChanged(
const std::shared_ptr<AppRunningRecord> &appRecord, const ApplicationState state);
void HandleTimeOut(const InnerEvent::Pointer &event);
@@ -455,7 +425,7 @@ public:
int CompelVerifyPermission(const std::string &permission, int pid, int uid, std::string &message);
/**
* SuspendApplication, Application state changed.
* OnAppStateChanged, Application state changed.
*
* @param appRecord, the app information.
* @param state, the app state.
@@ -559,55 +529,6 @@ private:
const std::shared_ptr<AbilityInfo> &abilityInfo, const std::shared_ptr<AppRunningRecord> &appRecord,
const HapModuleInfo &hapModuleInfo, const std::shared_ptr<AAFwk::Want> &want);
/**
* UnsuspendApplication, Application process state switch to unsuspend.
*
* @param appRecord, the app information.
*
* @return
*/
void UnsuspendApplication(const std::shared_ptr<AppRunningRecord> &appRecord);
/**
* SuspendApplication, Application process state switch to suspend.
*
* @param appRecord, the app information.
*
* @return
*/
void SuspendApplication(const std::shared_ptr<AppRunningRecord> &appRecord);
/**
* LowMemoryApplicationAlert, Application low memory alert.
*
* @param appRecord, the app information.
* @param level, the app low memory level.
*
* @return
*/
void LowMemoryApplicationAlert(
const std::shared_ptr<AppRunningRecord> &appRecord, const CgroupManager::LowMemoryLevel level);
/**
* GetAbilityOwnerApp, Get the process record of ability.
*
* @param abilityRecord, the ability information.
*
* @return process record.
*/
std::shared_ptr<AppRunningRecord> GetAbilityOwnerApp(
const std::shared_ptr<AbilityRunningRecord> &abilityRecord) const;
/**
* GetAbilityRunningRecordByAbilityToken, Get the ability record by token.
*
* @param abilityToken, the ability token.
*
* @return ability record.
*/
std::shared_ptr<AbilityRunningRecord> GetAbilityRunningRecordByAbilityToken(
const sptr<IRemoteObject> &abilityToken) const;
/**
* StartProcess, load the ability that needed to be started(Start on a new boot process).
*
@@ -803,7 +724,6 @@ private:
std::shared_ptr<AppProcessManager> appProcessManager_;
std::shared_ptr<RemoteClientManager> remoteClientManager_;
std::shared_ptr<AppRunningManager> appRunningManager_;
std::shared_ptr<ProcessOptimizerUBA> processOptimizerUBA_;
std::shared_ptr<AMSEventHandler> eventHandler_;
std::shared_ptr<Configuration> configuration_;
std::mutex serviceLock_;
-99
View File
@@ -1,99 +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_SERVICES_APPMGR_INCLUDE_CGROUP_MANAGER_H
#define FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_CGROUP_MANAGER_H
#include <memory>
#include <functional>
#include <shared_mutex>
#include "event_handler.h"
#include "file_descriptor_listener.h"
#include "nocopyable.h"
#include "singleton.h"
#include "unique_fd.h"
namespace OHOS {
namespace AppExecFwk {
class CgroupManager : public FileDescriptorListener, public std::enable_shared_from_this<CgroupManager> {
DECLARE_DELAYED_SINGLETON(CgroupManager)
public:
enum SchedPolicy {
SCHED_POLICY_DEFAULT = 0,
SCHED_POLICY_BACKGROUND,
SCHED_POLICY_FREEZED,
SCHED_POLICY_MAX
};
enum LowMemoryLevel {
LOW_MEMORY_LEVEL_LOW = 0,
LOW_MEMORY_LEVEL_MEDIUM,
LOW_MEMORY_LEVEL_CRITICAL,
LOW_MEMORY_LEVEL_MAX
};
enum SchedPolicyCpu {
SCHED_POLICY_CPU_DEFAULT = 0,
SCHED_POLICY_CPU_BACKGROUND,
SCHED_POLICY_CPU_MAX
};
enum SchedPolicyFreezer {
SCHED_POLICY_FREEZER_FROZEN = 0,
SCHED_POLICY_FREEZER_THAWED,
SCHED_POLICY_FREEZER_MAX
};
std::function<void(CgroupManager::LowMemoryLevel)> LowMemoryAlert;
public:
virtual bool Init();
virtual bool InitCheck();
virtual bool IsInited() const;
virtual bool SetThreadSchedPolicy(int tid, SchedPolicy schedPolicy);
virtual bool SetProcessSchedPolicy(int pid, SchedPolicy schedPolicy);
virtual void OnReadable(int32_t fd) override;
private:
std::shared_ptr<EventHandler> eventHandler_;
int cpusetTasksFds_[SCHED_POLICY_CPU_MAX] = {-1};
int cpuctlTasksFds_[SCHED_POLICY_CPU_MAX] = {-1};
int freezerTasksFds_[SCHED_POLICY_FREEZER_MAX] = {-1};
int memoryEventControlFd_ = -1;
int memoryEventFds_[LOW_MEMORY_LEVEL_MAX] = {-1};
int memoryPressureFds_[LOW_MEMORY_LEVEL_MAX] = {-1};
bool RegisterLowMemoryMonitor(const int memoryEventFds[LOW_MEMORY_LEVEL_MAX],
const int memoryPressureFds[LOW_MEMORY_LEVEL_MAX], const int memoryEventControlFd, const LowMemoryLevel level,
const std::shared_ptr<EventHandler> &eventHandler);
bool InitCpusetTasksFds(UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX]);
bool InitCpuctlTasksFds(UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX]);
bool InitFreezerTasksFds(UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX]);
bool InitMemoryEventControlFd(UniqueFd &memoryEventControlFd);
bool InitMemoryEventFds(UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX]);
bool InitMemoryPressureFds(UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX]);
bool SetCpusetSubsystem(const int tid, const SchedPolicy schedPolicy);
bool SetCpuctlSubsystem(const int tid, const SchedPolicy schedPolicy);
bool SetFreezerSubsystem(const int tid, const SchedPolicyFreezer state);
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_CGROUP_MANAGER_H
@@ -1,56 +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_SERVICES_APPMGR_INCLUDE_LMKS_SERVER_H
#define FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_LMKS_SERVER_H
#include <string>
#include <sys/un.h>
#include "lmks_utils.h"
namespace OHOS {
namespace LMKS {
constexpr uint32_t MAX_LMKS_TARGETS = 6; // max number of lmks command targets
constexpr uint32_t MAX_LMKS_TARGETS_SIZE = sizeof(int) * (MAX_LMKS_TARGETS * 2 + 1); // max packet length
using LMKS_PACKET = int[MAX_LMKS_TARGETS_SIZE / sizeof(int)];
class LmksServer {
public:
LmksServer();
virtual ~LmksServer();
void StartServer();
private:
int RegisterSocket();
int WaitConnection();
int RecvSocketMessage(int connectFd, void *buf, int len);
int SendSocketMessage(int connectFd, const void *buf, int len);
void ProcessMessage(int connectFd, LMKS_PACKET cmds, int len);
void CloseSocket();
private:
bool isStart_;
int socketFd_;
struct sockaddr_un socketAddr_;
uint32_t socketAddrLen_;
std::shared_ptr<LmksUtils> lmksUtils_;
};
} // namespace LMKS
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_LMKS_SERVER_H
-39
View File
@@ -1,39 +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_SERVICES_APPMGR_INCLUDE_LMKS_UTILS_H
#define FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_LMKS_UTILS_H
#include <string>
#include <sys/types.h>
namespace OHOS {
namespace LMKS {
class LmksUtils {
public:
LmksUtils();
virtual ~LmksUtils();
int RemoveProcess(pid_t pid);
private:
std::string GetProcName(pid_t pid);
int GetProcSize(pid_t pid);
ssize_t ReadAll(int fd, char *buf, size_t maxLen);
};
} // namespace LMKS
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_LMKS_UTILS_H
-62
View File
@@ -1,62 +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_SERVICES_APPMGR_INCLUDE_LMKS_CLIENT_H
#define FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_LMKS_CLIENT_H
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "ability_running_record.h"
#include "app_running_record.h"
#include "nocopyable.h"
namespace OHOS {
namespace AppExecFwk {
union LmksClientMsg {
int32_t result = -1;
int8_t resultBuf[sizeof(int32_t)];
};
class LmksClient : public NoCopyable {
public:
using Targets = std::vector<std::pair<int, int>>;
public:
LmksClient();
virtual ~LmksClient();
virtual int32_t Open();
virtual void Close();
virtual bool IsOpen() const;
virtual int32_t Target(const Targets &targets);
virtual int32_t ProcPrio(pid_t pid, uid_t uid, int oomAdj);
virtual int32_t ProcRemove(pid_t pid);
virtual bool ProcPurge();
static bool CheckOomAdj(int v);
private:
bool Write(const void *buf, size_t len);
bool Read(void *buf, size_t len);
private:
int socket_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_LMKS_CLIENT_H
@@ -171,16 +171,6 @@ public:
const std::shared_ptr<ApplicationInfo> GetAppInfo();
private:
/**
* OptimizerAbilityStateChanged, Optimizer processing ability state changes.
*
* @param ability, the ability info.
* @param state, the ability state.
*
* @return
*/
void OptimizerAbilityStateChanged(const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state);
void SendEvent(uint32_t msg, int64_t timeOut, const std::shared_ptr<AbilityRunningRecord> &abilityRecord);
ModuleRecordState GetState() const;
@@ -1,97 +0,0 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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_SERVICES_APPMGR_INCLUDE_PROCESS_OPTIMIZER_H
#define FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_PROCESS_OPTIMIZER_H
#include <functional>
#include <list>
#include <memory>
#include <set>
#include <string>
#include "ability_running_record.h"
#include "app_running_record.h"
#include "cgroup_manager.h"
#include "lmks_client.h"
#include "event_handler.h"
#include "nocopyable.h"
namespace OHOS {
namespace AppExecFwk {
class ProcessOptimizer : public NoCopyable {
public:
using EventHandlerPtr = std::shared_ptr<EventHandler>;
using AppPtr = std::shared_ptr<AppRunningRecord>;
using AbilityPtr = std::shared_ptr<AbilityRunningRecord>;
using CgroupManagerPtr = std::shared_ptr<CgroupManager>;
using LmksClientPtr = std::shared_ptr<LmksClient>;
static constexpr int APP_SUSPEND_TIMEOUT_DEFAULT = 5000; // in milliseconds
static constexpr int APP_SUSPEND_TIMEOUT_MAX = 30 * 1000; // in milliseconds
public:
ProcessOptimizer(const LmksClientPtr &lmksClient = nullptr, int suspendTimeout = APP_SUSPEND_TIMEOUT_DEFAULT);
virtual ~ProcessOptimizer();
public:
// callbacks
std::function<void(AppPtr)> AppSuspended;
std::function<void(AppPtr)> AppResumed;
std::function<void(AppPtr, CgroupManager::LowMemoryLevel)> AppLowMemoryAlert;
std::function<AppPtr(AbilityPtr)> GetAbilityOwnerApp;
public:
virtual bool Init();
virtual void OnAppAdded(const AppPtr &app);
virtual void OnAppRemoved(const AppPtr &app);
virtual void OnAppStateChanged(const AppPtr &app, const ApplicationState oldState);
virtual void OnAbilityStarted(const AbilityPtr &ability);
virtual void OnAbilityConnected(const AbilityPtr &ability, const AbilityPtr &targetAbility);
virtual void OnAbilityDisconnected(const AbilityPtr &ability, const AbilityPtr &targetAbility);
virtual void OnAbilityStateChanged(const AbilityPtr &ability, const AbilityState oldState);
virtual void OnAbilityVisibleChanged(const AbilityPtr &ability);
virtual void OnAbilityPerceptibleChanged(const AbilityPtr &ability);
virtual void OnAbilityRemoved(const AbilityPtr &ability);
protected:
bool SetAppOomAdj(const AppPtr &app, int oomAdj);
bool SetAppSchedPolicy(const AppPtr &app, const CgroupManager::SchedPolicy schedPolicy);
virtual void OnLowMemoryAlert(const CgroupManager::LowMemoryLevel level);
private:
bool UpdateAppOomAdj(const AppPtr &app);
bool GetAppOomAdj(const AppPtr &app,ApplicationState state,int &oomAdj,int &oomAdjMax);
bool UpdateAppSchedPolicy(const AppPtr &app);
void StartAppSuspendTimer(const AppPtr &app);
void StopAppSuspendTimer(const AppPtr &app);
void SuspendApp(const AppPtr &app);
std::string GetAppSuspendTimerName(const AppPtr &app);
private:
using AppLru = std::list<AppPtr>;
using SuspendTimers = std::set<std::string>;
LmksClientPtr lmksClient_;
AppLru appLru_;
EventHandlerPtr eventHandler_;
SuspendTimers suspendTimers_;
int suspendTimeout_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_PROCESS_OPTIMIZER_H
@@ -1,174 +0,0 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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_SERVICES_APPMGR_INCLUDE_PROCESS_OPTIMIZER_UBA_H
#define FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_PROCESS_OPTIMIZER_UBA_H
#include <chrono>
#include <functional>
#include <string>
#include <vector>
#include <variant>
#include "process_optimizer.h"
namespace OHOS {
namespace AppExecFwk {
// UBA short for User Behavior Analysis
using UbaService = int;
using UbaServicePtr = std::shared_ptr<UbaService>;
class ProcessOptimizerUBA : public ProcessOptimizer {
public:
using AbilityToken = sptr<IRemoteObject>;
public:
ProcessOptimizerUBA(const UbaServicePtr &ubaService, const LmksClientPtr &lmksClient = nullptr,
int suspendTimeout = APP_SUSPEND_TIMEOUT_DEFAULT);
virtual ~ProcessOptimizerUBA();
public:
// callbacks
std::function<AbilityPtr(AbilityToken)> GetAbilityByToken;
public:
void OnAppAdded(const AppPtr &app) override;
void OnAppRemoved(const AppPtr &app) override;
void OnAppStateChanged(const AppPtr &app, const ApplicationState oldState) override;
void OnAbilityStarted(const AbilityPtr &ability) override;
void OnAbilityConnected(const AbilityPtr &ability, const AbilityPtr &targetAbility) override;
void OnAbilityDisconnected(const AbilityPtr &ability, const AbilityPtr &targetAbility) override;
void OnAbilityStateChanged(const AbilityPtr &ability, const AbilityState oldState) override;
void OnAbilityVisibleChanged(const AbilityPtr &ability) override;
void OnAbilityPerceptibleChanged(const AbilityPtr &ability) override;
void OnAbilityRemoved(const AbilityPtr &ability) override;
protected:
void OnLowMemoryAlert(const CgroupManager::LowMemoryLevel level) override;
private:
using Clock = std::chrono::system_clock;
using TimePoint = Clock::time_point;
class BaseAbilityAction {
public:
BaseAbilityAction(const AbilityPtr &ability);
~BaseAbilityAction() = default;
TimePoint GetTime() const;
std::string GetTimeString() const;
const std::string &GetName() const;
private:
TimePoint time_;
std::string name_;
};
class StartAbilityAction : public BaseAbilityAction {
public:
StartAbilityAction(const AbilityPtr &ability, const AbilityPtr &preAbility);
~StartAbilityAction() = default;
const std::string &GetPreName() const;
private:
std::string preName_;
};
class ConnectAbilityAction : public BaseAbilityAction {
public:
ConnectAbilityAction(const AbilityPtr &ability, const AbilityPtr &targetAbility);
~ConnectAbilityAction() = default;
const std::string &GetTargetName() const;
private:
std::string targetName_;
};
class DisconnectAbilityAction : public BaseAbilityAction {
public:
DisconnectAbilityAction(const AbilityPtr &ability, const AbilityPtr &targetAbility);
~DisconnectAbilityAction() = default;
const std::string &GetTargetName() const;
private:
std::string targetName_;
};
class ChangeAbilityStateAction : public BaseAbilityAction {
public:
ChangeAbilityStateAction(const AbilityPtr &ability, const AbilityState oldState);
~ChangeAbilityStateAction() = default;
AbilityState GetOldState() const;
AbilityState GetNewState() const;
private:
AbilityState oldState_;
AbilityState newState_;
};
class ChangeAbilityVisible : public BaseAbilityAction {
public:
ChangeAbilityVisible(const AbilityPtr &ability);
~ChangeAbilityVisible() = default;
};
class ChangeAbilityPerceptible : public BaseAbilityAction {
public:
ChangeAbilityPerceptible(const AbilityPtr &ability);
~ChangeAbilityPerceptible() = default;
};
class RemoveAbilityAction : public BaseAbilityAction {
public:
RemoveAbilityAction(const AbilityPtr &ability);
~RemoveAbilityAction() = default;
};
using AbilityAction =
std::variant<std::monostate, StartAbilityAction, ConnectAbilityAction, DisconnectAbilityAction,
ChangeAbilityStateAction, ChangeAbilityVisible, ChangeAbilityPerceptible, RemoveAbilityAction>;
template<typename T, typename... ARGS>
void RecordAbilityAction(ARGS... args)
{
abilityActionCache_[abilityActionCount_++].emplace<T>(args...);
if (abilityActionCount_ >= ABILITY_ACTION_CACHE_SIZE) {
CommitAbilityActions();
}
}
void CommitAbilityActions();
void CommitStartAbilityAction(const StartAbilityAction& action, size_t index);
void CommitConnectAbilityAction(const ConnectAbilityAction& action, size_t index);
void CommitDisconnectAbilityAction(const DisconnectAbilityAction& action, size_t index);
void CommitChangedAbilityStateAction(const ChangeAbilityStateAction& action, size_t index);
void CommitRemoveAbilityAction(const RemoveAbilityAction& action, size_t index);
UbaServicePtr GetUbaService();
private:
UbaServicePtr ubaService_;
static constexpr size_t ABILITY_ACTION_CACHE_SIZE = 100;
AbilityAction abilityActionCache_[ABILITY_ACTION_CACHE_SIZE];
size_t abilityActionCount_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_APPMGR_INCLUDE_PROCESS_OPTIMIZER_UBA_H
-10
View File
@@ -1,10 +0,0 @@
{
"services" : [{
"name" : "lmks",
"path" : ["/system/bin/lmks"],
"importance" : -20,
"uid" : "root",
"gid" : ["root"]
}
]
}
-23
View File
@@ -1,23 +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.
on late-fs
# wait for selinux_policy_standard participate in compile
# start lmks
service lmks /system/bin/lmks
class lmks
priority -20
user root
group root
seclabel u:r:lmks:s0
-3
View File
@@ -145,9 +145,6 @@ ErrCode AppMgrService::Init()
APP_LOGE("init failed without ams scheduler");
return ERR_INVALID_OPERATION;
}
if (appMgrServiceInner_->ProcessOptimizerInit() != ERR_OK) {
APP_LOGE("init failed without process optimizer");
}
APP_LOGI("init success");
return ERR_OK;
}
@@ -269,7 +269,6 @@ void AppMgrServiceInner::LaunchApplication(const std::shared_ptr<AppRunningRecor
}
appRecord->LaunchApplication(*configuration_);
appRecord->SetState(ApplicationState::APP_STATE_READY);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_CREATE);
// There is no ability when the resident process starts
// The status of all resident processes is ready
@@ -308,11 +307,9 @@ void AppMgrServiceInner::ApplicationForegrounded(const int32_t recordId)
ApplicationState appState = appRecord->GetState();
if (appState == ApplicationState::APP_STATE_READY || appState == ApplicationState::APP_STATE_BACKGROUND) {
appRecord->SetState(ApplicationState::APP_STATE_FOREGROUND);
OptimizerAppStateChanged(appRecord, appState);
OnAppStateChanged(appRecord, ApplicationState::APP_STATE_FOREGROUND);
} else if (appState == ApplicationState::APP_STATE_SUSPENDED) {
appRecord->SetState(ApplicationState::APP_STATE_BACKGROUND);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_SUSPENDED);
} else {
APP_LOGW("app name(%{public}s), app state(%{public}d)!",
appRecord->GetName().c_str(),
@@ -334,11 +331,9 @@ void AppMgrServiceInner::ApplicationBackgrounded(const int32_t recordId)
}
if (appRecord->GetState() == ApplicationState::APP_STATE_FOREGROUND) {
appRecord->SetState(ApplicationState::APP_STATE_BACKGROUND);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_FOREGROUND);
OnAppStateChanged(appRecord, ApplicationState::APP_STATE_BACKGROUND);
} else if (appRecord->GetState() == ApplicationState::APP_STATE_SUSPENDED) {
appRecord->SetState(ApplicationState::APP_STATE_BACKGROUND);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_SUSPENDED);
} else {
APP_LOGW("app name(%{public}s), app state(%{public}d)!",
appRecord->GetName().c_str(),
@@ -365,7 +360,6 @@ void AppMgrServiceInner::ApplicationTerminated(const int32_t recordId)
return;
}
appRecord->SetState(ApplicationState::APP_STATE_TERMINATED);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_BACKGROUND);
appRecord->RemoveAppDeathRecipient();
OnAppStateChanged(appRecord, ApplicationState::APP_STATE_TERMINATED);
appRunningManager_->RemoveAppRunningRecordById(recordId);
@@ -749,7 +743,6 @@ void AppMgrServiceInner::TerminateAbility(const sptr<IRemoteObject> &token)
}
if (appRecord->GetState() == ApplicationState::APP_STATE_SUSPENDED) {
appRecord->SetState(ApplicationState::APP_STATE_BACKGROUND);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_SUSPENDED);
}
if (appRunningManager_) {
@@ -795,7 +788,6 @@ void AppMgrServiceInner::UpdateAbilityState(const sptr<IRemoteObject> &token, co
}
if (appRecord->GetState() == ApplicationState::APP_STATE_SUSPENDED) {
appRecord->SetState(ApplicationState::APP_STATE_BACKGROUND);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_SUSPENDED);
}
appRecord->UpdateAbilityState(token, state);
@@ -901,20 +893,9 @@ void AppMgrServiceInner::AbilityBehaviorAnalysis(const sptr<IRemoteObject> &toke
if (preToken) {
abilityRecord->SetPreToken(preToken);
}
if (abilityRecord->GetVisibility() != visibility) {
if (processOptimizerUBA_) {
processOptimizerUBA_->OnAbilityVisibleChanged(abilityRecord);
}
}
if (abilityRecord->GetPerceptibility() != perceptibility) {
if (processOptimizerUBA_) {
processOptimizerUBA_->OnAbilityPerceptibleChanged(abilityRecord);
}
}
abilityRecord->SetVisibility(visibility);
abilityRecord->SetPerceptibility(perceptibility);
abilityRecord->SetConnectionState(connectionState);
OptimizerAbilityStateChanged(abilityRecord, abilityRecord->GetState());
}
void AppMgrServiceInner::KillProcessByAbilityToken(const sptr<IRemoteObject> &token)
@@ -1017,7 +998,6 @@ void AppMgrServiceInner::StartAbility(const sptr<IRemoteObject> &token, const sp
ApplicationState appState = appRecord->GetState();
if (appState == ApplicationState::APP_STATE_SUSPENDED) {
appRecord->SetState(ApplicationState::APP_STATE_BACKGROUND);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_SUSPENDED);
}
auto appInfo = std::make_shared<ApplicationInfo>(abilityInfo->applicationInfo);
@@ -1051,79 +1031,6 @@ std::shared_ptr<AppRunningRecord> AppMgrServiceInner::GetAppRunningRecordByAbili
return appRunningManager_->GetAppRunningRecordByAbilityToken(abilityToken);
}
void AppMgrServiceInner::UnsuspendApplication(const std::shared_ptr<AppRunningRecord> &appRecord)
{
if (!appRecord) {
APP_LOGE("app record is null");
return;
}
APP_LOGI("app name is %{public}s , Uid is %{public}d", appRecord->GetName().c_str(), appRecord->GetUid());
// Resume subscription via UID
DelayedSingleton<EventFwk::CommonEvent>::GetInstance()->Unfreeze(appRecord->GetUid());
}
void AppMgrServiceInner::SuspendApplication(const std::shared_ptr<AppRunningRecord> &appRecord)
{
if (!appRecord) {
APP_LOGE("app record is null");
return;
}
APP_LOGD("app name is %{public}s , Uid is %{public}d", appRecord->GetName().c_str(), appRecord->GetUid());
// Temporary unsubscribe via UID
appRecord->SetState(ApplicationState::APP_STATE_SUSPENDED);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_BACKGROUND);
DelayedSingleton<EventFwk::CommonEvent>::GetInstance()->Freeze(appRecord->GetUid());
}
void AppMgrServiceInner::LowMemoryApplicationAlert(
const std::shared_ptr<AppRunningRecord> &appRecord, const CgroupManager::LowMemoryLevel level)
{
if (!appRecord) {
APP_LOGE("app record is null");
return;
}
}
std::shared_ptr<AppRunningRecord> AppMgrServiceInner::GetAbilityOwnerApp(
const std::shared_ptr<AbilityRunningRecord> &abilityRecord) const
{
if (!abilityRecord) {
APP_LOGE("ability record is null");
return nullptr;
}
if (!abilityRecord->GetToken()) {
APP_LOGE("ability token is null");
return nullptr;
}
auto appRecord = GetAppRunningRecordByAbilityToken(abilityRecord->GetToken());
if (!appRecord) {
APP_LOGE("The app information corresponding to token does not exist");
return nullptr;
}
return appRecord;
}
std::shared_ptr<AbilityRunningRecord> AppMgrServiceInner::GetAbilityRunningRecordByAbilityToken(
const sptr<IRemoteObject> &abilityToken) const
{
if (!abilityToken) {
APP_LOGE("ability token is null");
return nullptr;
}
auto appRecord = GetAppRunningRecordByAbilityToken(abilityToken);
if (!appRecord) {
APP_LOGE("The app information corresponding to token does not exist");
return nullptr;
}
auto abilityRecord = appRecord->GetAbilityRunningRecordByToken(abilityToken);
if (!abilityRecord) {
APP_LOGE("The ability information corresponding to token does not exist");
return nullptr;
}
return abilityRecord;
}
void AppMgrServiceInner::AbilityTerminated(const sptr<IRemoteObject> &token)
{
BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
@@ -1362,7 +1269,6 @@ void AppMgrServiceInner::StartProcess(const std::string &appName, const std::str
appRecord->GetPriorityObject()->SetPid(pid);
appRecord->SetUid(startMsg.uid);
appRecord->SetStartMsg(startMsg);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_CREATE);
appRecord->SetAppMgrServiceInner(weak_from_this());
OnAppStateChanged(appRecord, ApplicationState::APP_STATE_CREATE);
AddAppToRecentList(appName, appRecord->GetProcessName(), pid, appRecord->GetRecordId());
@@ -1449,11 +1355,9 @@ void AppMgrServiceInner::OnRemoteDied(const wptr<IRemoteObject> &remote, bool is
for (const auto &item : appRecord->GetAbilities()) {
const auto &abilityRecord = item.second;
OptimizerAbilityStateChanged(abilityRecord, AbilityState::ABILITY_STATE_TERMINATED);
appRecord->StateChangedNotifyObserver(abilityRecord,
static_cast<int32_t>(AbilityState::ABILITY_STATE_TERMINATED), true);
}
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_TERMINATED);
RemoveAppFromRecentListById(appRecord->GetRecordId());
OnProcessDied(appRecord);
@@ -1511,104 +1415,6 @@ void AppMgrServiceInner::AddAppDeathRecipient(const pid_t pid, const sptr<AppDea
}
}
int32_t AppMgrServiceInner::ProcessOptimizerInit()
{
processOptimizerUBA_ = std::make_shared<ProcessOptimizerUBA>(nullptr);
bool isSuccess = processOptimizerUBA_->Init();
if (!isSuccess) {
processOptimizerUBA_.reset();
processOptimizerUBA_ = nullptr;
APP_LOGE("optimizer init is fail");
return ERR_NO_INIT;
}
processOptimizerUBA_->AppSuspended =
std::bind(&AppMgrServiceInner::SuspendApplication, this, std::placeholders::_1);
// Register freeze callback function
processOptimizerUBA_->AppResumed =
std::bind(&AppMgrServiceInner::UnsuspendApplication, this, std::placeholders::_1);
// Register freeze recovery callback function
processOptimizerUBA_->AppLowMemoryAlert =
std::bind(&AppMgrServiceInner::LowMemoryApplicationAlert, this, std::placeholders::_1, std::placeholders::_2);
// Register low memory warning callback function
processOptimizerUBA_->GetAbilityOwnerApp =
std::bind(&AppMgrServiceInner::GetAbilityOwnerApp, this, std::placeholders::_1);
// Register to get the application record callback of ability
processOptimizerUBA_->GetAbilityByToken =
std::bind(&AppMgrServiceInner::GetAbilityRunningRecordByAbilityToken, this, std::placeholders::_1);
// Register to get the ability record through the token callback
APP_LOGI("optimizer init is success");
return ERR_OK;
}
void AppMgrServiceInner::OptimizerAbilityStateChanged(
const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state)
{
if (!processOptimizerUBA_) {
APP_LOGE("process optimizer is not init");
return;
}
if ((ability->GetAbilityInfo()->type == AbilityType::PAGE) ||
(ability->GetAbilityInfo()->type == AbilityType::DATA)) {
if (ability->GetState() == AbilityState::ABILITY_STATE_CREATE) {
processOptimizerUBA_->OnAbilityStarted(ability);
APP_LOGI("optimizer OnAbilityStarted is called");
} else if (ability->GetState() == AbilityState::ABILITY_STATE_TERMINATED) {
processOptimizerUBA_->OnAbilityRemoved(ability);
APP_LOGI("optimizer OnAbilityRemoved is called");
} else {
processOptimizerUBA_->OnAbilityStateChanged(ability, state);
APP_LOGI("optimizer OnAbilityStateChanged is called");
}
} else if (ability->GetAbilityInfo()->type == AbilityType::SERVICE) {
auto appRecord = GetAppRunningRecordByAbilityToken(ability->GetPreToken());
if (!appRecord) {
APP_LOGE("app record is not exist for ability token");
return;
}
auto targetAbility = appRecord->GetAbilityRunningRecordByToken(ability->GetPreToken());
if (!targetAbility) {
APP_LOGE("ability record is not exist for ability previous token");
return;
}
if (ability->GetConnectionState()) {
// connect
processOptimizerUBA_->OnAbilityConnected(ability, targetAbility);
APP_LOGI("optimizer OnAbilityConnected is called");
} else {
// disconnect
processOptimizerUBA_->OnAbilityDisconnected(ability, targetAbility);
APP_LOGI("optimizer OnAbilityDisconnected is called");
}
} else {
APP_LOGI("OptimizerAbilityStateChanged ability type is unknown");
}
if (ability->GetState() != state) {
processOptimizerUBA_->OnAbilityStateChanged(ability, state);
APP_LOGI("optimizer OnAbilityStateChanged is called");
}
}
void AppMgrServiceInner::OptimizerAppStateChanged(
const std::shared_ptr<AppRunningRecord> &appRecord, const ApplicationState state)
{
if (!processOptimizerUBA_) {
APP_LOGE("process optimizer is not init");
return;
}
if (appRecord->GetState() == ApplicationState::APP_STATE_CREATE) {
processOptimizerUBA_->OnAppAdded(appRecord);
APP_LOGI("optimizer OnAppAdded is called");
} else if (appRecord->GetState() == ApplicationState::APP_STATE_TERMINATED) {
processOptimizerUBA_->OnAppRemoved(appRecord);
APP_LOGI("optimizer OnAppRemoved is called");
} else {
processOptimizerUBA_->OnAppStateChanged(appRecord, state);
APP_LOGI("optimizer OnAppStateChanged is called");
}
}
void AppMgrServiceInner::HandleTimeOut(const InnerEvent::Pointer &event)
{
APP_LOGI("handle time out");
@@ -1681,7 +1487,6 @@ void AppMgrServiceInner::HandleTerminateApplicationTimeOut(const int64_t eventId
return;
}
appRecord->SetState(ApplicationState::APP_STATE_TERMINATED);
OptimizerAppStateChanged(appRecord, ApplicationState::APP_STATE_BACKGROUND);
appRecord->RemoveAppDeathRecipient();
OnAppStateChanged(appRecord, ApplicationState::APP_STATE_TERMINATED);
pid_t pid = appRecord->GetPriorityObject()->GetPid();
-524
View File
@@ -1,524 +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 "cgroup_manager.h"
#include <cerrno>
#include <cinttypes>
#include <cstdio>
#include <cstdlib>
#include <dirent.h>
#include <fcntl.h>
#include <sys/eventfd.h>
#include <sys/types.h>
#include <unistd.h>
#include "app_log_wrapper.h"
#include "event_handler.h"
#include "securec.h"
constexpr std::string_view CG_CPUSET_DEFAULT_TASKS_PATH("/dev/cpuset/tasks");
constexpr std::string_view CG_CPUSET_BACKGROUND_TASKS_PATH("/dev/cpuset/background/tasks");
constexpr std::string_view CG_CPUCTL_DEFAULT_TASKS_PATH("/dev/cpuctl/tasks");
constexpr std::string_view CG_CPUCTL_BACKGROUND_TASKS_PATH("/dev/cpuctl/background/tasks");
constexpr std::string_view CG_FREEZER_FROZEN_TASKS_PATH("/dev/freezer/frozen/tasks");
constexpr std::string_view CG_FREEZER_THAWED_TASKS_PATH("/dev/freezer/thawed/tasks");
[[maybe_unused]] constexpr std::string_view CG_MEM_OOMCTL_PATH("/dev/memcg/memory.oom_control");
constexpr std::string_view CG_MEM_EVTCTL_PATH("/dev/memcg/cgroup.event_control");
constexpr std::string_view CG_MEM_PRESSURE_LEVEL_PATH("/dev/memcg/memory.pressure_level");
namespace OHOS {
namespace AppExecFwk {
namespace {
class ScopeGuard final {
public:
using Function = std::function<void()>;
public:
explicit ScopeGuard(Function fn) : fn_(fn), dismissed_(false)
{}
~ScopeGuard()
{
if (!dismissed_) {
fn_();
}
}
public:
void Dismiss()
{
dismissed_ = true;
}
private:
Function fn_;
bool dismissed_ = false;
};
int WriteValue(int fd, std::string_view v)
{
if (fd < 0) {
errno = EINVAL;
return -1;
}
int ret = TEMP_FAILURE_RETRY(write(fd, v.data(), v.size()));
if (ret != 0) {
APP_LOGE("err: %{public}s.", strerror(errno));
}
fsync(fd);
return ret;
}
int WriteValue(int fd, int v, bool newLine = true)
{
if (fd < 0) {
errno = EINVAL;
return -1;
}
char str[32] = {0};
int len = snprintf_s(str, sizeof(str), sizeof(str) - 1, newLine ? "%d\n" : "%d", v);
if (len < 1) {
return -1;
}
return WriteValue(fd, str);
}
} // namespace
CgroupManager::CgroupManager()
{}
CgroupManager::~CgroupManager()
{
for (int i = 0; i < LOW_MEMORY_LEVEL_MAX; ++i) {
if (memoryEventFds_[i] >= 0) {
if (eventHandler_) {
eventHandler_->RemoveFileDescriptorListener(memoryEventFds_[i]);
}
close(memoryEventFds_[i]);
}
if (memoryPressureFds_[i] >= 0) {
close(memoryPressureFds_[i]);
}
}
if (memoryEventControlFd_ >= 0) {
close(memoryEventControlFd_);
}
for (int i = 0; i < SCHED_POLICY_CPU_MAX; ++i) {
if (cpusetTasksFds_[i] >= 0) {
close(cpusetTasksFds_[i]);
}
}
}
bool CgroupManager::Init()
{
APP_LOGI("Init enter.");
if (IsInited()) {
APP_LOGE("already inited.");
return false;
}
auto eventHandler = std::make_shared<EventHandler>(EventRunner::Create());
if (!eventHandler) {
APP_LOGE("failed to get event handler.");
return false;
}
if (!InitCheck()) {
return false;
}
if (!RegisterLowMemoryMonitor(
memoryEventFds_, memoryPressureFds_, memoryEventControlFd_, LOW_MEMORY_LEVEL_LOW, eventHandler)) {
return false;
}
ScopeGuard lowLevelListenerGuard(
[&]() { eventHandler->RemoveFileDescriptorListener(memoryEventFds_[LOW_MEMORY_LEVEL_LOW]); });
if (!RegisterLowMemoryMonitor(
memoryEventFds_, memoryPressureFds_, memoryEventControlFd_, LOW_MEMORY_LEVEL_MEDIUM, eventHandler)) {
return false;
}
ScopeGuard mediumLevelListenerGuard(
[&]() { eventHandler->RemoveFileDescriptorListener(memoryEventFds_[LOW_MEMORY_LEVEL_MEDIUM]); });
if (!RegisterLowMemoryMonitor(
memoryEventFds_, memoryPressureFds_, memoryEventControlFd_, LOW_MEMORY_LEVEL_CRITICAL, eventHandler)) {
return false;
}
ScopeGuard criticalLevelListenerGuard(
[&]() { eventHandler->RemoveFileDescriptorListener(memoryEventFds_[LOW_MEMORY_LEVEL_CRITICAL]); });
eventHandler_ = eventHandler;
lowLevelListenerGuard.Dismiss();
mediumLevelListenerGuard.Dismiss();
criticalLevelListenerGuard.Dismiss();
return true;
}
bool CgroupManager::InitCheck()
{
UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX];
if (!InitCpusetTasksFds(cpusetTasksFds)) {
return false;
}
UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX];
if (!InitCpuctlTasksFds(cpuctlTasksFds)) {
return false;
}
UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX];
if (!InitFreezerTasksFds(freezerTasksFds)) {
return false;
}
UniqueFd memoryEventControlFd;
if (!InitMemoryEventControlFd(memoryEventControlFd)) {
return false;
}
UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX];
if (!InitMemoryEventFds(memoryEventFds)) {
return false;
}
UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX];
if (!InitMemoryPressureFds(memoryPressureFds)) {
return false;
}
return true;
}
bool CgroupManager::IsInited() const
{
return bool(eventHandler_);
}
bool CgroupManager::SetThreadSchedPolicy(int tid, SchedPolicy schedPolicy)
{
if (!IsInited()) {
APP_LOGE("not inited.");
return false;
}
if (tid < 1) {
APP_LOGE("invalid tid %{public}d.", tid);
return false;
}
if (schedPolicy < 0 || schedPolicy >= SchedPolicy::SCHED_POLICY_MAX) {
APP_LOGE("invalid sched policy %{public}d.", schedPolicy);
return false;
}
if (schedPolicy == SchedPolicy::SCHED_POLICY_FREEZED) {
// set frozen of freezer
if (!SetFreezerSubsystem(tid, SchedPolicyFreezer::SCHED_POLICY_FREEZER_FROZEN)) {
APP_LOGE("set freezer subsystem failed sched policy %{public}d.", schedPolicy);
return false;
}
} else {
// set cpuset
if (!SetCpusetSubsystem(tid, schedPolicy)) {
APP_LOGE("set cpuset subsystem failed sched policy %{public}d.", schedPolicy);
return false;
}
// set cpuctl
if (!SetCpuctlSubsystem(tid, schedPolicy)) {
APP_LOGE("set cpuctl subsystem failed sched policy %{public}d.", schedPolicy);
return false;
}
// set thawed of freezer
if (!SetFreezerSubsystem(tid, SchedPolicyFreezer::SCHED_POLICY_FREEZER_THAWED)) {
APP_LOGE("set freezer subsystem failed sched policy %{public}d.", schedPolicy);
return false;
}
}
return true;
}
bool CgroupManager::SetProcessSchedPolicy(int pid, SchedPolicy schedPolicy)
{
if (!IsInited()) {
APP_LOGE("not inited.");
return false;
}
if (pid < 1) {
APP_LOGE("invalid pid %{public}d", pid);
return false;
}
if (schedPolicy < 0 && schedPolicy >= SCHED_POLICY_MAX) {
APP_LOGE("invalid sched policy %{public}d", schedPolicy);
return false;
}
// Set all threads's sched policy inside this process.
char taskDir[64];
if (snprintf_s(taskDir, sizeof(taskDir), sizeof(taskDir) - 1, "/proc/%d/task", pid) < 0) {
return false;
}
DIR *dir = opendir(taskDir);
if (dir == nullptr) {
APP_LOGE("failed to opendir invalid pid %{public}d taskDir %{public}s , %{public}s",
pid,
taskDir,
strerror(errno));
return false;
}
struct dirent *dent;
while ((dent = readdir(dir))) {
// Filter out '.' & '..'
if (dent->d_name[0] != '.') {
SetThreadSchedPolicy(atoi(dent->d_name), schedPolicy);
}
}
closedir(dir);
return true;
}
void CgroupManager::OnReadable(int32_t fd)
{
APP_LOGW("system low memory alert.");
if (!LowMemoryAlert) {
APP_LOGW("'LowMemoryAlert' not available.");
return;
}
auto TryToRaiseLowMemoryAlert = [=](LowMemoryLevel level) {
if (fd == memoryEventFds_[level]) {
APP_LOGW("checking level %{public}d", level);
uint64_t count = 0;
int ret = TEMP_FAILURE_RETRY(read(fd, &count, sizeof(uint64_t)));
if (ret <= 0) {
APP_LOGW("failed to read eventfd %{public}d.", errno);
return false;
}
if (count < 1) {
APP_LOGW("invalid eventfd count %{public}" PRIu64 ".", count);
return false;
}
APP_LOGW("raising low memory alert for level %{public}d...", level);
LowMemoryAlert(level);
return true;
}
return false;
};
if (TryToRaiseLowMemoryAlert(LOW_MEMORY_LEVEL_LOW)) {
return;
}
if (TryToRaiseLowMemoryAlert(LOW_MEMORY_LEVEL_MEDIUM)) {
return;
}
if (TryToRaiseLowMemoryAlert(LOW_MEMORY_LEVEL_CRITICAL)) {
return;
}
// Should not reach here!
APP_LOGE("Unknown fd %{public}d.", fd);
}
bool CgroupManager::RegisterLowMemoryMonitor(const int memoryEventFds[LOW_MEMORY_LEVEL_MAX],
const int memoryPressureFds[LOW_MEMORY_LEVEL_MAX], const int memoryEventControlFd, const LowMemoryLevel level,
const std::shared_ptr<EventHandler> &eventHandler)
{
APP_LOGI("RegisterLowMemoryMonitor(%{public}d) registering low memory monitor %{public}d...", __LINE__, level);
char buf[64] = {0};
static const char *levelName[] = {"low", "medium", "critical"};
if (snprintf_s(buf,
sizeof(buf),
sizeof(buf) - 1,
"%d %d %s",
memoryEventFds[level],
memoryPressureFds[level],
levelName[level]) < 0) {
return false;
}
int ret = TEMP_FAILURE_RETRY(write(memoryEventControlFd, buf, strlen(buf) + 1));
if (ret < 0) {
APP_LOGI("RegisterLowMemoryMonitor(%{public}d) failed to write memory control %{public}d...", __LINE__, errno);
return false;
}
eventHandler->AddFileDescriptorListener(memoryEventFds[level], FILE_DESCRIPTOR_INPUT_EVENT, shared_from_this());
return true;
}
bool CgroupManager::InitCpusetTasksFds(UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX])
{
cpusetTasksFds[SCHED_POLICY_CPU_DEFAULT] = UniqueFd(open(CG_CPUSET_DEFAULT_TASKS_PATH.data(), O_RDWR));
cpusetTasksFds[SCHED_POLICY_CPU_BACKGROUND] = UniqueFd(open(CG_CPUSET_BACKGROUND_TASKS_PATH.data(), O_RDWR));
if (cpusetTasksFds[SCHED_POLICY_CPU_DEFAULT].Get() < 0 || cpusetTasksFds[SCHED_POLICY_CPU_BACKGROUND].Get() < 0) {
APP_LOGE("cannot open cpuset cgroups %{public}d.", errno);
return false;
}
cpusetTasksFds_[SCHED_POLICY_CPU_DEFAULT] = cpusetTasksFds[SCHED_POLICY_CPU_DEFAULT].Release();
cpusetTasksFds_[SCHED_POLICY_CPU_BACKGROUND] = cpusetTasksFds[SCHED_POLICY_CPU_BACKGROUND].Release();
return true;
}
bool CgroupManager::InitCpuctlTasksFds(UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX])
{
cpuctlTasksFds[SCHED_POLICY_CPU_DEFAULT] = UniqueFd(open(CG_CPUCTL_DEFAULT_TASKS_PATH.data(), O_RDWR));
cpuctlTasksFds[SCHED_POLICY_CPU_BACKGROUND] = UniqueFd(open(CG_CPUCTL_BACKGROUND_TASKS_PATH.data(), O_RDWR));
if (cpuctlTasksFds[SCHED_POLICY_CPU_DEFAULT].Get() < 0 || cpuctlTasksFds[SCHED_POLICY_CPU_BACKGROUND].Get() < 0) {
APP_LOGE("cannot open cpuctl cgroups %{public}d.", errno);
return false;
}
cpuctlTasksFds_[SCHED_POLICY_CPU_DEFAULT] = cpuctlTasksFds[SCHED_POLICY_CPU_DEFAULT].Release();
cpuctlTasksFds_[SCHED_POLICY_CPU_BACKGROUND] = cpuctlTasksFds[SCHED_POLICY_CPU_BACKGROUND].Release();
return true;
}
bool CgroupManager::InitFreezerTasksFds(UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX])
{
freezerTasksFds[SCHED_POLICY_FREEZER_FROZEN] = UniqueFd(open(CG_FREEZER_FROZEN_TASKS_PATH.data(), O_RDWR));
freezerTasksFds[SCHED_POLICY_FREEZER_THAWED] = UniqueFd(open(CG_FREEZER_THAWED_TASKS_PATH.data(), O_RDWR));
if (freezerTasksFds[SCHED_POLICY_FREEZER_FROZEN].Get() < 0 ||
freezerTasksFds[SCHED_POLICY_FREEZER_THAWED].Get() < 0) {
APP_LOGE("cannot open freezer cgroups %{public}d.", errno);
return false;
}
freezerTasksFds_[SCHED_POLICY_FREEZER_FROZEN] = freezerTasksFds[SCHED_POLICY_FREEZER_FROZEN].Release();
freezerTasksFds_[SCHED_POLICY_FREEZER_THAWED] = freezerTasksFds[SCHED_POLICY_FREEZER_THAWED].Release();
return true;
}
bool CgroupManager::InitMemoryEventControlFd(UniqueFd &memoryEventControlFd)
{
memoryEventControlFd = UniqueFd(open(CG_MEM_EVTCTL_PATH.data(), O_WRONLY));
if (memoryEventControlFd.Get() < 0) {
APP_LOGE("failed to open memory event control node %{public}d.", errno);
return false;
}
memoryEventControlFd_ = memoryEventControlFd.Release();
return true;
}
bool CgroupManager::InitMemoryEventFds(UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX])
{
memoryEventFds[LOW_MEMORY_LEVEL_LOW] = UniqueFd(eventfd(0, EFD_NONBLOCK));
memoryEventFds[LOW_MEMORY_LEVEL_MEDIUM] = UniqueFd(eventfd(0, EFD_NONBLOCK));
memoryEventFds[LOW_MEMORY_LEVEL_CRITICAL] = UniqueFd(eventfd(0, EFD_NONBLOCK));
if (memoryEventFds[LOW_MEMORY_LEVEL_LOW].Get() < 0 || memoryEventFds[LOW_MEMORY_LEVEL_MEDIUM].Get() < 0 ||
memoryEventFds[LOW_MEMORY_LEVEL_CRITICAL].Get() < 0) {
APP_LOGE("failed to create memory eventfd %{public}d.", errno);
return false;
}
memoryEventFds_[LOW_MEMORY_LEVEL_LOW] = memoryEventFds[LOW_MEMORY_LEVEL_LOW].Release();
memoryEventFds_[LOW_MEMORY_LEVEL_MEDIUM] = memoryEventFds[LOW_MEMORY_LEVEL_MEDIUM].Release();
memoryEventFds_[LOW_MEMORY_LEVEL_CRITICAL] = memoryEventFds[LOW_MEMORY_LEVEL_CRITICAL].Release();
return true;
}
bool CgroupManager::InitMemoryPressureFds(UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX])
{
memoryPressureFds[LOW_MEMORY_LEVEL_LOW] = UniqueFd(open(CG_MEM_PRESSURE_LEVEL_PATH.data(), O_RDONLY));
memoryPressureFds[LOW_MEMORY_LEVEL_MEDIUM] = UniqueFd(open(CG_MEM_PRESSURE_LEVEL_PATH.data(), O_RDONLY));
memoryPressureFds[LOW_MEMORY_LEVEL_CRITICAL] = UniqueFd(open(CG_MEM_PRESSURE_LEVEL_PATH.data(), O_RDONLY));
if (memoryPressureFds[LOW_MEMORY_LEVEL_LOW].Get() < 0 || memoryPressureFds[LOW_MEMORY_LEVEL_MEDIUM].Get() < 0 ||
memoryPressureFds[LOW_MEMORY_LEVEL_CRITICAL].Get() < 0) {
APP_LOGE("failed to open memory pressure fd %{public}d.", errno);
return false;
}
memoryPressureFds_[LOW_MEMORY_LEVEL_LOW] = memoryPressureFds[LOW_MEMORY_LEVEL_LOW].Release();
memoryPressureFds_[LOW_MEMORY_LEVEL_MEDIUM] = memoryPressureFds[LOW_MEMORY_LEVEL_MEDIUM].Release();
memoryPressureFds_[LOW_MEMORY_LEVEL_CRITICAL] = memoryPressureFds[LOW_MEMORY_LEVEL_CRITICAL].Release();
return true;
}
bool CgroupManager::SetCpusetSubsystem(const int tid, const SchedPolicy schedPolicy)
{
int fd = cpusetTasksFds_[schedPolicy];
if (fd < 0) {
APP_LOGE("invalid cpuset fd for policy %{public}d.", schedPolicy);
return false;
}
int ret = WriteValue(fd, tid);
if (ret < 0) {
APP_LOGE("write cpuset tid failed %{public}d.", errno);
return false;
}
return true;
}
bool CgroupManager::SetCpuctlSubsystem(const int tid, const SchedPolicy schedPolicy)
{
int fd = cpuctlTasksFds_[schedPolicy];
if (fd < 0) {
APP_LOGE("invalid cpuctl fd for policy %{public}d.", schedPolicy);
return false;
}
int ret = WriteValue(fd, tid);
if (ret < 0) {
APP_LOGE("write cpuctl tid failed %{public}d.", errno);
return false;
}
return true;
}
bool CgroupManager::SetFreezerSubsystem(const int tid, const SchedPolicyFreezer state)
{
int fd = freezerTasksFds_[state];
if (fd < 0) {
APP_LOGE("invalid freezer fd for state %{public}d.", state);
return false;
}
int ret = WriteValue(fd, tid);
if (ret < 0) {
APP_LOGE("write freezer tid failed %{public}d.", errno);
return false;
}
return true;
}
} // namespace AppExecFwk
} // namespace OHOS
-26
View File
@@ -1,26 +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 "lmks_server.h"
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
OHOS::LMKS::LmksServer lmksServer;
lmksServer.StartServer();
return 0;
}
-286
View File
@@ -1,286 +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 "lmks_server.h"
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <thread>
#include <unistd.h>
#include "hilog/log.h"
#include "securec.h"
namespace OHOS {
namespace LMKS {
namespace {
#ifdef __MUSL__
const std::string LMKS_SOCKET_NAME = "/dev/unix/socket/lmks";
#else
const std::string LMKS_SOCKET_NAME = "/dev/socket/lmks";
#endif
constexpr uint32_t LISTEN_CLIENTS = 5; // 5: max num of clients
constexpr uint32_t WAIT_DELAY_US = 100 * 1000; // 100ms
constexpr int LMKS_CMD_TARGET = 0;
constexpr int LMKS_CMD_PROCPRIO = 1;
constexpr int LMKS_CMD_PROCREMOVE = 2;
constexpr int LMKS_CMD_PROCPURGE = 3;
constexpr uid_t LMKS_ID_ROOT = 0; // chown owner
constexpr gid_t LMKS_ID_SYSTEM = 1000; // chown group
constexpr mode_t SOCKET_PERM = 0666; // root system can read and write lmks socket
constexpr struct timeval SOCKET_TIMEOUT = {5, 0}; // 5, 0: { 5 sec, 0 msec } for timeout
} // namespace
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "LmksServer"};
LmksServer::LmksServer() : isStart_(false), socketFd_(-1), socketAddrLen_(0), lmksUtils_(nullptr)
{
memset_s(&socketAddr_, sizeof(socketAddr_), 0, sizeof(socketAddr_));
}
LmksServer::~LmksServer()
{
CloseSocket();
}
void LmksServer::StartServer()
{
if (isStart_) {
HiLog::Error(LABEL, "Lmks server has started.");
return;
}
if (RegisterSocket() != 0) {
HiLog::Error(LABEL, "Register error.");
return;
}
isStart_ = true;
if (lmksUtils_ == nullptr) {
lmksUtils_ = std::make_shared<LmksUtils>();
}
while (1) {
int connectFd = WaitConnection();
if (connectFd < 0) {
usleep(WAIT_DELAY_US);
continue;
}
LMKS_PACKET cmds;
int len = RecvSocketMessage(connectFd, (void *)cmds, sizeof(cmds));
if (len <= 0) {
HiLog::Error(LABEL, "Failed to read socket message, len %{public}d", len);
close(connectFd);
continue;
}
ProcessMessage(connectFd, cmds, len);
}
// close socket
CloseSocket();
}
int LmksServer::RegisterSocket()
{
if (socketFd_ > 0) {
HiLog::Error(LABEL, "Lmks server has already register.");
return -1;
}
socketFd_ = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
if (socketFd_ < 0) {
HiLog::Error(LABEL, "Failed to create socket, err %{public}s", strerror(errno));
return (-errno);
}
if (memset_s(&socketAddr_, sizeof(socketAddr_), 0, sizeof(socketAddr_)) != 0) {
HiLog::Error(LABEL, "Failed to memset socket addr, err %{public}s", strerror(errno));
return (-errno);
}
if (strcpy_s(socketAddr_.sun_path, sizeof(socketAddr_.sun_path), LMKS_SOCKET_NAME.c_str()) != 0) {
HiLog::Error(LABEL, "Failed to snprint32_tf_s socket addr, err %{public}s", strerror(errno));
return (-errno);
}
socketAddr_.sun_family = AF_LOCAL;
socketAddrLen_ = offsetof(struct sockaddr_un, sun_path) + LMKS_SOCKET_NAME.length() + 1;
if ((unlink(socketAddr_.sun_path) != 0) && (errno != ENOENT)) {
HiLog::Error(LABEL, "Failed to unlink, err %{public}s", strerror(errno));
return (-errno);
}
int reuseAddr = 0;
if ((setsockopt(socketFd_, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) != 0) ||
(setsockopt(socketFd_, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0) ||
(setsockopt(socketFd_, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0)) {
HiLog::Error(LABEL, "Failed to set opt of socket %d, err %{public}s", socketFd_, strerror(errno));
return (-errno);
}
if (bind(socketFd_, reinterpret_cast<struct sockaddr *>(&socketAddr_), socketAddrLen_) < 0) {
HiLog::Error(LABEL, "Failed to bind socket fd %d, err %{public}s", socketFd_, strerror(errno));
return (-errno);
}
if (chown(socketAddr_.sun_path, LMKS_ID_ROOT, LMKS_ID_SYSTEM)) {
HiLog::Error(LABEL, "Failed to chown socket. err %{public}s", strerror(errno));
return (-errno);
}
if (chmod(socketAddr_.sun_path, SOCKET_PERM)) {
HiLog::Error(LABEL, "Failed to chmod socket. err %{public}s", strerror(errno));
if ((unlink(socketAddr_.sun_path) != 0) && (errno != ENOENT)) {
HiLog::Error(LABEL, "Failed to unlink, err %{public}s", strerror(errno));
}
return (-errno);
}
if (listen(socketFd_, LISTEN_CLIENTS) != 0) {
HiLog::Error(LABEL, "Failed to listen socket fd %d, err %{public}s", socketFd_, strerror(errno));
return (-errno);
}
return 0;
}
int LmksServer::WaitConnection()
{
if (socketFd_ < 0) {
HiLog::Error(LABEL, "lmks server not register.");
return -1;
}
struct sockaddr_un clientAddr;
socklen_t clientLen = sizeof(clientAddr);
if (memset_s(&clientAddr, clientLen, 0, clientLen) != 0) {
HiLog::Warn(LABEL, "Failed to memset client addr, err %{public}s", strerror(errno));
}
int connFd = accept(socketFd_, reinterpret_cast<struct sockaddr *>(&clientAddr), &clientLen);
if (connFd < 0) {
HiLog::Warn(LABEL, "Accept warning %{public}s", strerror(errno));
return (-errno);
}
if ((setsockopt(connFd, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) < 0) ||
(setsockopt(connFd, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) < 0)) {
HiLog::Error(LABEL, "Failed to set opt of Connection %d, err %{public}s", connFd, strerror(errno));
close(connFd);
return (-errno);
}
return connFd;
}
void LmksServer::CloseSocket()
{
if (socketFd_ >= 0) {
HiLog::Debug(LABEL, "Closed socket with fd %d", socketFd_);
close(socketFd_);
socketFd_ = -1;
}
}
int LmksServer::SendSocketMessage(int connectFd, const void *buf, int len)
{
if (connectFd < 0 || len <= 0 || buf == nullptr) {
HiLog::Error(LABEL, "Invalid args: connect %d, len %d, buf might be nullptr", connectFd, len);
return -1;
}
ssize_t rLen = TEMP_FAILURE_RETRY(send(connectFd, buf, len, 0));
if (rLen < 0) {
HiLog::Error(LABEL, "Send message from fd %d error %zd: %s", connectFd, rLen, strerror(errno));
return (-errno);
}
return rLen;
}
int LmksServer::RecvSocketMessage(int connectFd, void *buf, int len)
{
if (connectFd < 0 || len <= 0 || buf == nullptr) {
HiLog::Error(LABEL, "Invalid args: connect %d, len %d, buf might be nullptr", connectFd, len);
return -1;
}
if (memset_s(buf, len, 0, len) != 0) {
HiLog::Error(LABEL, "Failed to memset read buf err %{public}s", strerror(errno));
return (-errno);
}
ssize_t rLen = TEMP_FAILURE_RETRY(recv(connectFd, buf, len, 0));
if (rLen < 0) {
HiLog::Error(LABEL, "Read message from fd %d error %zd: %s", connectFd, rLen, strerror(errno));
return (-errno);
}
return rLen;
}
void LmksServer::ProcessMessage(int connectFd, LMKS_PACKET cmds, int len)
{
if (!isStart_ || (lmksUtils_ == nullptr)) {
HiLog::Error(
LABEL, "Lmks server not start isStart_ %{public}d lmksUtils_%{public}p", isStart_, lmksUtils_.get());
close(connectFd);
return;
}
if (connectFd < 0 || len <= 0) {
HiLog::Error(LABEL, "Invalid args: len %d, connectFd %d", len, connectFd);
close(connectFd);
return;
}
int ret = -1;
pid_t pid = 0;
switch (cmds[0]) {
case LMKS_CMD_TARGET:
HiLog::Info(LABEL, "ProcessMessage LMKS_CMD_TARGET ");
break;
case LMKS_CMD_PROCPRIO:
HiLog::Info(LABEL, "ProcessMessage LMKS_CMD_PROCPRIO");
break;
case LMKS_CMD_PROCREMOVE:
HiLog::Info(LABEL, "ProcessMessage LMKS_CMD_PROCREMOVE");
pid = cmds[1];
ret = lmksUtils_->RemoveProcess(pid);
if (SendSocketMessage(connectFd, &ret, sizeof(ret)) <= 0) {
HiLog::Error(LABEL, "Failed to return the result of remove process");
}
break;
case LMKS_CMD_PROCPURGE:
HiLog::Info(LABEL, "ProcessMessage LMKS_CMD_PROCPURGE");
break;
default:
HiLog::Error(LABEL, "Wrong cmd %d", cmds[0]);
break;
}
// close connect fd.
close(connectFd);
}
} // namespace LMKS
} // namespace OHOS
-190
View File
@@ -1,190 +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 "lmks_utils.h"
#include <csignal>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "hilog/log.h"
#include "securec.h"
namespace OHOS {
namespace LMKS {
namespace {
constexpr int PROC_PATH_MAX = 256;
constexpr int PROC_LINE_MAX = 128;
} // namespace
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "LmksUtils"};
LmksUtils::LmksUtils()
{}
LmksUtils::~LmksUtils()
{}
int LmksUtils::RemoveProcess(pid_t pid)
{
auto procName = GetProcName(pid);
if (procName.empty()) {
HiLog::Error(LABEL, "pid %{public}d process name emptry", pid);
return -1;
}
auto procSize = GetProcSize(pid);
if (procSize <= 0) {
HiLog::Error(LABEL, "pid %{public}d process size error", pid);
return -1;
}
// kill process
HiLog::Info(LABEL, "kill pid %{public}d success, name %{public}s size %{public}d",
pid, procName.c_str(), procSize);
return 0;
}
std::string LmksUtils::GetProcName(pid_t pid)
{
std::string name = "";
if (pid < 1) {
HiLog::Warn(LABEL, "invalid pid %{public}d.", pid);
return name;
}
char path[PROC_PATH_MAX];
char line[PROC_LINE_MAX];
int fd = -1;
ssize_t ret = -1;
if (memset_s(path, sizeof(path), 0x00, sizeof(path)) != 0) {
HiLog::Error(LABEL, "memset_s path err %{public}s", strerror(errno));
return name;
}
if (memset_s(line, sizeof(line), 0x00, sizeof(line)) != 0) {
HiLog::Error(LABEL, "memset_s line err %{public}s", strerror(errno));
return name;
}
if (snprintf_s(path, PROC_PATH_MAX, PROC_PATH_MAX - 1, "/proc/%d/cmdline", pid) < 0) {
HiLog::Error(LABEL, "snprintf_s cmdline err %{public}s", strerror(errno));
return name;
}
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
HiLog::Error(LABEL, "open path[%{public}s] err %{public}s", path, strerror(errno));
return name;
}
ret = ReadAll(fd, line, sizeof(line) - 1);
if (ret < 0) {
close(fd);
return name;
}
if (strlen(line) + 1 <= PROC_LINE_MAX && strlen(line) != 0) {
name = line;
} else {
HiLog::Error(LABEL, "cmdline no data");
}
close(fd);
return name;
}
int LmksUtils::GetProcSize(pid_t pid)
{
int rss = 0;
if (pid <= 0) {
HiLog::Error(LABEL, "invalid pid %{public}d.", pid);
return rss;
}
char path[PROC_PATH_MAX];
char line[PROC_LINE_MAX];
int fd = -1;
int total = -1;
ssize_t ret = -1;
if (memset_s(path, sizeof(path), 0x00, sizeof(path)) != 0) {
HiLog::Error(LABEL, "memset_s path err %{public}s", strerror(errno));
return -1;
}
if (memset_s(line, sizeof(line), 0x00, sizeof(line)) != 0) {
HiLog::Error(LABEL, "memset_s line err %{public}s", strerror(errno));
return -1;
}
if (snprintf_s(path, PROC_PATH_MAX, PROC_PATH_MAX - 1, "/proc/%d/statm", pid) < 0) {
HiLog::Error(LABEL, "snprintf_s statm err %{public}s", strerror(errno));
return rss;
}
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
HiLog::Error(LABEL, "open path[%{public}s] err %{public}s", path, strerror(errno));
return -1;
}
ret = ReadAll(fd, line, sizeof(line) - 1);
if (ret < 0) {
close(fd);
return -1;
}
if ((strlen(line) + 1 <= PROC_LINE_MAX && strlen(line) != 0) && (sscanf_s(line, "%d %d ", &total, &rss) > 0)) {
HiLog::Info(LABEL, "pid %{public}d total %{public}d rss %{public}d", pid, total, rss);
} else {
HiLog::Error(LABEL, "strlen or sscanf_s err %{public}s", strerror(errno));
rss = 0;
}
close(fd);
return rss;
}
ssize_t LmksUtils::ReadAll(int fd, char *buf, size_t maxLen)
{
ssize_t ret = 0;
off_t offSet = 0;
while (maxLen > 0) {
ssize_t rc = TEMP_FAILURE_RETRY(pread(fd, buf, maxLen, offSet));
if (rc == 0) {
break;
}
if (rc == -1) {
HiLog::Error(LABEL, "pread err %{public}s", strerror(errno));
return -1;
}
ret += rc;
buf += rc;
offSet += rc;
maxLen -= rc;
}
return ret;
}
} // namespace LMKS
} // namespace OHOS
-270
View File
@@ -1,270 +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 "lmks_client.h"
#include <cerrno>
#include <memory>
#include <string>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <thread>
#include <unistd.h>
#include "app_log_wrapper.h"
#include "event_handler.h"
#include "securec.h"
#include "unique_fd.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
constexpr int LMKS_SOCKET_TIMEOUT = 3;
constexpr size_t LMKS_START_VALUE = 1;
constexpr size_t LMKS_MULTIPLE = 2;
constexpr size_t LMKS_MAX_TARGETS = 6;
constexpr int LMKS_CMD_TARGET = 0;
constexpr int LMKS_CMD_PROCPRIO = 1;
constexpr int LMKS_CMD_PROCREMOVE = 2;
constexpr int LMKS_CMD_PROCPURGE = 3;
constexpr int APP_OOM_ADJ_MIN = -1000;
constexpr int APP_OOM_ADJ_MAX = 1000;
constexpr int LMKS_SOCKET_PATH_MAX = 108;
constexpr std::string_view LMKS_SOCKET_PATH("/dev/socket/lmks");
static_assert(LMKS_SOCKET_PATH.size() < LMKS_SOCKET_PATH_MAX);
} // namespace
LmksClient::LmksClient() : socket_(-1)
{}
LmksClient::~LmksClient()
{
if (IsOpen()) {
Close();
}
}
int32_t LmksClient::Open()
{
APP_LOGI("connecting lmks.");
if (socket_ >= 0) {
APP_LOGE("already connected.");
return -1;
}
UniqueFd sk(socket(PF_LOCAL, SOCK_SEQPACKET, 0));
if (sk.Get() < 0) {
APP_LOGE("failed to create local socket %{public}d.", errno);
return (-errno);
}
struct timeval timeOut = {.tv_sec = LMKS_SOCKET_TIMEOUT, .tv_usec = 0};
int fd = sk.Get();
if (fd < 0) {
APP_LOGE("fd is negative.");
return -1;
}
if ((setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) != 0) ||
(setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeOut, sizeof(timeOut)) != 0)) {
APP_LOGE("failed to set local socket timeout %{public}s.", strerror(errno));
return (-errno);
}
struct sockaddr_un addr;
int32_t ret;
ret = memset_s(&addr, sizeof(addr), 0, sizeof(addr));
if (ret != EOK) {
APP_LOGE("failed to clear local socket addr.");
return ret;
}
ret = memcpy_s(addr.sun_path, LMKS_SOCKET_PATH_MAX, LMKS_SOCKET_PATH.data(), LMKS_SOCKET_PATH.size());
if (ret != EOK) {
APP_LOGE("failed to make local socket path.");
return ret;
}
addr.sun_family = AF_LOCAL;
socklen_t addrLen = offsetof(struct sockaddr_un, sun_path) + LMKS_SOCKET_PATH.size() + 1;
if (connect(sk, reinterpret_cast<struct sockaddr *>(&addr), addrLen) < 0) {
APP_LOGE("failed to connect to lmks %{public}s.", strerror(errno));
return (-errno);
}
socket_ = sk.Release();
return ERR_OK;
}
void LmksClient::Close()
{
APP_LOGI("closing lmks.");
if (socket_ < 0) {
APP_LOGE("not connected.");
return;
}
close(socket_);
socket_ = -1;
}
bool LmksClient::IsOpen() const
{
return socket_ >= 0;
}
int32_t LmksClient::Target(const Targets &targets)
{
APP_LOGI("Target enter");
if (targets.empty() || targets.size() > LMKS_MAX_TARGETS) {
APP_LOGE("empty target or too many targets. %{public}zu", targets.size());
return (-EINVAL);
}
int i = 0;
int32_t buf[LMKS_START_VALUE + LMKS_MULTIPLE * LMKS_MAX_TARGETS];
buf[i++] = LMKS_CMD_TARGET;
for (auto target : targets) {
if (target.first < 0 || !CheckOomAdj(target.second)) {
APP_LOGE("invalid target: %{public}d %{public}d", target.first, target.second);
return (-EINVAL);
}
buf[i++] = target.first;
buf[i++] = target.second;
}
return Write(buf, i * sizeof(int32_t)) ? ERR_OK : -1;
}
int32_t LmksClient::ProcPrio(pid_t pid, uid_t uid, int oomAdj)
{
APP_LOGI("ProcPrio enter");
if (pid < 0 || uid < 0 || !CheckOomAdj(oomAdj)) {
APP_LOGE("invalid parameter: %{public}d %{public}d %{public}d.", pid, uid, oomAdj);
return (-EINVAL);
}
int32_t buf[4] = {LMKS_CMD_PROCPRIO, pid, uid, oomAdj};
return Write(buf, sizeof(buf)) ? ERR_OK : -1;
}
int32_t LmksClient::ProcRemove(pid_t pid)
{
APP_LOGI("ProcRemove enter");
if (pid < 1) {
APP_LOGE("invalid pid %{public}d.", pid);
return (-EINVAL);
}
int32_t buf[2] = {LMKS_CMD_PROCREMOVE, pid};
if (!Write(buf, sizeof(buf))) {
APP_LOGE("failed to write");
return -1;
}
LmksClientMsg msg;
if (!Read(msg.resultBuf, sizeof(int32_t))) {
APP_LOGE("failed to read");
return -1;
}
if (msg.result != 0) {
APP_LOGE("failed to remove process");
return -1;
}
APP_LOGI("success to remove process");
return 0;
}
bool LmksClient::ProcPurge()
{
APP_LOGI("ProcPurge enter");
int32_t cmd = LMKS_CMD_PROCPURGE;
return Write(reinterpret_cast<void *>(&cmd), sizeof(cmd));
}
bool LmksClient::CheckOomAdj(int v)
{
return (APP_OOM_ADJ_MIN <= v && v <= APP_OOM_ADJ_MAX);
}
bool LmksClient::Write(const void *buf, size_t len)
{
if (buf == nullptr || len < 1) {
APP_LOGE("invalid parameter.");
return false;
}
constexpr int retryTimes = 5;
for (int i = 0; i < retryTimes; ++i) {
if (socket_ < 0 && !Open()) {
std::this_thread::yield();
continue;
}
int rLen = TEMP_FAILURE_RETRY(send(socket_, buf, len, 0));
if (rLen <= 0) {
APP_LOGE("failed to send data to lmks err %{public}s.", strerror(errno));
Close();
std::this_thread::yield();
} else {
return true;
}
}
return false;
}
bool LmksClient::Read(void *buf, size_t len)
{
if (buf == nullptr || len < 1) {
APP_LOGE("invalid parameter. len %zu", len);
return false;
}
constexpr int retryTimes = 5;
for (int i = 0; i < retryTimes; ++i) {
if (socket_ < 0 && !Open()) {
std::this_thread::yield();
continue;
}
int rLen = TEMP_FAILURE_RETRY(recv(socket_, buf, len, 0));
if (rLen <= 0) {
APP_LOGE("failed to recv data from lmks err %{public}s.", strerror(errno));
Close();
std::this_thread::yield();
} else {
return true;
}
}
return false;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -159,7 +159,6 @@ void ModuleRunningRecord::OnAbilityStateChanged(
}
AbilityState oldState = ability->GetState();
ability->SetState(state);
OptimizerAbilityStateChanged(ability, oldState);
APP_LOGI("OnAbilityStateChanged oldState:%{public}d, state:%{public}d", oldState, state);
auto serviceInner = appMgrServiceInner_.lock();
if (serviceInner) {
@@ -167,16 +166,6 @@ void ModuleRunningRecord::OnAbilityStateChanged(
}
}
void ModuleRunningRecord::OptimizerAbilityStateChanged(
const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state)
{
APP_LOGI("Optimizer ability state changed.");
auto serviceInner = appMgrServiceInner_.lock();
if (serviceInner) {
serviceInner->OptimizerAbilityStateChanged(ability, state);
}
}
void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
{
APP_LOGI("Launch ability.");
@@ -189,7 +178,6 @@ void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningReco
APP_LOGI("ScheduleLaunchAbility ability:%{public}s", ability->GetName().c_str());
appLifeCycleDeal_->LaunchAbility(ability);
ability->SetState(AbilityState::ABILITY_STATE_READY);
OptimizerAbilityStateChanged(ability, AbilityState::ABILITY_STATE_CREATE);
}
}
@@ -233,7 +221,6 @@ void ModuleRunningRecord::TerminateAbility(const sptr<IRemoteObject> &token, con
}
}
OptimizerAbilityStateChanged(abilityRecord, AbilityState::ABILITY_STATE_TERMINATED);
if (appLifeCycleDeal_) {
appLifeCycleDeal_->ScheduleCleanAbility(token);
} else {
-688
View File
@@ -1,688 +0,0 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "process_optimizer.h"
#include <algorithm>
#include <cerrno>
#include <string>
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
using namespace std::placeholders;
namespace {
constexpr auto APP_SUSPEND_TIMER_NAME_PREFIX = "AppSuspendTimer";
constexpr int APP_OOM_ADJ_SYSTEM = -100;
// foreground process oom_adj
constexpr int APP_OOM_ADJ_FOREGROUND = 0;
// visible process oom_adj
constexpr int APP_OOM_ADJ_VISIBLE_MIN = 1;
constexpr int APP_OOM_ADJ_VISIBLE_MAX = 199;
constexpr int APP_OOM_ADJ_VISIBLE_MAX_VALUE = 1 * 1024;
// preceptible process oom_adj
constexpr int APP_OOM_ADJ_PERCEPTIBLE_MIN = 200;
constexpr int APP_OOM_ADJ_PERCEPTIBLE_MAX = 399;
constexpr int APP_OOM_ADJ_PERCEPTIBLE_MAX_VALUE = 4 * 1024;
// background process oom_adj
constexpr int APP_OOM_ADJ_BACKGROUND_MIN = 400;
constexpr int APP_OOM_ADJ_BACKGROUND_MAX = 599;
constexpr int APP_OOM_ADJ_BACKGROUND_MAX_VALUE = 16 * 1024;
// suspend process oom_adj
constexpr int APP_OOM_ADJ_SUSPEND_MIN = 600;
constexpr int APP_OOM_ADJ_SUSPEND_MAX = 799;
constexpr int APP_OOM_ADJ_SUSPEND_MAX_VALUE = 24 * 1024;
// empty process oom_adj
[[maybe_unused]] constexpr int APP_OOM_ADJ_EMPTY_MIN = 800;
constexpr int APP_OOM_ADJ_EMPTY_MAX = 999;
constexpr int APP_OOM_ADJ_EMPTY_MAX_VALUE = 32 * 1024;
constexpr int APP_OOM_ADJ_UNKNOWN = 1000;
constexpr int APP_OOM_ADJ_UNKNOWN_VALUE = 64 * 1024;
constexpr std::string_view SYSTEM_UI_BUNDLE_NAME = "com.ohos.systemui";
// pressure level low
constexpr int LMKS_OOM_ADJ_LOW = 800;
// pressure level medium
constexpr int LMKS_OOM_ADJ_MEDIUM = 600;
// pressure level critical
constexpr int LMKS_OOM_ADJ_CRITICAL = 0;
constexpr int G_MEMORY_LEVEL[] = {LMKS_OOM_ADJ_LOW, LMKS_OOM_ADJ_MEDIUM, LMKS_OOM_ADJ_CRITICAL};
} // namespace
ProcessOptimizer::ProcessOptimizer(const LmksClientPtr &lmksClient, int suspendTimeout)
: lmksClient_(lmksClient), suspendTimeout_(suspendTimeout)
{}
ProcessOptimizer::~ProcessOptimizer()
{
APP_LOGI("ProcessOptimizer destructed");
DelayedSingleton<CgroupManager>::GetInstance()->LowMemoryAlert = nullptr;
if (lmksClient_) {
lmksClient_->ProcPurge();
}
}
bool ProcessOptimizer::Init()
{
APP_LOGI("initializing...");
if (suspendTimeout_ < 0) {
APP_LOGE("invalid suspend timeout.");
return false;
}
if (eventHandler_) {
APP_LOGE("already inited.");
return false;
}
// Initializing cgroup manager.
if (!DelayedSingleton<CgroupManager>::GetInstance()->IsInited()) {
APP_LOGW("cgroup manager not inited.");
if (!DelayedSingleton<CgroupManager>::GetInstance()->Init()) {
APP_LOGE("cannot init cgroup manager.");
return false;
}
}
if (DelayedSingleton<CgroupManager>::GetInstance()->LowMemoryAlert) {
APP_LOGW("cgroup manager 'LowMemoryWarning' already registered.");
}
DelayedSingleton<CgroupManager>::GetInstance()->LowMemoryAlert =
std::bind(&ProcessOptimizer::OnLowMemoryAlert, this, _1);
// Initializing lmks.
LmksClientPtr lmksClientLocal = nullptr;
LmksClient::Targets targets = {
{APP_OOM_ADJ_VISIBLE_MAX_VALUE, APP_OOM_ADJ_VISIBLE_MAX},
{APP_OOM_ADJ_PERCEPTIBLE_MAX_VALUE, APP_OOM_ADJ_PERCEPTIBLE_MAX},
{APP_OOM_ADJ_BACKGROUND_MAX_VALUE, APP_OOM_ADJ_BACKGROUND_MAX},
{APP_OOM_ADJ_SUSPEND_MAX_VALUE, APP_OOM_ADJ_SUSPEND_MAX},
{APP_OOM_ADJ_EMPTY_MAX_VALUE, APP_OOM_ADJ_EMPTY_MAX},
{APP_OOM_ADJ_UNKNOWN_VALUE, APP_OOM_ADJ_UNKNOWN},
};
lmksClientLocal.swap(lmksClient_);
if (!lmksClientLocal) {
lmksClientLocal = std::make_shared<LmksClient>();
if (!lmksClientLocal) {
APP_LOGE("failed to create lmks client.");
return false;
}
}
if (!lmksClientLocal->IsOpen()) {
if (lmksClientLocal->Open()) {
APP_LOGE("cannot open lmks connection.");
return false;
}
}
if (lmksClientLocal->Target(targets) != ERR_OK) {
// print warning when lmks server not implement.
APP_LOGW("cannot init lmks.");
}
lmksClient_ = lmksClientLocal;
// Save initialized states.
auto eventHandler = std::make_shared<EventHandler>(EventRunner::Create());
if (!eventHandler) {
APP_LOGE("no available event handler for current thread.");
return false;
}
eventHandler_ = eventHandler;
return true;
}
void ProcessOptimizer::OnAppAdded(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return;
}
if (app != appLru_.front()) {
auto it = std::find(appLru_.begin(), appLru_.end(), app);
if (it != appLru_.end()) {
APP_LOGE("app '%{public}s' already existed.", app->GetName().c_str());
appLru_.erase(it);
}
if (app->GetState() == ApplicationState::APP_STATE_FOREGROUND) {
appLru_.push_front(app);
} else {
appLru_.push_back(app);
}
}
// Initial sched policy has been already set by appspawn.
UpdateAppOomAdj(app);
}
void ProcessOptimizer::OnAppRemoved(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return;
}
if (!lmksClient_) {
APP_LOGE("invalid lmks client.");
return;
}
// remove timer
StopAppSuspendTimer(app);
auto it = std::find(appLru_.begin(), appLru_.end(), app);
if (it != appLru_.end()) {
appLru_.erase(it);
} else {
APP_LOGE("app '%{public}s' is not existed.", app->GetName().c_str());
}
auto priorityObject = app->GetPriorityObject();
if (!priorityObject) {
APP_LOGE("invalid priority object.");
return;
}
if (lmksClient_->ProcRemove(priorityObject->GetPid()) != ERR_OK) {
APP_LOGE("failed to remove app '%{public}s'(%{publid}d) from lmks.",
app->GetName().c_str(),
priorityObject->GetPid());
}
}
void ProcessOptimizer::OnAppStateChanged(const AppPtr &app, const ApplicationState oldState)
{
if (!app) {
APP_LOGE("invalid app.");
return;
}
auto priorityObject = app->GetPriorityObject();
if (!priorityObject) {
APP_LOGE("invalid priority object.");
return;
}
auto curState = app->GetState();
APP_LOGD("ability state changed to %{public}d.", curState);
if (curState == oldState) {
APP_LOGW("no change.");
return;
}
if (curState == ApplicationState::APP_STATE_FOREGROUND) {
if (app != appLru_.front()) {
auto it = std::find(appLru_.begin(), appLru_.end(), app);
if (it != appLru_.end()) {
appLru_.erase(it);
} else {
APP_LOGE("app '%{public}s' is not existed.", app->GetName().c_str());
}
appLru_.push_front(app);
}
}
UpdateAppSchedPolicy(app);
UpdateAppOomAdj(app);
// only background also no visible and no preceptible can freezer
if (curState == ApplicationState::APP_STATE_BACKGROUND &&
(!priorityObject->GetVisibleStatus() && !priorityObject->GetPerceptibleStatus())) {
StartAppSuspendTimer(app);
}
if (oldState == ApplicationState::APP_STATE_BACKGROUND && curState != ApplicationState::APP_STATE_SUSPENDED) {
StopAppSuspendTimer(app);
}
}
void ProcessOptimizer::OnAbilityStarted(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
APP_LOGI("OnAbilityStarted.");
}
void ProcessOptimizer::OnAbilityConnected(const AbilityPtr &ability, const AbilityPtr &targetAbility)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
if (!targetAbility) {
APP_LOGE("invalid targetAbility.");
return;
}
APP_LOGI("OnAbilityConnected end.");
}
void ProcessOptimizer::OnAbilityDisconnected(const AbilityPtr &ability, const AbilityPtr &targetAbility)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
if (!targetAbility) {
APP_LOGE("invalid targetAbility.");
return;
}
APP_LOGI("OnAbilityDisconnected end.");
}
void ProcessOptimizer::OnAbilityStateChanged(const AbilityPtr &ability, const AbilityState oldState)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
APP_LOGI("OnAbilityStateChanged end.");
}
void ProcessOptimizer::OnAbilityVisibleChanged(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
APP_LOGI("OnAbilityVisibleChanged end.");
}
void ProcessOptimizer::OnAbilityPerceptibleChanged(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
}
APP_LOGI("OnAbilityPerceptibleChanged end.");
}
void ProcessOptimizer::OnAbilityRemoved(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
APP_LOGI("OnAbilityRemoved end.");
}
bool ProcessOptimizer::SetAppOomAdj(const AppPtr &app, int oomAdj)
{
if (!app) {
APP_LOGE("invalid app.");
return false;
}
if (!LmksClient::CheckOomAdj(oomAdj)) {
APP_LOGE("invalid oom adj %{public}d.", oomAdj);
return false;
}
if (!lmksClient_) {
APP_LOGE("invalid lmks client.");
return false;
}
auto priorityObject = app->GetPriorityObject();
if (!priorityObject) {
APP_LOGE("invalid priority object.");
return false;
}
if (priorityObject->GetCurAdj() == oomAdj) {
APP_LOGW("oom adj has no change.");
return true;
}
if (lmksClient_->ProcPrio(priorityObject->GetPid(), app->GetUid(), oomAdj) != ERR_OK) {
// print warning when lmks server not implement.
APP_LOGW("lmks proc prio failed.");
}
priorityObject->SetCurAdj(oomAdj);
return true;
}
bool ProcessOptimizer::SetAppSchedPolicy(const AppPtr &app, const CgroupManager::SchedPolicy schedPolicy)
{
if (!app) {
APP_LOGE("invalid app.");
return false;
}
auto priorityObject = app->GetPriorityObject();
if (!priorityObject) {
APP_LOGE("invalid priority object.");
return false;
}
auto oldSchedPolicy = priorityObject->GetCurCgroup();
if (oldSchedPolicy == schedPolicy) {
APP_LOGW("no change.");
return true;
}
bool result =
DelayedSingleton<CgroupManager>::GetInstance()->SetProcessSchedPolicy(priorityObject->GetPid(), schedPolicy);
if (result) {
priorityObject->SetCurCgroup(schedPolicy);
if (schedPolicy == CgroupManager::SCHED_POLICY_FREEZED) {
if (AppSuspended) {
AppSuspended(app);
}
} else if (oldSchedPolicy == CgroupManager::SCHED_POLICY_FREEZED) {
if (AppResumed) {
AppResumed(app);
}
}
}
return result;
}
void ProcessOptimizer::OnLowMemoryAlert(const CgroupManager::LowMemoryLevel level)
{
APP_LOGI("OnLowMemoryAlert level %{public}d", level);
// Find the oldest background app.
for (auto it(appLru_.rbegin()); it != appLru_.rend(); ++it) {
auto appRecord = (*it);
if (appRecord && appRecord->GetState() == ApplicationState::APP_STATE_BACKGROUND) {
APP_LOGI("OnLowMemoryAlert bundle:%{public}s, level:%{public}d",
appRecord->GetBundleName().c_str(), level);
AppLowMemoryAlert(*it, level);
break;
}
}
// send pid which will be killed.
std::list<AppPtr>::iterator iter = appLru_.begin();
while (iter != appLru_.end()) {
auto appRecord = (*iter);
if (!appRecord) {
continue;
}
auto priorityObject = appRecord->GetPriorityObject();
if (priorityObject != nullptr && priorityObject->GetCurAdj() >= G_MEMORY_LEVEL[level]) {
auto pid = priorityObject->GetPid();
if (pid <= 0) {
APP_LOGE("pid %{public}d invalid", pid);
iter = appLru_.erase(iter);
continue;
}
APP_LOGI("remove pid (%{publid}d) from lmks, bundle:%{public}s", pid, appRecord->GetBundleName().c_str());
if (lmksClient_->ProcRemove(pid) == ERR_OK) {
iter = appLru_.erase(iter);
continue;
}
APP_LOGE("remove error, pid:%{publid}d, bundle:%{public}s", pid, appRecord->GetBundleName().c_str());
}
iter++;
}
}
bool ProcessOptimizer::UpdateAppOomAdj(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return false;
}
APP_LOGI("UpdateAppOomAdj bundleName[%{public}s] state[%{public}d] pid[%{public}d] curadj[%{public}d]",
app->GetBundleName().c_str(),
app->GetState(),
app->GetPriorityObject()->GetPid(),
app->GetPriorityObject()->GetCurAdj());
auto priorityObject = app->GetPriorityObject();
if (!priorityObject) {
APP_LOGE("invalid priority object.");
return false;
}
// special set launcher and systemui adj
if (app->IsLauncherApp() || app->GetBundleName() == SYSTEM_UI_BUNDLE_NAME) {
return SetAppOomAdj(app, APP_OOM_ADJ_SYSTEM);
}
auto state = app->GetState();
if (state == ApplicationState::APP_STATE_FOREGROUND || state == ApplicationState::APP_STATE_CREATE ||
state == ApplicationState::APP_STATE_READY) {
return SetAppOomAdj(app, APP_OOM_ADJ_FOREGROUND);
}
int oomAdj;
int oomAdjMax;
if (!GetAppOomAdj(app, state, oomAdj, oomAdjMax)) {
return false;
}
for (auto curApp : appLru_) {
if (curApp->GetState() != state) {
continue;
}
// adj of launcher and systemui is always APP_OOM_ADJ_SYSTEM
if (curApp->IsLauncherApp() || curApp->GetBundleName() == SYSTEM_UI_BUNDLE_NAME) {
continue;
}
SetAppOomAdj(curApp, oomAdj);
if (oomAdj < oomAdjMax) {
oomAdj += 1;
}
}
return true;
}
bool ProcessOptimizer::GetAppOomAdj(const AppPtr &app, ApplicationState state, int &oomAdj, int &oomAdjMax)
{
auto priorityObject = app->GetPriorityObject();
if (!priorityObject) {
APP_LOGE("invalid priority object.");
return false;
}
switch (state) {
case ApplicationState::APP_STATE_BACKGROUND:
oomAdj = APP_OOM_ADJ_BACKGROUND_MIN;
oomAdjMax = APP_OOM_ADJ_BACKGROUND_MAX;
// perceptible oom_adj
if (priorityObject->GetPerceptibleStatus()) {
oomAdj = APP_OOM_ADJ_PERCEPTIBLE_MIN;
oomAdjMax = APP_OOM_ADJ_PERCEPTIBLE_MAX;
}
// visible oom_adj
if (priorityObject->GetVisibleStatus()) {
oomAdj = APP_OOM_ADJ_VISIBLE_MIN;
oomAdjMax = APP_OOM_ADJ_VISIBLE_MAX;
}
break;
case ApplicationState::APP_STATE_SUSPENDED:
oomAdj = APP_OOM_ADJ_SUSPEND_MIN;
oomAdjMax = APP_OOM_ADJ_SUSPEND_MAX;
break;
default:
oomAdj = APP_OOM_ADJ_UNKNOWN;
oomAdjMax = APP_OOM_ADJ_UNKNOWN;
break;
}
return true;
}
bool ProcessOptimizer::UpdateAppSchedPolicy(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return false;
}
bool ret = false;
switch (app->GetState()) {
case ApplicationState::APP_STATE_CREATE:
case ApplicationState::APP_STATE_READY:
case ApplicationState::APP_STATE_FOREGROUND:
ret = SetAppSchedPolicy(app, CgroupManager::SCHED_POLICY_DEFAULT);
break;
case ApplicationState::APP_STATE_BACKGROUND:
ret = SetAppSchedPolicy(app, CgroupManager::SCHED_POLICY_BACKGROUND);
break;
case ApplicationState::APP_STATE_SUSPENDED:
// SUSPEND state should be set in 'ProcessOptimizer::SuspendApp()' (to be specific,
// in 'AppSuspended' callback), and the sched policy has been set in it, so do nothing here.
ret = true;
break;
default:
ret = true;
break;
}
return ret;
}
void ProcessOptimizer::StartAppSuspendTimer(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return;
}
APP_LOGI("starting suspend timer for app '%{public}s'...", app->GetName().c_str());
if (!eventHandler_) {
APP_LOGE("invalid event handler.");
return;
}
auto timerName = GetAppSuspendTimerName(app);
if (timerName.empty()) {
APP_LOGE("invalid suspend timer name.");
return;
}
auto it = suspendTimers_.find(timerName);
if (it != suspendTimers_.end()) {
APP_LOGW("app '%{public}s' suspend timer already started.", app->GetName().c_str());
return;
}
suspendTimers_.emplace(timerName);
eventHandler_->PostTask(
[=]() {
auto finder = suspendTimers_.find(timerName);
if (finder != suspendTimers_.end()) {
APP_LOGD("removing app '%{public}s' '%{public}s' suspend timer name...",
timerName.c_str(),
app->GetName().c_str());
suspendTimers_.erase(finder);
} else {
APP_LOGE("invalid suspend timer for app '%{public}s' '%{public}s'.",
timerName.c_str(),
app->GetName().c_str());
}
SuspendApp(app);
},
timerName,
suspendTimeout_);
}
void ProcessOptimizer::StopAppSuspendTimer(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return;
}
APP_LOGI("stopping suspend timer for app '%{public}s'...", app->GetName().c_str());
if (!eventHandler_) {
APP_LOGE("invalid event handler.");
return;
}
auto timerName = GetAppSuspendTimerName(app);
if (timerName.empty()) {
APP_LOGE("invalid suspend timer name.");
return;
}
auto it = suspendTimers_.find(timerName);
if (it == suspendTimers_.end()) {
APP_LOGW("app '%{public}s' suspend timer not started.", app->GetName().c_str());
return;
}
suspendTimers_.erase(it);
eventHandler_->RemoveTask(timerName);
}
void ProcessOptimizer::SuspendApp(const AppPtr &app)
{
if (!app) {
APP_LOGE("invalid app.");
return;
}
APP_LOGI("suspending app '%{public}s'...", app->GetName().c_str());
if (app->GetState() == ApplicationState::APP_STATE_SUSPENDED) {
APP_LOGE("app '%{public}s' already suspended.", app->GetName().c_str());
return;
}
if (!SetAppSchedPolicy(app, CgroupManager::SCHED_POLICY_FREEZED)) {
APP_LOGE("failed to suspend app '%s'.", app->GetName().c_str());
}
}
std::string ProcessOptimizer::GetAppSuspendTimerName(const AppPtr &app)
{
std::string ret;
if (app) {
auto priorityObject = app->GetPriorityObject();
if (priorityObject) {
ret = APP_SUSPEND_TIMER_NAME_PREFIX + std::to_string(priorityObject->GetPid());
}
}
return ret;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -1,388 +0,0 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "process_optimizer_uba.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
ProcessOptimizerUBA::BaseAbilityAction::BaseAbilityAction(const AbilityPtr &ability)
: time_(Clock::now()), name_(ability->GetName())
{}
ProcessOptimizerUBA::TimePoint ProcessOptimizerUBA::BaseAbilityAction::GetTime() const
{
return time_;
}
std::string ProcessOptimizerUBA::BaseAbilityAction::GetTimeString() const
{
std::time_t tmp = Clock::to_time_t(time_);
char *pTime = std::ctime(&tmp);
return (pTime == nullptr) ? "" : std::string(pTime);
}
const std::string &ProcessOptimizerUBA::BaseAbilityAction::GetName() const
{
return name_;
}
ProcessOptimizerUBA::StartAbilityAction::StartAbilityAction(const AbilityPtr &ability, const AbilityPtr &preAbility)
: BaseAbilityAction(ability), preName_(preAbility ? preAbility->GetName() : std::string())
{}
const std::string &ProcessOptimizerUBA::StartAbilityAction::GetPreName() const
{
return preName_;
}
ProcessOptimizerUBA::ConnectAbilityAction::ConnectAbilityAction(
const AbilityPtr &ability, const AbilityPtr &targetAbility)
: BaseAbilityAction(ability), targetName_(targetAbility->GetName())
{}
const std::string &ProcessOptimizerUBA::ConnectAbilityAction::GetTargetName() const
{
return targetName_;
}
ProcessOptimizerUBA::DisconnectAbilityAction::DisconnectAbilityAction(
const AbilityPtr &ability, const AbilityPtr &targetAbility)
: BaseAbilityAction(ability), targetName_(targetAbility->GetName())
{}
const std::string &ProcessOptimizerUBA::DisconnectAbilityAction::GetTargetName() const
{
return targetName_;
}
ProcessOptimizerUBA::ChangeAbilityStateAction::ChangeAbilityStateAction(
const AbilityPtr &ability, const AbilityState oldState)
: BaseAbilityAction(ability), oldState_(oldState), newState_(ability->GetState())
{}
AbilityState ProcessOptimizerUBA::ChangeAbilityStateAction::GetOldState() const
{
return oldState_;
}
AbilityState ProcessOptimizerUBA::ChangeAbilityStateAction::GetNewState() const
{
return newState_;
}
ProcessOptimizerUBA::ChangeAbilityVisible::ChangeAbilityVisible(const AbilityPtr &ability)
: BaseAbilityAction(ability){};
ProcessOptimizerUBA::ChangeAbilityPerceptible::ChangeAbilityPerceptible(const AbilityPtr &ability)
: BaseAbilityAction(ability){};
ProcessOptimizerUBA::RemoveAbilityAction::RemoveAbilityAction(const AbilityPtr &ability) : BaseAbilityAction(ability)
{}
ProcessOptimizerUBA::ProcessOptimizerUBA(
const UbaServicePtr &ubaService, const LmksClientPtr &lmksClient, int suspendTimeout)
: ProcessOptimizer(lmksClient, suspendTimeout), ubaService_(ubaService), abilityActionCount_(0)
{
APP_LOGI("ProcessOptimizerUBA ProcessOptimizerUBA start !");
}
ProcessOptimizerUBA::~ProcessOptimizerUBA()
{
if (abilityActionCount_ > 0) {
CommitAbilityActions();
}
}
void ProcessOptimizerUBA::OnAppAdded(const AppPtr &app)
{
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAppAdded(app);
}
}
void ProcessOptimizerUBA::OnAppRemoved(const AppPtr &app)
{
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAppRemoved(app);
}
}
void ProcessOptimizerUBA::OnAppStateChanged(const AppPtr &app, const ApplicationState oldState)
{
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAppStateChanged(app, oldState);
}
}
void ProcessOptimizerUBA::OnAbilityStarted(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
AbilityPtr preAbility;
auto preToken = ability->GetPreToken();
if (GetAbilityByToken) {
// 'preAbility' can be a nullptr.
preAbility = GetAbilityByToken(preToken);
} else {
APP_LOGW(" 'GetAbilityByToken' is not registered.");
}
RecordAbilityAction<StartAbilityAction>(ability, preAbility);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityStarted(ability);
}
}
void ProcessOptimizerUBA::OnAbilityConnected(const AbilityPtr &ability, const AbilityPtr &targetAbility)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
if (!targetAbility) {
APP_LOGE("invalid targetAbility.");
return;
}
RecordAbilityAction<ConnectAbilityAction>(ability, targetAbility);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityConnected(ability, targetAbility);
}
}
void ProcessOptimizerUBA::OnAbilityDisconnected(const AbilityPtr &ability, const AbilityPtr &targetAbility)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
if (!targetAbility) {
APP_LOGE("invalid targetAbility.");
return;
}
RecordAbilityAction<DisconnectAbilityAction>(ability, targetAbility);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityDisconnected(ability, targetAbility);
}
}
void ProcessOptimizerUBA::OnAbilityStateChanged(const AbilityPtr &ability, const AbilityState oldState)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
RecordAbilityAction<ChangeAbilityStateAction>(ability, oldState);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityStateChanged(ability, oldState);
}
}
void ProcessOptimizerUBA::OnAbilityVisibleChanged(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
RecordAbilityAction<ChangeAbilityVisible>(ability);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityVisibleChanged(ability);
}
}
void ProcessOptimizerUBA::OnAbilityPerceptibleChanged(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
RecordAbilityAction<ChangeAbilityPerceptible>(ability);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityPerceptibleChanged(ability);
}
}
void ProcessOptimizerUBA::OnAbilityRemoved(const AbilityPtr &ability)
{
if (!ability) {
APP_LOGE("invalid ability.");
return;
}
RecordAbilityAction<RemoveAbilityAction>(ability);
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnAbilityRemoved(ability);
}
}
void ProcessOptimizerUBA::OnLowMemoryAlert(const CgroupManager::LowMemoryLevel level)
{
auto ubaService = GetUbaService();
if (ubaService) {
APP_LOGI("ubaService implement.");
} else {
ProcessOptimizer::OnLowMemoryAlert(level);
}
}
void ProcessOptimizerUBA::CommitAbilityActions()
{
auto n = abilityActionCount_;
abilityActionCount_ = 0;
auto ubaService = GetUbaService();
if (!ubaService) {
APP_LOGE("uba is not available.");
return;
}
APP_LOGI("committing %{public}zu actions...", n);
for (size_t i = 0; i < n; ++i) {
auto &abilityAction = abilityActionCache_[i];
auto startAbilityAction = std::get_if<StartAbilityAction>(&abilityAction);
if (startAbilityAction) {
CommitStartAbilityAction(*startAbilityAction, i);
continue;
}
auto connectAbilityAction = std::get_if<ConnectAbilityAction>(&abilityAction);
if (connectAbilityAction) {
CommitConnectAbilityAction(*connectAbilityAction, i);
continue;
}
auto disconnectAbilityAction = std::get_if<DisconnectAbilityAction>(&abilityAction);
if (disconnectAbilityAction) {
CommitDisconnectAbilityAction(*disconnectAbilityAction, i);
continue;
}
auto changedAbilityStateAction = std::get_if<ChangeAbilityStateAction>(&abilityAction);
if (changedAbilityStateAction) {
CommitChangedAbilityStateAction(*changedAbilityStateAction, i);
continue;
}
auto removeAbilityAction = std::get_if<RemoveAbilityAction>(&abilityAction);
if (removeAbilityAction) {
CommitRemoveAbilityAction(*removeAbilityAction, i);
continue;
}
}
}
void ProcessOptimizerUBA::CommitStartAbilityAction(const StartAbilityAction& action, size_t index)
{
APP_LOGI(" [%{public}zu] %{public}s ability '%{public}s' starts '%{public}s'",
index,
action.GetTimeString().c_str(),
action.GetPreName().c_str(),
action.GetName().c_str());
// commit action
}
void ProcessOptimizerUBA::CommitConnectAbilityAction(const ConnectAbilityAction& action, size_t index)
{
APP_LOGI(" [%{public}zu] %{public}s ability '%{public}s' connect to '%{public}s'",
index,
action.GetTimeString().c_str(),
action.GetName().c_str(),
action.GetTargetName().c_str());
// commit action
}
void ProcessOptimizerUBA::CommitDisconnectAbilityAction(const DisconnectAbilityAction& action, size_t index)
{
APP_LOGI(" [%{public}zu] %{public}s '%{public}s' ability disconnect with '%{public}s'",
index,
action.GetTimeString().c_str(),
action.GetName().c_str(),
action.GetTargetName().c_str());
// commit action
}
void ProcessOptimizerUBA::CommitChangedAbilityStateAction(const ChangeAbilityStateAction& action, size_t index)
{
APP_LOGI(" [%{public}zu] %{public}s ability '%{public}s' state changed from %{public}d to %{public}d.",
index,
action.GetTimeString().c_str(),
action.GetName().c_str(),
action.GetOldState(),
action.GetNewState());
// commit action
}
void ProcessOptimizerUBA::CommitRemoveAbilityAction(const RemoveAbilityAction& action, size_t index)
{
APP_LOGI(" [%{public}zu] %{public}s '%{public}s' removed.",
index,
action.GetTimeString().c_str(),
action.GetName().c_str());
// commit action
}
UbaServicePtr ProcessOptimizerUBA::GetUbaService()
{
if (ubaService_) {
return ubaService_;
}
// try to get uba service here.
return nullptr;
}
} // namespace AppExecFwk
} // namespace OHOS
-6
View File
@@ -111,14 +111,8 @@ group("unittest") {
"unittest/ams_app_running_record_test:unittest",
"unittest/ams_app_state_callback_test:unittest",
"unittest/ams_app_workflow_test:unittest",
# "unittest/ams_cgroup_manager_test:unittest",
"unittest/ams_ipc_interface_test:unittest",
# "unittest/ams_lmks_client_test:unittest",
"unittest/ams_mgr_scheduler_test:unittest",
# "unittest/ams_process_optimizer_test:unittest",
"unittest/ams_recent_app_list_test:unittest",
"unittest/ams_service_app_spawn_client_test:unittest",
"unittest/ams_service_app_spawn_msg_wrapper_test:unittest",
@@ -55,8 +55,6 @@ public:
MOCK_METHOD5(AbilityBehaviorAnalysis,
void(const sptr<IRemoteObject> &token, const sptr<IRemoteObject> &preToken, const int32_t visibility,
const int32_t perceptibility, const int32_t connectionState));
MOCK_METHOD2(OptimizerAbilityStateChanged,
void(const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state));
MOCK_METHOD1(AddAbilityStageDone, void(const int32_t recordId));
void Post()
{
@@ -1,156 +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 "cgroup_manager.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/eventfd.h>
#include <sys/types.h>
#include <unistd.h>
#include "app_log_wrapper.h"
#include "event_handler.h"
#include "securec.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
class ScopeGuard final {
public:
using Function = std::function<void()>;
public:
explicit ScopeGuard(Function fn) : fn_(fn), dismissed_(false)
{}
~ScopeGuard()
{
if (!dismissed_) {
fn_();
}
}
public:
void Dismiss()
{
dismissed_ = true;
}
private:
Function fn_;
bool dismissed_ = false;
};
} // namespace
CgroupManager::CgroupManager() : memoryEventControlFd_(-1)
{}
CgroupManager::~CgroupManager()
{}
bool CgroupManager::Init()
{
APP_LOGD("Init start.");
return true;
}
bool CgroupManager::IsInited() const
{
APP_LOGD("IsInited start.");
return true;
}
bool CgroupManager::SetThreadSchedPolicy(int tid, SchedPolicy schedPolicy)
{
APP_LOGD("SetThreadSchedPolicy start.");
return true;
}
bool CgroupManager::SetProcessSchedPolicy(int pid, SchedPolicy schedPolicy)
{
APP_LOGD("SetProcessSchedPolicy start.");
return true;
}
void CgroupManager::OnReadable(int32_t fd)
{
APP_LOGD("OnReadable start.");
return;
}
bool CgroupManager::RegisterLowMemoryMonitor(const int memoryEventFds[LOW_MEMORY_LEVEL_MAX],
const int memoryPressureFds[LOW_MEMORY_LEVEL_MAX], const int memoryEventControlFd, const LowMemoryLevel level,
const std::shared_ptr<EventHandler> &eventHandler)
{
APP_LOGD("RegisterLowMemoryMonitor start.");
return true;
}
bool CgroupManager::InitCpusetTasksFds(UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX])
{
APP_LOGD("InitCpusetTasksFds start.");
return true;
}
bool CgroupManager::InitCpuctlTasksFds(UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX])
{
APP_LOGD("InitCpuctlTasksFds start.");
return true;
}
bool CgroupManager::InitFreezerTasksFds(UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX])
{
APP_LOGD("InitFreezerTasksFds start.");
return true;
}
bool CgroupManager::InitMemoryEventControlFd(UniqueFd &memoryEventControlFd)
{
APP_LOGD("InitMemoryEventControlFd start.");
return true;
}
bool CgroupManager::InitMemoryEventFds(UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX])
{
APP_LOGD("InitMemoryEventFds start.");
return true;
}
bool CgroupManager::InitMemoryPressureFds(UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX])
{
APP_LOGD("InitMemoryPressureFds start.");
return true;
}
bool CgroupManager::SetCpusetSubsystem(const int tid, const SchedPolicy schedPolicy)
{
APP_LOGD("SetCpusetSubsystem start.");
return true;
}
bool CgroupManager::SetCpuctlSubsystem(const int tid, const SchedPolicy schedPolicy)
{
APP_LOGD("SetCpuctlSubsystem start.");
return true;
}
bool CgroupManager::SetFreezerSubsystem(const int tid, const SchedPolicyFreezer state)
{
APP_LOGD("SetFreezerSubsystem start.");
return true;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -30,11 +30,7 @@ ohos_unittest("AppDeathRecipientTest") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
"${services_path}/appmgr/test/mock/src/mock_bundle_manager.cpp",
]
@@ -38,11 +38,7 @@ ohos_unittest("AmsAppLifeCycleTest") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
"${services_path}/appmgr/test/mock/src/mock_bundle_manager.cpp",
]
@@ -1711,52 +1711,6 @@ HWTEST_F(AmsAppLifeCycleTest, AppStateChanged001, TestSize.Level1)
serviceInner_->OnAppStateChanged(appRecord, ApplicationState::APP_STATE_END);
}
/*
* Feature: AMS
* Function: AppLifeCycle
* SubFunction: UnsuspendApplication
* FunctionPoints: UnsuspendApplication
* CaseDescription: test application state is APP_STATE_BACKGROUND
*/
HWTEST_F(AmsAppLifeCycleTest, Unsuspend_001, TestSize.Level1)
{
TestApplicationPreRecord testAppRecord = PrepareLoadTestAbilityAndApp(ApplicationState::APP_STATE_FOREGROUND);
testAppRecord.appRecord_->LaunchPendingAbilities();
EXPECT_CALL(*(testAppRecord.mockAppScheduler_), ScheduleLaunchAbility(_, _, _)).Times(1);
auto newAbilityRecord = AddNewAbility(testAppRecord.appRecord_, "1");
EXPECT_EQ(AbilityState::ABILITY_STATE_READY, newAbilityRecord->GetState());
EXPECT_EQ(ApplicationState::APP_STATE_FOREGROUND, testAppRecord.appRecord_->GetState());
testAppRecord.appRecord_->SetState(ApplicationState::APP_STATE_BACKGROUND);
EXPECT_EQ(ApplicationState::APP_STATE_BACKGROUND, testAppRecord.appRecord_->GetState());
testAppRecord.appRecord_->SetState(ApplicationState::APP_STATE_SUSPENDED);
EXPECT_EQ(ApplicationState::APP_STATE_SUSPENDED, testAppRecord.appRecord_->GetState());
serviceInner_->UnsuspendApplication(testAppRecord.appRecord_);
EXPECT_EQ(ApplicationState::APP_STATE_SUSPENDED, testAppRecord.appRecord_->GetState());
}
/*
* Feature: AMS
* Function: AppLifeCycle
* SubFunction: UnsuspendApplication
* FunctionPoints: UnsuspendApplication
* CaseDescription: test application state is APP_STATE_SUSPENDED(apprecord is nullptr)
*/
HWTEST_F(AmsAppLifeCycleTest, Unsuspend_002, TestSize.Level1)
{
TestApplicationPreRecord testAppRecord = PrepareLoadTestAbilityAndApp(ApplicationState::APP_STATE_FOREGROUND);
testAppRecord.appRecord_->LaunchPendingAbilities();
EXPECT_CALL(*(testAppRecord.mockAppScheduler_), ScheduleLaunchAbility(_, _, _)).Times(1);
auto newAbilityRecord = AddNewAbility(testAppRecord.appRecord_, "1");
EXPECT_EQ(AbilityState::ABILITY_STATE_READY, newAbilityRecord->GetState());
EXPECT_EQ(ApplicationState::APP_STATE_FOREGROUND, testAppRecord.appRecord_->GetState());
testAppRecord.appRecord_->SetState(ApplicationState::APP_STATE_BACKGROUND);
EXPECT_EQ(ApplicationState::APP_STATE_BACKGROUND, testAppRecord.appRecord_->GetState());
testAppRecord.appRecord_->SetState(ApplicationState::APP_STATE_SUSPENDED);
EXPECT_EQ(ApplicationState::APP_STATE_SUSPENDED, testAppRecord.appRecord_->GetState());
serviceInner_->UnsuspendApplication(nullptr);
EXPECT_EQ(ApplicationState::APP_STATE_SUSPENDED, testAppRecord.appRecord_->GetState());
}
/*
* Feature: AMS
* Function: AppLifeCycle
@@ -1778,27 +1732,6 @@ HWTEST_F(AmsAppLifeCycleTest, Suspend_001, TestSize.Level1)
EXPECT_EQ(ApplicationState::APP_STATE_SUSPENDED, testAppRecord.appRecord_->GetState());
}
/*
* Feature: AMS
* Function: AppLifeCycle
* SubFunction: UnsuspendApplication
* FunctionPoints: UnsuspendApplication
* CaseDescription: test application state is APP_STATE_BACKGROUND(apprecord is nullptr)
*/
HWTEST_F(AmsAppLifeCycleTest, Suspend_002, TestSize.Level1)
{
TestApplicationPreRecord testAppRecord = PrepareLoadTestAbilityAndApp(ApplicationState::APP_STATE_FOREGROUND);
testAppRecord.appRecord_->LaunchPendingAbilities();
EXPECT_CALL(*(testAppRecord.mockAppScheduler_), ScheduleLaunchAbility(_, _, _)).Times(1);
auto newAbilityRecord = AddNewAbility(testAppRecord.appRecord_, "1");
EXPECT_EQ(AbilityState::ABILITY_STATE_READY, newAbilityRecord->GetState());
EXPECT_EQ(ApplicationState::APP_STATE_FOREGROUND, testAppRecord.appRecord_->GetState());
testAppRecord.appRecord_->SetState(ApplicationState::APP_STATE_BACKGROUND);
EXPECT_EQ(ApplicationState::APP_STATE_BACKGROUND, testAppRecord.appRecord_->GetState());
serviceInner_->UnsuspendApplication(nullptr);
EXPECT_EQ(ApplicationState::APP_STATE_BACKGROUND, testAppRecord.appRecord_->GetState());
}
/*
* Feature: AMS
* Function: AppLifeCycle
@@ -1965,34 +1898,6 @@ HWTEST_F(AmsAppLifeCycleTest, CheckAppRunningRecordIsExist_001, TestSize.Level1)
EXPECT_EQ(ApplicationState::APP_STATE_FOREGROUND, appRecordProc->GetState());
}
/*
* Feature: AMS
* Function: AppLifeCycle::CreateAppRunningRecord
* SubFunction: bundleMgr CheckPermission
* FunctionPoints: UnsuspendApplication
* CaseDescription: Check if there is background operation permission
*/
HWTEST_F(AmsAppLifeCycleTest, GetAbilityRunningRecordByAbilityToken_001, TestSize.Level1)
{
// RecordQueryResult result;
auto abilityInfo = GetAbilityInfoByIndex("0");
auto appInfo = GetApplication();
sptr<IRemoteObject> token = GetMockToken();
auto abilityRecord = serviceInner_->GetAbilityRunningRecordByAbilityToken(nullptr);
EXPECT_FALSE(abilityRecord);
abilityRecord = serviceInner_->GetAbilityRunningRecordByAbilityToken(token);
EXPECT_FALSE(abilityRecord);
auto appRecord = StartProcessAndLoadAbility(token, nullptr, abilityInfo, appInfo, 1234);
EXPECT_TRUE(appRecord);
abilityRecord = serviceInner_->GetAbilityRunningRecordByAbilityToken(token);
sptr<IRemoteObject> token2 = new MockAbilityToken();
auto abilityRecord2 = serviceInner_->GetAbilityRunningRecordByAbilityToken(token2);
EXPECT_FALSE(abilityRecord2);
}
/*
* Feature: AMS
* Function: AppLifeCycle::StartResidentProcess
@@ -39,11 +39,7 @@ ohos_unittest("AmsWorkFlowTest") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
]
@@ -1,57 +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.
import("//build/test.gni")
import("//foundation/aafwk/standard/aafwk.gni")
module_output_path = "ability_runtime/appmgrservice"
ohos_unittest("AmsCgroupManagerTest") {
module_out_path = module_output_path
include_dirs = [
"//foundation/aafwk/standard/services/appmgr/include",
"//base/account/os_account/frameworks/common/database/include",
"//base/account/os_account/frameworks/common/account_error/include",
]
sources = [ "${services_path}/appmgr/src/cgroup_manager.cpp" ]
sources += [ "ams_cgroup_manager_test.cpp" ]
configs = [
"${services_path}/appmgr/test:appmgr_test_config",
"${appexecfwk_path}/libs/libeventhandler:libeventhandler_config",
]
cflags = []
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
deps = [
"${aafwk_path}/interfaces/innerkits/app_manager:app_manager",
"${appexecfwk_path}/libs/libeventhandler:libeventhandler_target",
"${services_path}/appmgr/test:appmgr_test_source",
"//base/account/os_account/frameworks/osaccount/native:os_account_innerkits",
]
external_deps = [
"bundle_framework:appexecfwk_core",
"hiviewdfx_hilog_native:libhilog",
]
}
group("unittest") {
testonly = true
deps = [ ":AmsCgroupManagerTest" ]
}
@@ -1,58 +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.
import("//build/test.gni")
import("//foundation/aafwk/standard/aafwk.gni")
module_output_path = "ability_runtime/appmgrservice"
ohos_unittest("AmsLmksClientTest") {
module_out_path = module_output_path
include_dirs = [
"//foundation/aafwk/standard/services/appmgr/include",
"//base/account/os_account/frameworks/common/database/include",
"//base/account/os_account/frameworks/common/account_error/include",
]
sources = [ "${services_path}/appmgr/src/lmks_client.cpp" ]
sources += [ "ams_lmks_client_test.cpp" ]
configs = [
"${services_path}/appmgr/test:appmgr_test_config",
"${appexecfwk_path}/libs/libeventhandler:libeventhandler_config",
]
cflags = []
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
deps = [
"${appexecfwk_path}/libs/libeventhandler:libeventhandler_target",
"${services_path}/appmgr/test:appmgr_test_source",
"//base/account/os_account/frameworks/osaccount/native:os_account_innerkits",
"//foundation/aafwk/standard/interfaces/innerkits/app_manager:app_manager",
]
external_deps = [
"bundle_framework:appexecfwk_core",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
}
group("unittest") {
testonly = true
deps = [ ":AmsLmksClientTest" ]
}
@@ -1,387 +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.
*/
#define private public
#include "lmks_client.h"
#undef private
#include <gtest/gtest.h>
#include <fcntl.h>
#include <sys/eventfd.h>
#include <unistd.h>
#include <sys/socket.h>
#include "app_log_wrapper.h"
using namespace testing::ext;
namespace OHOS {
namespace AppExecFwk {
class AmsLmksClientTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
};
void AmsLmksClientTest::SetUpTestCase()
{}
void AmsLmksClientTest::TearDownTestCase()
{}
void AmsLmksClientTest::SetUp()
{}
void AmsLmksClientTest::TearDown()
{}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Open
* FunctionPoints: open socket
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Open can check the invalid socket_
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Open_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Open_001 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
amsLmksClient->socket_ = 0;
EXPECT_EQ(-1, amsLmksClient->Open());
APP_LOGD("AmsLmksClientTest_Open_001 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Open
* FunctionPoints: open socket
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: open socket success
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Open_002, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Open_002 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
amsLmksClient->socket_ = -1;
EXPECT_EQ(ERR_OK, amsLmksClient->Open());
APP_LOGD("AmsLmksClientTest_Open_002 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Target
* FunctionPoints: Oom adj mapping table value of the initialization process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Target can check the invalid targets
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Target_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Target_001 start.");
std::vector<std::pair<int, int>> targets;
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
EXPECT_EQ(-EINVAL, amsLmksClient->Target(targets));
APP_LOGD("AmsLmksClientTest_Target_001 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Target
* FunctionPoints: Oom adj mapping table value of the initialization process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Target can check the invalid targets
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Target_002, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Target_002 start.");
std::vector<std::pair<int, int>> targets{{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}};
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
EXPECT_EQ(-EINVAL, amsLmksClient->Target(targets));
APP_LOGD("AmsLmksClientTest_Target_002 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Target
* FunctionPoints: Oom adj mapping table value of the initialization process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Target can check the invalid targets
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Target_003, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Target_003 start.");
std::vector<std::pair<int, int>> targets{{-1, 2}};
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
EXPECT_EQ(-EINVAL, amsLmksClient->Target(targets));
APP_LOGD("AmsLmksClientTest_Target_003 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Target
* FunctionPoints: Oom adj mapping table value of the initialization process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Target can check the invalid targets
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Target_004, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Target_004 start.");
std::vector<std::pair<int, int>> targets{{1, 1100}};
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
EXPECT_EQ(-EINVAL, amsLmksClient->Target(targets));
APP_LOGD("AmsLmksClientTest_Target_004 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Target
* FunctionPoints: Oom adj mapping table value of the initialization process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function Target can be executed normally
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Target_005, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Target_005 start.");
std::vector<std::pair<int, int>> targets{{1, 10}};
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
EXPECT_EQ(ERR_OK, amsLmksClient->Target(targets));
APP_LOGD("AmsLmksClientTest_Target_005 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: ProcPrio
* FunctionPoints: Update the oom adj value of pid
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function ProcPrio can check the invalid pid
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_ProcPrio_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_ProcPrio_001 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
pid_t pid = -1;
uid_t uid = 1;
int oomAdj = 0;
EXPECT_EQ(-EINVAL, amsLmksClient->ProcPrio(pid, uid, oomAdj));
APP_LOGD("AmsLmksClientTest_ProcPrio_001 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: ProcPrio
* FunctionPoints: Update the oom adj value of pid
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function ProcPrio can check the invalid oomAdj
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_ProcPrio_002, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_ProcPrio_002 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
pid_t pid = 1;
uid_t uid = 1;
int oomAdj = 1100;
EXPECT_EQ(-EINVAL, amsLmksClient->ProcPrio(pid, uid, oomAdj));
APP_LOGD("AmsLmksClientTest_ProcPrio_002 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: ProcPrio
* FunctionPoints: Update the oom adj value of pid
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function ProcPrio can be executed normally
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_ProcPrio_003, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_ProcPrio_003 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
pid_t pid = 1;
uid_t uid = 1;
int oomAdj = 10;
EXPECT_EQ(ERR_OK, amsLmksClient->ProcPrio(pid, uid, oomAdj));
APP_LOGD("AmsLmksClientTest_ProcPrio_003 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: ProcRemove
* FunctionPoints: remove process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function ProcRemove can check the invalid pid
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_ProcRemove_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_ProcRemove_001 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
pid_t pid = -1;
EXPECT_EQ(-EINVAL, amsLmksClient->ProcRemove(pid));
APP_LOGD("AmsLmksClientTest_ProcRemove_001 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: ProcRemove
* FunctionPoints: remove process
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function ProcRemove success to remove process
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_ProcRemove_002, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_ProcRemove_002 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
pid_t pid = 1;
EXPECT_EQ(0, amsLmksClient->ProcRemove(pid));
APP_LOGD("AmsLmksClientTest_ProcRemove_002 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Write
* FunctionPoints: send data
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Write can check the invalid buf
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Write_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Write_001 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
int32_t *buf = nullptr;
size_t len = 2;
EXPECT_EQ(false, amsLmksClient->Write(buf, len));
APP_LOGD("AmsLmksClientTest_Write_001 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Write
* FunctionPoints: send data
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Write can check the invalid len
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Write_002, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Write_002 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
int32_t buf[2] = {1, 2};
size_t len = -1;
EXPECT_EQ(false, amsLmksClient->Write(buf, len));
APP_LOGD("AmsLmksClientTest_Write_002 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Read
* FunctionPoints: Receive data
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Read can check the invalid buf
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Read_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Read_001 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
int32_t *buf = nullptr;
size_t len = 2;
EXPECT_EQ(false, amsLmksClient->Read(buf, len));
APP_LOGD("AmsLmksClientTest_Read_001 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Read
* FunctionPoints: Receive data
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Read can check the invalid len
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Read_002, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Read_002 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
int32_t buf[2] = {1, 2};
size_t len = -1;
EXPECT_EQ(false, amsLmksClient->Read(buf, len));
APP_LOGD("AmsLmksClientTest_Read_002 end.");
}
/*
* Feature: AMS
* Function: LmksClient
* SubFunction: Close
* FunctionPoints: close socket
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the close function closes the socket
*/
HWTEST_F(AmsLmksClientTest, AmsLmksClientTest_Close_001, TestSize.Level1)
{
APP_LOGD("AmsLmksClientTest_Close_001 start.");
std::unique_ptr<LmksClient> amsLmksClient = std::make_unique<LmksClient>();
amsLmksClient->Close();
EXPECT_EQ(false, amsLmksClient->IsOpen());
APP_LOGD("AmsLmksClientTest_Close_001 end.");
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -1,69 +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.
import("//build/test.gni")
import("//foundation/aafwk/standard/aafwk.gni")
module_output_path = "ability_runtime/appmgrservice"
ohos_unittest("AmsamsProcessOptimizerTest") {
module_out_path = module_output_path
include_dirs = [
"//foundation/aafwk/standard/interfaces/innerkits/base/include",
"//foundation/aafwk/standard/interfaces/innerkits/want/include",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include",
"//foundation/aafwk/standard/services/appmgr/include",
"//base/account/os_account/frameworks/common/database/include",
"//base/account/os_account/frameworks/common/account_error/include",
]
sources = [
"${services_path}/appmgr/src/app_running_record.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
]
sources += [
"${services_path}/appmgr/test/mock/src/cgroup_manager.cpp",
"ams_process_optimizer_test.cpp",
]
configs = [
"${services_path}/appmgr/test:appmgr_test_config",
"${appexecfwk_path}/libs/libeventhandler:libeventhandler_config",
]
cflags = []
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
deps = [
"${aafwk_path}/interfaces/innerkits/app_manager:app_manager",
"${appexecfwk_path}/libs/libeventhandler:libeventhandler_target",
"${services_path}/appmgr/test:appmgr_test_source",
"//base/account/os_account/frameworks/osaccount/native:os_account_innerkits",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
]
external_deps = [
"bundle_framework:appexecfwk_core",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
}
group("unittest") {
testonly = true
deps = [ ":AmsamsProcessOptimizerTest" ]
}
@@ -1,905 +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 <gtest/gtest.h>
#define private public
#define protected public
#include "process_optimizer.h"
#undef private
#undef protected
#include "app_log_wrapper.h"
#include <fcntl.h>
#include <sys/eventfd.h>
#include <unistd.h>
#include "lmks_client.h"
namespace{
constexpr int APP_OOM_ADJ_BACKGROUND_MIN = 400;
constexpr int APP_OOM_ADJ_SUSPEND_MIN = 600;
const std::string APP_RECORD_NAME = "App_Name_Z";
static constexpr int APP_SUSPEND_TIMEOUT_DEFAULT = 100;
static constexpr int APP_USLEEP = 200 * 1000;
using namespace testing::ext;
};
namespace OHOS {
namespace AppExecFwk {
class AmsProcessOptimizerTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
};
void AmsProcessOptimizerTest::SetUpTestCase()
{}
void AmsProcessOptimizerTest::TearDownTestCase()
{}
void AmsProcessOptimizerTest::SetUp()
{}
void AmsProcessOptimizerTest::TearDown()
{}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: Init
* FunctionPoints: initialization
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Init can check the invalid suspendTimeout
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_Init_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_Init_001 start.");
auto lmksClient = std::make_shared<LmksClient>();
int suspendTimeout = -1;
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer =
std::make_unique<ProcessOptimizer>(lmksClient, suspendTimeout);
EXPECT_EQ(false, amsProcessOptimizer->Init());
APP_LOGD("AmsProcessOptimizerTest_Init_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: Init
* FunctionPoints: initialization
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function Init can check the invalid eventHandler_
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_Init_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_Init_002 start.");
auto lmksClient = std::make_shared<LmksClient>();
int suspendTimeout = 0;
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer =
std::make_unique<ProcessOptimizer>(lmksClient, suspendTimeout);
amsProcessOptimizer->eventHandler_ = std::make_shared<EventHandler>(EventRunner::Create());
EXPECT_EQ(false, amsProcessOptimizer->Init());
amsProcessOptimizer->eventHandler_ = nullptr;
APP_LOGD("AmsProcessOptimizerTest_Init_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: Init
* FunctionPoints: initialization
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function Init can be executed normally and initialize
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_Init_003, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_Init_003 start.");
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
EXPECT_EQ(true, amsProcessOptimizer->Init());
APP_LOGD("AmsProcessOptimizerTest_Init_003 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppAdded
* FunctionPoints: add application in appLru_
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function OnAppAdded can check the invalid app
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_OnAppAdded_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_OnAppAdded_001 start.");
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
amsProcessOptimizer->appLru_.clear();
amsProcessOptimizer->OnAppAdded(nullptr);
EXPECT_TRUE(amsProcessOptimizer->appLru_.size() == 0);
APP_LOGD("AmsProcessOptimizerTest_OnAppAdded_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppAdded
* FunctionPoints: add application in appLru_
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function OnAppAdded adds app to appLru_
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_OnAppAdded_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_OnAppAdded_002 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
amsProcessOptimizer->appLru_.clear();
amsProcessOptimizer->OnAppAdded(app);
EXPECT_TRUE(amsProcessOptimizer->appLru_.size() > 0);
APP_LOGD("AmsProcessOptimizerTest_OnAppAdded_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppRemoved
* FunctionPoints: remove application from appLru_
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function OnAppRemoved can check the invalid app
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_OnAppRemoved_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_OnAppRemoved_001 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
amsProcessOptimizer->appLru_.clear();
amsProcessOptimizer->appLru_.push_front(app);
amsProcessOptimizer->OnAppRemoved(nullptr);
EXPECT_TRUE(amsProcessOptimizer->appLru_.size() > 0);
APP_LOGD("AmsProcessOptimizerTest_OnAppRemoved_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppRemoved
* FunctionPoints: remove application from appLru_
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify whether the function OnAppRemoved removes the app in appLru_
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_OnAppRemoved_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_OnAppRemoved_002 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
amsProcessOptimizer->appLru_.clear();
amsProcessOptimizer->appLru_.push_front(app);
amsProcessOptimizer->OnAppRemoved(app);
EXPECT_TRUE(amsProcessOptimizer->appLru_.size() == 0);
APP_LOGD("AmsProcessOptimizerTest_OnAppRemoved_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppStateChanged
* FunctionPoints: change application state
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify whether the function OnAppStateChanged moves app2 in appLru_ to the head
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_OnAppStateChanged_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_OnAppStateChanged_001 start.");
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto app1 = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app1->GetPriorityObject()->SetPid(11);
auto app2 = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app2->GetPriorityObject()->SetPid(22);
auto app3 = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app3->GetPriorityObject()->SetPid(33);
amsProcessOptimizer->appLru_.clear();
amsProcessOptimizer->appLru_.push_back(app1);
amsProcessOptimizer->appLru_.push_back(app2);
amsProcessOptimizer->appLru_.push_back(app3);
app2->SetState(ApplicationState::APP_STATE_FOREGROUND);
amsProcessOptimizer->OnAppStateChanged(app2, ApplicationState::APP_STATE_BEGIN);
EXPECT_TRUE(app2 == amsProcessOptimizer->appLru_.front());
APP_LOGD("AmsProcessOptimizerTest_OnAppStateChanged_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppOomAdj
* FunctionPoints: set application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function SetAppOomAdj can check the invalid app
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppOomAdj_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_001 start.");
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
int oomAdj = 1;
EXPECT_EQ(false, amsProcessOptimizer->SetAppOomAdj(nullptr, oomAdj));
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppOomAdj
* FunctionPoints: set application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function SetAppOomAdj can check the invalid oomAdj
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppOomAdj_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_002 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
int oomAdj = 1100;
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
EXPECT_EQ(false, amsProcessOptimizer->SetAppOomAdj(app, oomAdj));
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppOomAdj
* FunctionPoints: set application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function SetAppOomAdj can check the invalid lmksClient_
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppOomAdj_003, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_003 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(nullptr);
int oomAdj = 1;
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
EXPECT_EQ(false, amsProcessOptimizer->SetAppOomAdj(app, oomAdj));
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_003 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppOomAdj
* FunctionPoints: set application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Oom adj has no change in the verification function SetAppOomAdj
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppOomAdj_004, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_004 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
int oomAdj = 1;
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
auto priorityObject = app->GetPriorityObject();
EXPECT_TRUE(priorityObject != nullptr);
priorityObject->SetCurAdj(oomAdj);
EXPECT_EQ(true, amsProcessOptimizer->SetAppOomAdj(app, oomAdj));
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_004 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppOomAdj
* FunctionPoints: set application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function SetAppOomAdj is executed normally
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppOomAdj_005, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_005 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
int oomAdj = 1;
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
EXPECT_EQ(true, amsProcessOptimizer->SetAppOomAdj(app, oomAdj));
APP_LOGD("AmsProcessOptimizerTest_SetAppOomAdj_005 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppSchedPolicy
* FunctionPoints: set the application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function SetAppSchedPolicy can check the invalid app
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppSchedPolicy_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_001 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
EXPECT_EQ(
false, amsProcessOptimizer->SetAppSchedPolicy(nullptr, CgroupManager::SchedPolicy::SCHED_POLICY_BACKGROUND));
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppSchedPolicy
* FunctionPoints: set the application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the incoming SchedPolicy is the same as before
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppSchedPolicy_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_002 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetCurCgroup(CgroupManager::SchedPolicy::SCHED_POLICY_BACKGROUND);
EXPECT_EQ(true, amsProcessOptimizer->SetAppSchedPolicy(app, CgroupManager::SchedPolicy::SCHED_POLICY_BACKGROUND));
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppSchedPolicy
* FunctionPoints: set the application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the incoming SchedPolicy is equal to CgroupManager::SCHED_POLICY_FREEZED
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppSchedPolicy_003, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_003 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
EXPECT_EQ(true, amsProcessOptimizer->SetAppSchedPolicy(app, CgroupManager::SchedPolicy::SCHED_POLICY_FREEZED));
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_003 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: SetAppSchedPolicy
* FunctionPoints: set the application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the old SchedPolicy is equal to CgroupManager::SCHED_POLICY_FREEZED
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_SetAppSchedPolicy_004, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_004 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetCurCgroup(CgroupManager::SchedPolicy::SCHED_POLICY_FREEZED);
EXPECT_EQ(true, amsProcessOptimizer->SetAppSchedPolicy(app, CgroupManager::SchedPolicy::SCHED_POLICY_BACKGROUND));
APP_LOGD("AmsProcessOptimizerTest_SetAppSchedPolicy_004 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnLowMemoryAlert
* FunctionPoints: processing when low memory
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the OnLowMemoryAlert function will remove the app in appLru_ when the pid is less than
* zero
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_OnLowMemoryAlert_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_OnLowMemoryAlert_001 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
auto priorityObject = app->GetPriorityObject();
amsProcessOptimizer->appLru_.clear();
amsProcessOptimizer->appLru_.push_back(app);
priorityObject->SetPid(-1);
amsProcessOptimizer->OnLowMemoryAlert(CgroupManager::LowMemoryLevel::LOW_MEMORY_LEVEL_CRITICAL);
EXPECT_TRUE(amsProcessOptimizer->appLru_.size() == 0);
APP_LOGD("AmsProcessOptimizerTest_OnLowMemoryAlert_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppOomAdj
* FunctionPoints: update application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function UpdateAppOomAdj can check the invalid app
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppOomAdj_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_001 start.");
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
EXPECT_EQ(false, amsProcessOptimizer->UpdateAppOomAdj(nullptr));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppOomAdj
* FunctionPoints: update application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function UpdateAppOomAdj can check the invalid state
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppOomAdj_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_002 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_FOREGROUND);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetCurAdj(0);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppOomAdj(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppOomAdj
* FunctionPoints: update application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function UpdateAppOomAdj can check the invalid state
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppOomAdj_003, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_003 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_CREATE);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetCurAdj(0);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppOomAdj(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_003 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppOomAdj
* FunctionPoints: update application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function UpdateAppOomAdj can check the invalid state
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppOomAdj_004, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_004 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_READY);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetCurAdj(0);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppOomAdj(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_004 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppOomAdj
* FunctionPoints: update application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check the execution of the UpdateAppOomAdj function when the state is normal
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppOomAdj_005, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_005 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_BACKGROUND);
amsProcessOptimizer->appLru_.push_back(app);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppOomAdj(app));
auto priorityObject = app->GetPriorityObject();
auto curAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(curAdj == APP_OOM_ADJ_BACKGROUND_MIN);
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_005 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppOomAdj
* FunctionPoints: update application OOM adjustment
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check the execution of the UpdateAppOomAdj function when the state is normal
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppOomAdj_006, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_006 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_SUSPENDED);
amsProcessOptimizer->appLru_.push_back(app);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppOomAdj(app));
auto priorityObject = app->GetPriorityObject();
auto curAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(curAdj == APP_OOM_ADJ_SUSPEND_MIN);
APP_LOGD("AmsProcessOptimizerTest_UpdateAppOomAdj_006 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify the function UpdateAppSchedPolicy can check the invalid app
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_001 start.");
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
EXPECT_EQ(false, amsProcessOptimizer->UpdateAppSchedPolicy(nullptr));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the case ApplicationState::APP_STATE_CREATE in the switch case can be executed
* correctly
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_002, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_002 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_CREATE);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppSchedPolicy(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_002 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the case ApplicationState::APP_STATE_READY in the switch case can be executed
* correctly
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_003, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_003 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_READY);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppSchedPolicy(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_003 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the case ApplicationState::APP_STATE_FOREGROUND in the switch case can be executed
* correctly
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_004, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_004 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_FOREGROUND);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppSchedPolicy(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_004 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the case ApplicationState::APP_STATE_BACKGROUND in the switch case can be executed
* correctly
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_005, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_005 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_BACKGROUND);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppSchedPolicy(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_005 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the case ApplicationState::APP_STATE_SUSPENDED in the switch case can be executed
* correctly
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_006, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_006 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_SUSPENDED);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppSchedPolicy(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_006 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: UpdateAppSchedPolicy
* FunctionPoints: update application SchedPolicy
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Check whether the default in switch case can be executed correctly
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_UpdateAppSchedPolicy_007, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_007 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_END);
EXPECT_EQ(true, amsProcessOptimizer->UpdateAppSchedPolicy(app));
APP_LOGD("AmsProcessOptimizerTest_UpdateAppSchedPolicy_007 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: StartAppSuspendTimer
* FunctionPoints: start application SuspendTimer
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function StartAppSuspendTimer can work normally.
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_StartAppSuspendTimer_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_StartAppSuspendTimer_001 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer =
std::make_unique<ProcessOptimizer>(lmksClient, APP_SUSPEND_TIMEOUT_DEFAULT);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
amsProcessOptimizer->eventHandler_ = std::make_shared<EventHandler>(EventRunner::Create());
EXPECT_TRUE(amsProcessOptimizer->eventHandler_ != nullptr);
amsProcessOptimizer->suspendTimers_.clear();
amsProcessOptimizer->StartAppSuspendTimer(app);
EXPECT_TRUE(amsProcessOptimizer->suspendTimers_.size() > 0);
usleep(APP_USLEEP);
EXPECT_TRUE(amsProcessOptimizer->suspendTimers_.size() == 0);
amsProcessOptimizer->eventHandler_ = nullptr;
APP_LOGD("AmsProcessOptimizerTest_StartAppSuspendTimer_001 end.");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: StopAppSuspendTimer
* FunctionPoints: stop application SuspendTimer
* EnvConditions: Mobile that can run ohos test framework.
* CaseDescription: Verify that the function StopAppSuspendTimer can work normally.
*/
HWTEST_F(AmsProcessOptimizerTest, AmsProcessOptimizerTest_StopAppSuspendTimer_001, TestSize.Level1)
{
APP_LOGD("AmsProcessOptimizerTest_StopAppSuspendTimer_001 start.");
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto lmksClient = std::make_shared<LmksClient>();
std::unique_ptr<ProcessOptimizer> amsProcessOptimizer = std::make_unique<ProcessOptimizer>(lmksClient);
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
amsProcessOptimizer->eventHandler_ = std::make_shared<EventHandler>(EventRunner::Create());
EXPECT_TRUE(amsProcessOptimizer->eventHandler_ != nullptr);
amsProcessOptimizer->suspendTimers_.clear();
auto timerName = amsProcessOptimizer->GetAppSuspendTimerName(app);
amsProcessOptimizer->suspendTimers_.emplace(timerName);
amsProcessOptimizer->StopAppSuspendTimer(app);
auto it = amsProcessOptimizer->suspendTimers_.find(timerName);
EXPECT_TRUE(it == amsProcessOptimizer->suspendTimers_.end());
APP_LOGD("AmsProcessOptimizerTest_StopAppSuspendTimer_001 end.");
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -36,11 +36,7 @@ ohos_unittest("AmsRecentAppListTest") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
"${services_path}/appmgr/test/mock/src/mock_bundle_manager.cpp",
]
@@ -36,11 +36,7 @@ ohos_unittest("AmsServiceLoadAbilityProcessTest") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
"${services_path}/appmgr/test/mock/src/mock_bundle_manager.cpp",
]
@@ -36,11 +36,7 @@ ohos_unittest("AMSEventHandlerTest") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
]
@@ -31,11 +31,7 @@ ohos_source_set("appmgr_mst_source") {
"${services_path}/appmgr/src/app_spawn_client.cpp",
"${services_path}/appmgr/src/app_spawn_msg_wrapper.cpp",
"${services_path}/appmgr/src/app_spawn_socket.cpp",
"${services_path}/appmgr/src/cgroup_manager.cpp",
"${services_path}/appmgr/src/lmks_client.cpp",
"${services_path}/appmgr/src/module_running_record.cpp",
"${services_path}/appmgr/src/process_optimizer.cpp",
"${services_path}/appmgr/src/process_optimizer_uba.cpp",
"${services_path}/appmgr/src/remote_client_manager.cpp",
"${services_path}/appmgr/test/mock/src/mock_bundle_manager.cpp",
@@ -118,7 +114,5 @@ group("moduletest") {
"service_app_spawn_client_test:moduletest",
"service_event_drive_test:moduletest",
"service_start_process_test:moduletest",
# "process_optimizer_uba_test:moduletest",
]
}
@@ -128,8 +128,6 @@ void AmsAppLifeCycleModuleTest::SetUp()
mockBundleMgr = new (std::nothrow) BundleMgrService();
serviceInner_->SetBundleManager(mockBundleMgr);
serviceInner_->ProcessOptimizerInit();
auto runner = EventRunner::Create("AmsAppLifeCycleModuleTest");
handler_ = std::make_shared<AMSEventHandler>(runner, serviceInner_);
serviceInner_->SetEventHandler(handler_);
@@ -1,47 +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.
import("//build/test.gni")
import("//foundation/aafwk/standard/aafwk.gni")
module_output_path = "ability_runtime/mstappmgrservice"
ohos_moduletest("AmsProcessOptimizerModuleTest") {
module_out_path = module_output_path
include_dirs =
[ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include" ]
defines = [
"APP_LOG_TAG = \"AppMgrService\"",
"LOG_DOMAIN = 0xD001110",
]
sources = [ "ams_process_optimizer_uba_module_test.cpp" ]
deps = [
"${services_path}/common:perm_verification",
"${services_path}/test/moduletest/common/ams:appmgr_mst_source",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
}
group("moduletest") {
testonly = true
deps = [ ":AmsProcessOptimizerModuleTest" ]
}
@@ -1,279 +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.
*/
#define private public
#define protected public
#include "app_mgr_service.h"
#undef private
#undef protected
#include <gtest/gtest.h>
#include "app_log_wrapper.h"
using namespace testing::ext;
namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string APP_RECORD_NAME = "App_Name_Z";
// foreground process oom_adj
constexpr int APP_OOM_ADJ_FOREGROUND = 0;
// background process oom_adj
constexpr int APP_OOM_ADJ_BACKGROUND_MIN = 400;
// suspend process oom_adj
constexpr int APP_OOM_ADJ_SUSPEND_MIN = 600;
static constexpr int APP_SUSPEND_TIMEOUT_DEFAULT = 100;
static constexpr int APP_USLEEP = 200 * 1000;
} // namespace
class AmsProcessOptimizerUbaModuleTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
void SuspendApplication(const std::shared_ptr<AppRunningRecord> &appRecord);
void ResumeApplication(const std::shared_ptr<AppRunningRecord> &appRecord);
std::shared_ptr<ProcessOptimizerUBA> processOptimizerUBA =
std::make_unique<ProcessOptimizerUBA>(nullptr, nullptr, APP_SUSPEND_TIMEOUT_DEFAULT);
};
void AmsProcessOptimizerUbaModuleTest::SuspendApplication(const std::shared_ptr<AppRunningRecord> &appRecord)
{
if (!appRecord) {
APP_LOGE("app record is null");
return;
}
APP_LOGD("%{public}s : app name is %{public}s , Uid is %{public}d",
__func__,
appRecord->GetName().c_str(),
appRecord->GetUid());
// Temporary unsubscribe via UID
appRecord->SetState(ApplicationState::APP_STATE_SUSPENDED);
processOptimizerUBA->OnAppStateChanged(appRecord, ApplicationState::APP_STATE_BACKGROUND);
}
void AmsProcessOptimizerUbaModuleTest::ResumeApplication(const std::shared_ptr<AppRunningRecord> &appRecord)
{
if (!appRecord) {
APP_LOGE("app record is null");
return;
}
APP_LOGD("%{public}s : app name is %{public}s , Uid is %{public}d",
__func__,
appRecord->GetName().c_str(),
appRecord->GetUid());
}
void AmsProcessOptimizerUbaModuleTest::SetUpTestCase()
{}
void AmsProcessOptimizerUbaModuleTest::TearDownTestCase()
{}
void AmsProcessOptimizerUbaModuleTest::SetUp()
{}
void AmsProcessOptimizerUbaModuleTest::TearDown()
{}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppAdded
* FunctionPoints: add application
* CaseDescription: Call the OnAppAdded function to add multiple application
*/
HWTEST_F(AmsProcessOptimizerUbaModuleTest, OnAppAdded_001, TestSize.Level1)
{
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppAdded_001 start");
bool isSuccess = processOptimizerUBA->Init();
EXPECT_TRUE(true == isSuccess);
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto app1 = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app1->GetPriorityObject()->SetPid(1000);
auto priorityObject1 = app1->GetPriorityObject();
processOptimizerUBA->OnAppAdded(app1);
auto oomAdj1 = priorityObject1->GetCurAdj();
EXPECT_TRUE(oomAdj1 == APP_OOM_ADJ_FOREGROUND);
auto app2 = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app2->GetPriorityObject()->SetPid(1100);
auto priorityObject2 = app2->GetPriorityObject();
processOptimizerUBA->OnAppAdded(app2);
auto oomAdj2 = priorityObject2->GetCurAdj();
EXPECT_TRUE(oomAdj2 == APP_OOM_ADJ_FOREGROUND);
oomAdj1 = priorityObject1->GetCurAdj();
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppAdded_001 end");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppStateChanged
* FunctionPoints: change application status
* CaseDescription: Set a different state, check the value of adj
*/
HWTEST_F(AmsProcessOptimizerUbaModuleTest, OnAppStateChanged_001, TestSize.Level1)
{
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppStateChanged_001 start");
bool isSuccess = processOptimizerUBA->Init();
EXPECT_TRUE(true == isSuccess);
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
app->SetState(ApplicationState::APP_STATE_FOREGROUND);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetPid(1200);
processOptimizerUBA->OnAppStateChanged(app, ApplicationState::APP_STATE_BACKGROUND);
auto oomAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(oomAdj == APP_OOM_ADJ_FOREGROUND);
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppStateChanged_001 end");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppStateChanged
* FunctionPoints: change application status
* CaseDescription: Set a different state, check the value of adj
*/
HWTEST_F(AmsProcessOptimizerUbaModuleTest, OnAppStateChanged_002, TestSize.Level1)
{
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppStateChanged_002 start");
bool isSuccess = processOptimizerUBA->Init();
EXPECT_TRUE(true == isSuccess);
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
processOptimizerUBA->OnAppAdded(app);
app->SetState(ApplicationState::APP_STATE_BACKGROUND);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetPid(1300);
processOptimizerUBA->OnAppStateChanged(app, ApplicationState::APP_STATE_FOREGROUND);
auto oomAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(oomAdj == APP_OOM_ADJ_BACKGROUND_MIN);
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppStateChanged_002 end");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppStateChanged
* FunctionPoints: change application status
* CaseDescription: 1. Call the OnAppStateChanged function, make the conditions meet, call the StartAppSuspendTimer
function, make the app state suspended
2. Call the OnAppStateChanged function to remove the suspended state
*/
HWTEST_F(AmsProcessOptimizerUbaModuleTest, OnAppStateChanged_003, TestSize.Level1)
{
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppStateChanged_003 start");
processOptimizerUBA->AppSuspended =
std::bind(&AmsProcessOptimizerUbaModuleTest::SuspendApplication, this, std::placeholders::_1);
processOptimizerUBA->AppResumed =
std::bind(&AmsProcessOptimizerUbaModuleTest::ResumeApplication, this, std::placeholders::_1);
bool isSuccess = processOptimizerUBA->Init();
EXPECT_TRUE(true == isSuccess);
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
processOptimizerUBA->OnAppAdded(app);
app->SetState(ApplicationState::APP_STATE_BACKGROUND);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetPid(1);
priorityObject->SetVisibleStatus(false);
priorityObject->SetPerceptibleStatus(false);
processOptimizerUBA->OnAppStateChanged(app, ApplicationState::APP_STATE_FOREGROUND);
usleep(APP_USLEEP);
auto oomAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(oomAdj == APP_OOM_ADJ_SUSPEND_MIN);
GTEST_LOG_(INFO) << "AmsProcessOptimizerUbaModuleTest OnAppStateChanged_003 oomAdj: " << oomAdj;
auto appState = app->GetState();
if (appState == ApplicationState::APP_STATE_SUSPENDED) {
app->SetState(ApplicationState::APP_STATE_BACKGROUND);
processOptimizerUBA->OnAppStateChanged(app, ApplicationState::APP_STATE_SUSPENDED);
oomAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(oomAdj == APP_OOM_ADJ_BACKGROUND_MIN);
}
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppStateChanged_003 end");
}
/*
* Feature: AMS
* Function: ProcessOptimizer
* SubFunction: OnAppRemoved
* FunctionPoints: remove application
* CaseDescription: 1. Call the OnAppStateChanged function to make the conditions meet and call the StartAppSuspendTimer
function
2. Calling the OnAppRemoved function will call the StopAppSuspendTimer function
*/
HWTEST_F(AmsProcessOptimizerUbaModuleTest, OnAppRemoved_001, TestSize.Level1)
{
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppRemoved_001 start");
bool isSuccess = processOptimizerUBA->Init();
EXPECT_TRUE(true == isSuccess);
auto appInfo = std::make_shared<ApplicationInfo>();
appInfo->name = APP_RECORD_NAME;
appInfo->bundleName = APP_RECORD_NAME; // specify process condition
auto app = std::make_shared<AppRunningRecord>(appInfo, AppRecordId::Create(), appInfo->bundleName);
processOptimizerUBA->OnAppAdded(app);
app->SetState(ApplicationState::APP_STATE_BACKGROUND);
auto priorityObject = app->GetPriorityObject();
priorityObject->SetPid(1500);
priorityObject->SetVisibleStatus(false);
priorityObject->SetPerceptibleStatus(false);
processOptimizerUBA->OnAppStateChanged(app, ApplicationState::APP_STATE_FOREGROUND);
processOptimizerUBA->OnAppRemoved(app);
auto oomAdj = priorityObject->GetCurAdj();
EXPECT_TRUE(oomAdj == APP_OOM_ADJ_BACKGROUND_MIN);
APP_LOGI("AmsProcessOptimizerUbaModuleTest OnAppRemoved_001 end");
}
} // namespace AppExecFwk
} // namespace OHOS