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 }
26
AppStateObserver()27 AppStateObserver::AppStateObserver()
28 {
29 }
30
~AppStateObserver()31 AppStateObserver::~AppStateObserver()
32 {
33 }
34
IsProcessForeground(int32_t pid,int32_t uid)35 bool AppStateObserver::IsProcessForeground(int32_t pid, int32_t uid)
36 {
37 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
38 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
39 if (pid == iter->pid) {
40 return true;
41 }
42
43 if ((iter->pid == -1) && (uid == iter->uid)) {
44 iter->pid = pid;
45 return true;
46 }
47 }
48 return false;
49 }
50
AddProcessToForegroundSet(int32_t pid,const SecCompProcessData & data)51 void AppStateObserver::AddProcessToForegroundSet(int32_t pid, const SecCompProcessData& data)
52 {
53 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
54 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
55 if (pid == -1) {
56 if (iter->uid == data.uid) {
57 SC_LOG_INFO(LABEL, "uid %{public}d is already in foreground", data.uid);
58 return;
59 }
60 } else if (pid == iter->pid) {
61 SC_LOG_INFO(LABEL, "pid %{public}d is already in foreground", pid);
62 return;
63 }
64 }
65 foregrandProcList_.emplace_back(data);
66 }
67
AddProcessToForegroundSet(const AppExecFwk::AppStateData & stateData)68 void AppStateObserver::AddProcessToForegroundSet(const AppExecFwk::AppStateData& stateData)
69 {
70 SecCompProcessData proc = {
71 .bundleName = stateData.bundleName,
72 .pid = stateData.pid,
73 .uid = stateData.uid
74 };
75 AddProcessToForegroundSet(stateData.pid, proc);
76 }
77
AddProcessToForegroundSet(const AppExecFwk::ProcessData & processData)78 void AppStateObserver::AddProcessToForegroundSet(const AppExecFwk::ProcessData &processData)
79 {
80 SecCompProcessData proc = {
81 .bundleName = processData.bundleName,
82 .pid = processData.pid,
83 .uid = processData.uid
84 };
85 AddProcessToForegroundSet(processData.pid, proc);
86 }
87
RemoveProcessFromForegroundSet(const AppExecFwk::ProcessData & processData)88 void AppStateObserver::RemoveProcessFromForegroundSet(const AppExecFwk::ProcessData &processData)
89 {
90 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
91 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
92 if (processData.pid == iter->pid) {
93 foregrandProcList_.erase(iter);
94 return;
95 }
96 }
97 }
98
OnProcessStateChanged(const AppExecFwk::ProcessData & processData)99 void AppStateObserver::OnProcessStateChanged(const AppExecFwk::ProcessData &processData)
100 {
101 if (processData.state == AppExecFwk::AppProcessState::APP_STATE_FOREGROUND) {
102 AddProcessToForegroundSet(processData);
103 SecCompManager::GetInstance().NotifyProcessForeground(processData.pid);
104 } else if (processData.state == AppExecFwk::AppProcessState::APP_STATE_BACKGROUND) {
105 RemoveProcessFromForegroundSet(processData);
106 SecCompManager::GetInstance().NotifyProcessBackground(processData.pid);
107 }
108 }
109
OnProcessDied(const AppExecFwk::ProcessData & processData)110 void AppStateObserver::OnProcessDied(const AppExecFwk::ProcessData& processData)
111 {
112 SC_LOG_INFO(LABEL, "OnProcessDied die %{public}s pid %{public}d",
113 processData.bundleName.c_str(), processData.pid);
114 RemoveProcessFromForegroundSet(processData);
115 SecCompManager::GetInstance().NotifyProcessDied(processData.pid);
116 }
117
DumpProcess(std::string & dumpStr)118 void AppStateObserver::DumpProcess(std::string& dumpStr)
119 {
120 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->fgProcLock_);
121 for (auto iter = foregrandProcList_.begin(); iter != foregrandProcList_.end(); ++iter) {
122 dumpStr.append("uid:" + std::to_string(iter->uid) + ", pid:" + std::to_string(iter->pid));
123 dumpStr.append(", procName:" + iter->bundleName + "\n");
124 }
125 }
126 } // namespace SecurityComponent
127 } // namespace Security
128 } // namespace OHOS
129
130