1 /*
2 * Copyright (c) 2025 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 #ifndef LOG_TAG
17 #define LOG_TAG "AudioServiceAppStateListener"
18 #endif
19
20 #include <map>
21
22 #include "audio_common_log.h"
23 #include "app_state_listener.h"
24 #include "dfx_msg_manager.h"
25 #include "audio_utils.h"
26 #include "system_ability_definition.h"
27 #include "bundle_mgr_interface.h"
28 #include "bundle_mgr_proxy.h"
29 #include "iservice_registry.h"
30
31
32 namespace OHOS {
33 namespace AudioStandard {
34
35 static const std::map<AppExecFwk::ApplicationState, DfxAppState> DFX_APPSTATE_MAP = {
36 {AppExecFwk::ApplicationState::APP_STATE_CREATE, DFX_APP_STATE_START},
37 {AppExecFwk::ApplicationState::APP_STATE_FOREGROUND, DFX_APP_STATE_FOREGROUND},
38 {AppExecFwk::ApplicationState::APP_STATE_BACKGROUND, DFX_APP_STATE_BACKGROUND},
39 {AppExecFwk::ApplicationState::APP_STATE_END, DFX_APP_STATE_END},
40 {AppExecFwk::ApplicationState::APP_STATE_TERMINATED, DFX_APP_STATE_END}
41 };
42
AppStateListener()43 AppStateListener::AppStateListener()
44 {
45 AUDIO_INFO_LOG("enter");
46 }
47
OnAppStateChanged(const AppExecFwk::AppProcessData & appProcessData)48 void AppStateListener::OnAppStateChanged(const AppExecFwk::AppProcessData& appProcessData)
49 {
50 for (const auto& appData : appProcessData.appDatas) {
51 AUDIO_INFO_LOG("app state changed, bundleName=%{public}s uid=%{public}d pid=%{public}d state=%{public}d",
52 appData.appName.c_str(), appData.uid, appProcessData.pid, appProcessData.appState);
53 HandleAppStateChange(appProcessData.pid, appData.uid, static_cast<int32_t>(appProcessData.appState));
54 }
55 }
56
GetBundleInfoFromUid(int32_t callingUid)57 AppExecFwk::BundleInfo AppStateListener::GetBundleInfoFromUid(int32_t callingUid)
58 {
59 AudioXCollie audioXCollie("AudioPolicyServer::PerStateChangeCbCustomizeCallback::getUidByBundleName",
60 GET_BUNDLE_TIME_OUT_SECONDS);
61 std::string bundleName {"uid:" + std::to_string(callingUid)};
62 AppExecFwk::BundleInfo bundleInfo;
63 WatchTimeout guard("SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager():GetBundleInfoFromUid");
64 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
65 CHECK_AND_RETURN_RET_LOG(systemAbilityManager != nullptr, bundleInfo, "systemAbilityManager is nullptr");
66 guard.CheckCurrTimeout();
67
68 sptr<IRemoteObject> remoteObject = systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
69 CHECK_AND_RETURN_RET_PRELOG(remoteObject != nullptr, bundleInfo, "remoteObject is nullptr");
70
71 sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
72 CHECK_AND_RETURN_RET_LOG(bundleMgrProxy != nullptr, bundleInfo, "bundleMgrProxy is nullptr");
73
74 WatchTimeout reguard("bundleMgrProxy->GetNameForUid:GetBundleInfoFromUid");
75 bundleMgrProxy->GetNameForUid(callingUid, bundleName);
76
77 bundleMgrProxy->GetBundleInfoV9(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT |
78 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES |
79 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION |
80 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO |
81 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_HASH_VALUE,
82 bundleInfo,
83 AppExecFwk::Constants::ALL_USERID);
84 reguard.CheckCurrTimeout();
85
86 return bundleInfo;
87 }
88
89
HandleAppStateChange(int32_t pid,int32_t uid,int32_t state)90 void AppStateListener::HandleAppStateChange(int32_t pid, int32_t uid, int32_t state)
91 {
92 auto pos = DFX_APPSTATE_MAP.find(static_cast<AppExecFwk::ApplicationState>(state));
93 auto appState = (pos == DFX_APPSTATE_MAP.end()) ? DFX_APP_STATE_UNKNOWN : pos->second;
94 CHECK_AND_RETURN_LOG(pos != DFX_APPSTATE_MAP.end(), "invalid app state%{public}d", state);
95
96 AUDIO_INFO_LOG("app state changed, pid=%{public}d state=%{public}d", pid, state);
97 auto &manager = DfxMsgManager::GetInstance();
98 if (appState == DFX_APP_STATE_START) {
99 if (manager.CheckCanAddAppInfo(uid)) {
100 auto info = GetBundleInfoFromUid(uid);
101 manager.SaveAppInfo({uid, info.name, info.versionName});
102 }
103 manager.UpdateAppState(uid, appState, true);
104 } else {
105 manager.UpdateAppState(uid, appState);
106 }
107 }
108 }
109 }
110