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
24namespace OHOS {
25namespace NFC {
26std::mutex mutex_ {};
27sptr<AppExecFwk::IAppMgr> appMgrProxy_ {nullptr};
28sptr<AppMgrDeathRecipient> appMgrDeathRecipient_(new (std::nothrow) AppMgrDeathRecipient());
29
30void AppMgrDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr<IRemoteObject> &remote)
31{
32    ErrorLog("On AppMgr died");
33    std::lock_guard<std::mutex> guard(mutex_);
34    appMgrProxy_ = nullptr;
35};
36
37AppStateObserver::AppStateObserver(INfcAppStateObserver *nfcAppStateChangeCallback)
38{
39    SubscribeAppState();
40    RegisterAppStateChangeCallback(nfcAppStateChangeCallback);
41}
42
43AppStateObserver::~AppStateObserver()
44{
45    UnSubscribeAppState();
46}
47
48bool AppStateObserver::SubscribeAppState()
49{
50    std::lock_guard<std::mutex> lock(mutex_);
51    if (appStateAwareObserver_) {
52        ErrorLog("SubscribeAppState: appStateAwareObserver_ has register");
53        return false;
54    }
55    if (!Connect()) {
56        return false;
57    }
58    appStateAwareObserver_ = new (std::nothrow)AppStateAwareObserver();
59    auto err = appMgrProxy_->RegisterApplicationStateObserver(appStateAwareObserver_);
60    if (err != 0) {
61        ErrorLog("SubscribeAppState error, code = %{public}d", err);
62        appStateAwareObserver_ = nullptr;
63        return false;
64    }
65    DebugLog("SubscribeAppState success");
66    return true;
67}
68
69bool AppStateObserver::UnSubscribeAppState()
70{
71    InfoLog("UnSubscribeAppState start");
72    std::lock_guard<std::mutex> lock(mutex_);
73    if (!appStateAwareObserver_) {
74        ErrorLog("UnSubscribeAppState: appStateAwareObserver_ is nullptr");
75        return false;
76    }
77    if (appMgrProxy_) {
78        appMgrProxy_->UnregisterApplicationStateObserver(appStateAwareObserver_);
79        appMgrProxy_ = nullptr;
80        appStateAwareObserver_ = nullptr;
81    }
82    InfoLog("UnSubscribeAppState end");
83    return true;
84}
85
86bool AppStateObserver::Connect()
87{
88    if (appMgrProxy_ != nullptr) {
89        InfoLog("already connect");
90        return true;
91    }
92
93    sptr<ISystemAbilityManager> systemAbilityManager =
94        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
95    if (systemAbilityManager == nullptr) {
96        ErrorLog("get SystemAbilityManager failed");
97        return false;
98    }
99
100    sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
101    if (remoteObject == nullptr) {
102        ErrorLog("get App Manager Service failed");
103        return false;
104    }
105
106    appMgrProxy_ = iface_cast<AppExecFwk::IAppMgr>(remoteObject);
107    if (!appMgrProxy_ || !appMgrProxy_->AsObject()) {
108        ErrorLog("get app mgr proxy failed!");
109        return false;
110    }
111    appMgrProxy_->AsObject()->AddDeathRecipient(appMgrDeathRecipient_);
112    return true;
113}
114
115bool AppStateObserver::RegisterAppStateChangeCallback(INfcAppStateObserver *nfcAppStateChangeCallback)
116{
117    if (!appStateAwareObserver_) {
118        ErrorLog("UnSubscribeAppState: appStateAwareObserver_ is nullptr");
119        return false;
120    }
121    if (nfcAppStateChangeCallback == nullptr) {
122        ErrorLog("nfcAppStateChangeCallback_ is nullptr");
123        return false;
124    }
125    return appStateAwareObserver_->RegisterAppStateChangeCallback(nfcAppStateChangeCallback);
126}
127
128void AppStateObserver::AppStateAwareObserver::OnAbilityStateChanged(
129    const AppExecFwk::AbilityStateData &abilityStateData)
130{
131    if (nfcAppStateChangeCallback_ == nullptr) {
132        ErrorLog("nfcAppStateChangeCallback_ is nullptr");
133        return;
134    }
135    nfcAppStateChangeCallback_->HandleAppStateChanged(abilityStateData.bundleName, abilityStateData.abilityName,
136        abilityStateData.abilityState);
137}
138
139void AppStateObserver::AppStateAwareObserver::OnForegroundApplicationChanged(
140    const AppExecFwk::AppStateData &appStateData)
141{
142}
143
144bool AppStateObserver::AppStateAwareObserver::RegisterAppStateChangeCallback(
145    INfcAppStateObserver *nfcAppStateChangeCallback)
146{
147    if (nfcAppStateChangeCallback == nullptr) {
148        ErrorLog("nfcAppStateChangeCallback_ is nullptr");
149        return false;
150    }
151    nfcAppStateChangeCallback_ = nfcAppStateChangeCallback;
152    return true;
153}
154
155void AppStateObserver::AppStateAwareObserver::OnProcessDied(const AppExecFwk::ProcessData &processData)
156{
157}
158
159bool AppStateObserver::IsForegroundApp(const std::string &bundleName)
160{
161    std::lock_guard<std::mutex> lock(mutex_);
162    if (!Connect()) {
163        ErrorLog("IsForegroundApp connect failed");
164        return false;
165    }
166    std::vector<AppExecFwk::AppStateData> appList;
167    appMgrProxy_->GetForegroundApplications(appList);
168    for (AppExecFwk::AppStateData appData : appList) {
169        if (bundleName.compare(appData.bundleName) == 0) {
170            InfoLog("IsForegroundApp: %{public}s is foreground", bundleName.c_str());
171            return true;
172        }
173    }
174    ErrorLog("IsForegroundApp: %{public}s is not foreground", bundleName.c_str());
175    return false;
176}
177} // namespace NFC
178} // namespace OHOS