1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "app_state_observer.h"
16
17 #include "sec_comp_log.h"
18 #include "sec_comp_manager.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace SecurityComponent {
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "AppStateObserver"};
25 constexpr int32_t APP_STATE_CACHED = 100;
26 }
27
AppStateObserver()28 AppStateObserver::AppStateObserver()
29 {
30 }
31
~AppStateObserver()32 AppStateObserver::~AppStateObserver()
33 {
34 }
35
IsProcessForeground(int32_t pid,int32_t uid)36 bool AppStateObserver::IsProcessForeground(int32_t pid, int32_t uid)
37 {
38 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
39 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
40 if (pid == iter->pid) {
41 return true;
42 }
43
44 if ((iter->pid == -1) && (uid == iter->uid)) {
45 iter->pid = pid;
46 return true;
47 }
48 }
49 return false;
50 }
51
AddProcessToForegroundSet(int32_t pid,const SecCompProcessData & data)52 void AppStateObserver::AddProcessToForegroundSet(int32_t pid, const SecCompProcessData& data)
53 {
54 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
55 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
56 if (pid == -1) {
57 if (iter->uid == data.uid) {
58 SC_LOG_INFO(LABEL, "uid %{public}d is already in foreground", data.uid);
59 return;
60 }
61 } else if (pid == iter->pid) {
62 SC_LOG_INFO(LABEL, "pid %{public}d is already in foreground", pid);
63 return;
64 }
65 }
66 foregrandProcList_.emplace_back(data);
67 }
68
AddProcessToForegroundSet(const AppExecFwk::AppStateData & stateData)69 void AppStateObserver::AddProcessToForegroundSet(const AppExecFwk::AppStateData& stateData)
70 {
71 SecCompProcessData proc = {
72 .bundleName = stateData.bundleName,
73 .pid = stateData.pid,
74 .uid = stateData.uid
75 };
76 AddProcessToForegroundSet(stateData.pid, proc);
77 }
78
AddProcessToForegroundSet(const AppExecFwk::ProcessData & processData)79 void AppStateObserver::AddProcessToForegroundSet(const AppExecFwk::ProcessData &processData)
80 {
81 SecCompProcessData proc = {
82 .bundleName = processData.bundleName,
83 .pid = processData.pid,
84 .uid = processData.uid
85 };
86 AddProcessToForegroundSet(processData.pid, proc);
87 }
88
RemoveProcessFromForegroundSet(int32_t pid)89 void AppStateObserver::RemoveProcessFromForegroundSet(int32_t pid)
90 {
91 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
92 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
93 if (pid == iter->pid) {
94 foregrandProcList_.erase(iter);
95 return;
96 }
97 }
98 }
99
OnProcessStateChanged(const AppExecFwk::ProcessData & processData)100 void AppStateObserver::OnProcessStateChanged(const AppExecFwk::ProcessData &processData)
101 {
102 if (processData.state == AppExecFwk::AppProcessState::APP_STATE_FOREGROUND) {
103 AddProcessToForegroundSet(processData);
104 SecCompManager::GetInstance().NotifyProcessForeground(processData.pid);
105 } else if (processData.state == AppExecFwk::AppProcessState::APP_STATE_BACKGROUND) {
106 RemoveProcessFromForegroundSet(processData.pid);
107 SecCompManager::GetInstance().NotifyProcessBackground(processData.pid);
108 }
109 }
110
OnProcessDied(const AppExecFwk::ProcessData & processData)111 void AppStateObserver::OnProcessDied(const AppExecFwk::ProcessData& processData)
112 {
113 SC_LOG_INFO(LABEL, "OnProcessDied die %{public}s pid %{public}d",
114 processData.bundleName.c_str(), processData.pid);
115 RemoveProcessFromForegroundSet(processData.pid);
116 SecCompManager::GetInstance().NotifyProcessDied(processData.pid, false);
117 }
118
OnAppCacheStateChanged(const AppExecFwk::AppStateData & appStateData)119 void AppStateObserver::OnAppCacheStateChanged(const AppExecFwk::AppStateData &appStateData)
120 {
121 SC_LOG_INFO(LABEL, "OnAppCacheStateChanged pid %{public}d",
122 appStateData.pid);
123 if (appStateData.state != APP_STATE_CACHED) {
124 return;
125 }
126 RemoveProcessFromForegroundSet(appStateData.pid);
127 SecCompManager::GetInstance().NotifyProcessDied(appStateData.pid, true);
128 }
129
DumpProcess(std::string & dumpStr)130 void AppStateObserver::DumpProcess(std::string& dumpStr)
131 {
132 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
133 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
134 dumpStr.append("uid:" + std::to_string(iter->uid) + ", pid:" + std::to_string(iter->pid));
135 dumpStr.append(", procName:" + iter->bundleName + "\n");
136 }
137 }
138 } // namespace SecurityComponent
139 } // namespace Security
140 } // namespace OHOS
141
142