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 SLOGI(" add for uid=%{public}d ", uid);
92 }
93
RemoveObservedApp(int32_t uid)94 void AppManagerAdapter::RemoveObservedApp(int32_t uid)
95 {
96 std::lock_guard lockGuard(uidLock_);
97 observedAppUIDs_.erase(uid);
98 SLOGI(" remove for uid=%{public}d ", uid);
99 }
100
HandleAppStateChanged(const AppProcessData & appProcessData)101 void AppManagerAdapter::HandleAppStateChanged(const AppProcessData& appProcessData)
102 {
103 if (appProcessData.appState == ApplicationState::APP_STATE_TERMINATED) {
104 for (const auto& appData : appProcessData.appDatas) {
105 RemoveObservedApp(appData.uid);
106 }
107 }
108
109 if (appProcessData.appState != ApplicationState::APP_STATE_BACKGROUND) {
110 return;
111 }
112
113 std::set<int32_t> backgroundUIDs;
114 {
115 std::lock_guard lockGuard(uidLock_);
116 for (const auto& appData : appProcessData.appDatas) {
117 SLOGI("bundleName=%{public}s uid=%{public}d state=%{public}d",
118 appData.appName.c_str(), appData.uid, appProcessData.appState);
119 auto it = observedAppUIDs_.find(appData.uid);
120 if (it != observedAppUIDs_.end()) {
121 backgroundUIDs.insert(appData.uid);
122 }
123 }
124 }
125
126 if (backgroundObserver_) {
127 for (const auto uid : backgroundUIDs) {
128 backgroundObserver_(uid);
129 }
130 }
131 }
132
OnAppStateChanged(const AppExecFwk::AppProcessData & appProcessData)133 void AVSessionAppStateCallback::OnAppStateChanged(const AppExecFwk::AppProcessData& appProcessData)
134 {
135 AppManagerAdapter::GetInstance().HandleAppStateChanged(appProcessData);
136 }
137 }