mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 12:43:16 -04:00
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:
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"services" : [{
|
||||
"name" : "lmks",
|
||||
"path" : ["/system/bin/lmks"],
|
||||
"importance" : -20,
|
||||
"uid" : "root",
|
||||
"gid" : ["root"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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" ]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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" ]
|
||||
}
|
||||
-905
@@ -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",
|
||||
]
|
||||
}
|
||||
|
||||
-2
@@ -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" ]
|
||||
}
|
||||
-279
@@ -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
|
||||
Reference in New Issue
Block a user