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
16 #include "app_state_observer.h"
17
18 #include "app_mgr_constants.h"
19 #include "iservice_registry.h"
20 #include "ability_manager_client.h"
21 #include "system_ability_definition.h"
22 #include "loghelper.h"
23
24 namespace OHOS {
25 namespace NFC {
26 TAG::TagSession *tagSession_ = nullptr;
AppStateObserver(TAG::TagSession * tagSession)27 AppStateObserver::AppStateObserver(TAG::TagSession *tagSession)
28 {
29 tagSession_ = tagSession;
30 SubscribeAppState();
31 if (appStateAwareObserver_) {
32 appStateAwareObserver_->foregroundAppBundleName_ = GetForegroundApp();
33 }
34 }
35
~AppStateObserver()36 AppStateObserver::~AppStateObserver()
37 {
38 UnSubscribeAppState();
39 }
40
SubscribeAppState()41 bool AppStateObserver::SubscribeAppState()
42 {
43 InfoLog("SubscribeAppState start");
44 std::lock_guard<std::mutex> lock(mutex_);
45 if (appStateAwareObserver_) {
46 ErrorLog("SubscribeAppState: appStateAwareObserver_ has register");
47 return false;
48 }
49 if (!Connect()) {
50 return false;
51 }
52 appStateAwareObserver_ = new (std::nothrow)AppStateAwareObserver();
53 auto err = appMgrProxy_->RegisterApplicationStateObserver(appStateAwareObserver_);
54 if (err != 0) {
55 ErrorLog("SubscribeAppState error, code = %{public}d", err);
56 appStateAwareObserver_ = nullptr;
57 return false;
58 }
59 InfoLog("SubscribeAppState end");
60 return true;
61 }
62
UnSubscribeAppState()63 bool AppStateObserver::UnSubscribeAppState()
64 {
65 InfoLog("UnSubscribeAppState start");
66 std::lock_guard<std::mutex> lock(mutex_);
67 if (!appStateAwareObserver_) {
68 ErrorLog("UnSubscribeAppState: appStateAwareObserver_ is nullptr");
69 return false;
70 }
71 if (appMgrProxy_) {
72 appMgrProxy_->UnregisterApplicationStateObserver(appStateAwareObserver_);
73 appMgrProxy_ = nullptr;
74 appStateAwareObserver_ = nullptr;
75 }
76 InfoLog("UnSubscribeAppState end");
77 return true;
78 }
79
Connect()80 bool AppStateObserver::Connect()
81 {
82 if (appMgrProxy_ != nullptr) {
83 InfoLog("already connect");
84 return true;
85 }
86
87 sptr<ISystemAbilityManager> systemAbilityManager =
88 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
89 if (systemAbilityManager == nullptr) {
90 ErrorLog("get SystemAbilityManager failed");
91 return false;
92 }
93
94 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
95 if (remoteObject == nullptr) {
96 ErrorLog("get App Manager Service failed");
97 return false;
98 }
99
100 appMgrProxy_ = iface_cast<AppExecFwk::IAppMgr>(remoteObject);
101 if (!appMgrProxy_ || !appMgrProxy_->AsObject()) {
102 ErrorLog("get app mgr proxy failed!");
103 return false;
104 }
105 return true;
106 }
107
GetForegroundApp()108 std::string AppStateObserver::GetForegroundApp()
109 {
110 if (!Connect()) {
111 return "";
112 }
113 std::vector<AppExecFwk::AppStateData> fgAppList;
114 appMgrProxy_->GetForegroundApplications(fgAppList);
115 if (fgAppList.size() > 0) {
116 InfoLog("fgApp: %{public}s, state = %{public}d", fgAppList[0].bundleName.c_str(), fgAppList[0].state);
117 return fgAppList[0].bundleName;
118 }
119 return "";
120 }
121
OnAbilityStateChanged(const AppExecFwk::AbilityStateData & abilityStateData)122 void AppStateObserver::AppStateAwareObserver::OnAbilityStateChanged(
123 const AppExecFwk::AbilityStateData &abilityStateData)
124 {
125 if (tagSession_->GetFgDataVecSize() == 0 && tagSession_->GetReaderDataVecSize() == 0) {
126 return;
127 }
128 tagSession_->HandleAppStateChanged(abilityStateData.bundleName, abilityStateData.abilityName,
129 abilityStateData.abilityState);
130 }
131
OnForegroundApplicationChanged(const AppExecFwk::AppStateData & appStateData)132 void AppStateObserver::AppStateAwareObserver::OnForegroundApplicationChanged(
133 const AppExecFwk::AppStateData &appStateData)
134 {
135 if (!ValidateAppStateData(appStateData)) {
136 ErrorLog("OnForegroundApplicationChanged, validate app state data failed");
137 return;
138 }
139 InfoLog("OnForegroundApplicationChanged, name = %{public}s, state = %{public}d",
140 appStateData.bundleName.c_str(), appStateData.state);
141 if (appStateData.state == static_cast<int32_t>(AppExecFwk::ApplicationState::APP_STATE_FOREGROUND)) {
142 foregroundAppBundleName_ = appStateData.bundleName;
143 } else if (appStateData.state == static_cast<int32_t>(AppExecFwk::ApplicationState::APP_STATE_BACKGROUND) &&
144 foregroundAppBundleName_ == appStateData.bundleName) {
145 foregroundAppBundleName_ = "";
146 }
147 }
148
OnProcessDied(const AppExecFwk::ProcessData & processData)149 void AppStateObserver::AppStateAwareObserver::OnProcessDied(const AppExecFwk::ProcessData &processData)
150 {
151 // The process died on the foreground, can not update foregroundAppBundleName_ by OnForegroundApplicationChanged
152 if (foregroundAppBundleName_ == processData.bundleName) {
153 foregroundAppBundleName_ = "";
154 }
155 }
156
ValidateAppStateData(const AppExecFwk::AppStateData & appStateData)157 inline bool AppStateObserver::AppStateAwareObserver::ValidateAppStateData(const AppExecFwk::AppStateData &appStateData)
158 {
159 return appStateData.uid > 0 && appStateData.bundleName.length() > 0;
160 }
161
IsForegroundApp(const std::string & bundleName)162 bool AppStateObserver::IsForegroundApp(const std::string &bundleName)
163 {
164 if (!appStateAwareObserver_) {
165 SubscribeAppState();
166 if (!appStateAwareObserver_) {
167 ErrorLog("IsForegroundApp: appStateAwareObserver_ is nullptr");
168 return false;
169 }
170 }
171 InfoLog("IsForegroundApp: foreground app: %{public}s", appStateAwareObserver_->foregroundAppBundleName_.c_str());
172 return bundleName == appStateAwareObserver_->foregroundAppBundleName_;
173 }
174 } // namespace NFC
175 } // namespace OHOS