1 /*
2 * Copyright (c) 2022 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
16 #include <thread>
17 #include <chrono>
18
19 #include "avsession_log.h"
20 #include "app_mgr_constants.h"
21 #include "app_manager_adapter.h"
22
23 namespace OHOS::AVSession {
24 using AppExecFwk::AppProcessData;
25 using AppExecFwk::AppProcessState;
26 using AppExecFwk::AppMgrResultCode;
27 using AppExecFwk::RunningProcessInfo;
28 using AppExecFwk::ApplicationState;
29
AppManagerAdapter()30 AppManagerAdapter::AppManagerAdapter()
31 {
32 SLOGI("construct");
33 }
34
~AppManagerAdapter()35 AppManagerAdapter::~AppManagerAdapter()
36 {
37 SLOGI("destroy");
38 }
39
GetInstance()40 AppManagerAdapter& AppManagerAdapter::GetInstance()
41 {
42 static AppManagerAdapter appManagerAdapter;
43 return appManagerAdapter;
44 }
45
Init()46 void AppManagerAdapter::Init()
47 {
48 appStateCallback_ = new(std::nothrow) AVSessionAppStateCallback();
49 if (appStateCallback_ == nullptr) {
50 SLOGE("no memory");
51 return;
52 }
53 int retryCount = 0;
54 while (retryCount < RETRY_COUNT_MAX) {
55 if (appManager_.RegisterAppStateCallback(appStateCallback_) != AppMgrResultCode::RESULT_OK) {
56 SLOGE("register app state callback failed");
57 retryCount++;
58 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL_TIME));
59 continue;
60 }
61 break;
62 }
63 }
64
IsAppBackground(int32_t uid)65 bool AppManagerAdapter::IsAppBackground(int32_t uid)
66 {
67 std::vector<RunningProcessInfo> infos;
68 if (appManager_.GetAllRunningProcesses(infos) != AppMgrResultCode::RESULT_OK) {
69 SLOGE("get all running processes info failed");
70 return false;
71 }
72 for (const auto& info : infos) {
73 if (info.uid_ == uid && info.state_ == AppProcessState::APP_STATE_BACKGROUND) {
74 SLOGI("uid=%{public}d is background", uid);
75 return true;
76 }
77 }
78 SLOGI("uid=%{public}d is not background", uid);
79 return false;
80 }
81
SetAppBackgroundStateObserver(const std::function<void (int32_t)> & observer)82 void AppManagerAdapter::SetAppBackgroundStateObserver(const std::function<void(int32_t)>& observer)
83 {
84 backgroundObserver_ = observer;
85 }
86
AddObservedApp(int32_t uid)87 void AppManagerAdapter::AddObservedApp(int32_t uid)
88 {
89 std::lock_guard lockGuard(uidLock_);
90 observedAppUIDs_.insert(uid);
91 }
92
RemoveObservedApp(int32_t uid)93 void AppManagerAdapter::RemoveObservedApp(int32_t uid)
94 {
95 std::lock_guard lockGuard(uidLock_);
96 observedAppUIDs_.erase(uid);
97 }
98
HandleAppStateChanged(const AppProcessData & appProcessData)99 void AppManagerAdapter::HandleAppStateChanged(const AppProcessData& appProcessData)
100 {
101 if (appProcessData.appState == ApplicationState::APP_STATE_TERMINATED) {
102 for (const auto& appData : appProcessData.appDatas) {
103 RemoveObservedApp(appData.uid);
104 }
105 }
106
107 if (appProcessData.appState != ApplicationState::APP_STATE_BACKGROUND) {
108 return;
109 }
110
111 std::set<int32_t> backgroundUIDs;
112 {
113 std::lock_guard lockGuard(uidLock_);
114 for (const auto& appData : appProcessData.appDatas) {
115 SLOGI("bundleName=%{public}s uid=%{public}d state=%{public}d",
116 appData.appName.c_str(), appData.uid, appProcessData.appState);
117 auto it = observedAppUIDs_.find(appData.uid);
118 if (it != observedAppUIDs_.end()) {
119 backgroundUIDs.insert(appData.uid);
120 }
121 }
122 }
123
124 if (backgroundObserver_) {
125 for (const auto uid : backgroundUIDs) {
126 backgroundObserver_(uid);
127 }
128 }
129 }
130
OnAppStateChanged(const AppExecFwk::AppProcessData & appProcessData)131 void AVSessionAppStateCallback::OnAppStateChanged(const AppExecFwk::AppProcessData& appProcessData)
132 {
133 AppManagerAdapter::GetInstance().HandleAppStateChanged(appProcessData);
134 }
135 }