• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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