180922886Sopenharmony_ci/*
280922886Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
380922886Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
480922886Sopenharmony_ci * you may not use this file except in compliance with the License.
580922886Sopenharmony_ci * You may obtain a copy of the License at
680922886Sopenharmony_ci *
780922886Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
880922886Sopenharmony_ci *
980922886Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1080922886Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1180922886Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1280922886Sopenharmony_ci * See the License for the specific language governing permissions and
1380922886Sopenharmony_ci * limitations under the License.
1480922886Sopenharmony_ci */
1580922886Sopenharmony_ci
1680922886Sopenharmony_ci#include "bundle_status_adapter.h"
1780922886Sopenharmony_ci
1880922886Sopenharmony_ci#include "avsession_log.h"
1980922886Sopenharmony_ci#include "iservice_registry.h"
2080922886Sopenharmony_ci#include "system_ability_definition.h"
2180922886Sopenharmony_ci#include "want.h"
2280922886Sopenharmony_ci#include "want_params_wrapper.h"
2380922886Sopenharmony_ci#include "string_wrapper.h"
2480922886Sopenharmony_ci#include "array_wrapper.h"
2580922886Sopenharmony_ci
2680922886Sopenharmony_cinamespace OHOS::AVSession {
2780922886Sopenharmony_ciBundleStatusAdapter::BundleStatusAdapter()
2880922886Sopenharmony_ci{
2980922886Sopenharmony_ci    SLOGI("construct");
3080922886Sopenharmony_ci}
3180922886Sopenharmony_ci
3280922886Sopenharmony_ciBundleStatusAdapter::~BundleStatusAdapter()
3380922886Sopenharmony_ci{
3480922886Sopenharmony_ci    SLOGI("destroy");
3580922886Sopenharmony_ci}
3680922886Sopenharmony_ci
3780922886Sopenharmony_ciBundleStatusAdapter& BundleStatusAdapter::GetInstance()
3880922886Sopenharmony_ci{
3980922886Sopenharmony_ci    static BundleStatusAdapter bundleStatusAdapter;
4080922886Sopenharmony_ci    return bundleStatusAdapter;
4180922886Sopenharmony_ci}
4280922886Sopenharmony_ci
4380922886Sopenharmony_civoid BundleStatusAdapter::Init()
4480922886Sopenharmony_ci{
4580922886Sopenharmony_ci    auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
4680922886Sopenharmony_ci    if (!systemAbilityManager) {
4780922886Sopenharmony_ci        SLOGI("fail to get system ability mgr");
4880922886Sopenharmony_ci        return;
4980922886Sopenharmony_ci    }
5080922886Sopenharmony_ci
5180922886Sopenharmony_ci    auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
5280922886Sopenharmony_ci    if (!remoteObject) {
5380922886Sopenharmony_ci        SLOGI("fail to get bundle manager proxy");
5480922886Sopenharmony_ci        return;
5580922886Sopenharmony_ci    }
5680922886Sopenharmony_ci
5780922886Sopenharmony_ci    std::lock_guard bundleMgrProxyLockGuard(bundleMgrProxyLock_);
5880922886Sopenharmony_ci    SLOGI("get bundle manager proxy success");
5980922886Sopenharmony_ci    bundleMgrProxy = iface_cast<AppExecFwk::BundleMgrProxy>(remoteObject);
6080922886Sopenharmony_ci}
6180922886Sopenharmony_ci
6280922886Sopenharmony_cibool BundleStatusAdapter::SubscribeBundleStatusEvent(const std::string bundleName,
6380922886Sopenharmony_ci    const std::function<void(const std::string, const int32_t userId)>& callback, int32_t userId)
6480922886Sopenharmony_ci{
6580922886Sopenharmony_ci    SLOGI("Bundle status adapter subscribe bundle status event, bundleName=%{public}s, userId=%{public}d",
6680922886Sopenharmony_ci        bundleName.c_str(), userId);
6780922886Sopenharmony_ci    auto bundleStatusListener = bundleStatusListeners_.find(std::make_pair(bundleName, userId));
6880922886Sopenharmony_ci    if (bundleStatusListener != bundleStatusListeners_.end()) {
6980922886Sopenharmony_ci        SLOGE("bundle status has already register");
7080922886Sopenharmony_ci        return false;
7180922886Sopenharmony_ci    }
7280922886Sopenharmony_ci    auto bundleStatusCallback = [this](std::string bundleName, int32_t userId) {
7380922886Sopenharmony_ci        NotifyBundleRemoved(bundleName, userId);
7480922886Sopenharmony_ci    };
7580922886Sopenharmony_ci    sptr<BundleStatusCallbackImpl> bundleStatusCallbackImpl =
7680922886Sopenharmony_ci            new(std::nothrow) BundleStatusCallbackImpl(bundleStatusCallback, userId);
7780922886Sopenharmony_ci    if (bundleStatusCallbackImpl == nullptr) {
7880922886Sopenharmony_ci        SLOGE("no memory");
7980922886Sopenharmony_ci        return false;
8080922886Sopenharmony_ci    }
8180922886Sopenharmony_ci    std::lock_guard bundleMgrProxyLockGuard(bundleMgrProxyLock_);
8280922886Sopenharmony_ci    if (bundleMgrProxy == nullptr) {
8380922886Sopenharmony_ci        SLOGE("SubscribeBundleStatusEvent with proxy null!");
8480922886Sopenharmony_ci        Init();
8580922886Sopenharmony_ci        if (bundleMgrProxy == nullptr) {
8680922886Sopenharmony_ci            SLOGE("SubscribeBundleStatusEvent with proxy null after init!");
8780922886Sopenharmony_ci            return false;
8880922886Sopenharmony_ci        }
8980922886Sopenharmony_ci    }
9080922886Sopenharmony_ci    bundleStatusCallbackImpl->SetBundleName(bundleName);
9180922886Sopenharmony_ci    bundleStatusCallbackImpl->SetUserId(userId);
9280922886Sopenharmony_ci    if (bundleMgrProxy->RegisterBundleStatusCallback(bundleStatusCallbackImpl)) {
9380922886Sopenharmony_ci        bundleStatusListeners_.insert(std::make_pair(std::make_pair(bundleName, userId), callback));
9480922886Sopenharmony_ci        return true;
9580922886Sopenharmony_ci    } else {
9680922886Sopenharmony_ci        SLOGE("Register bundle status callback failed, bundleName=%{public}s", bundleName.c_str());
9780922886Sopenharmony_ci        return false;
9880922886Sopenharmony_ci    }
9980922886Sopenharmony_ci}
10080922886Sopenharmony_ci
10180922886Sopenharmony_cibool BundleStatusAdapter::IsAudioPlayback(const std::string& bundleName, const std::string& abilityName)
10280922886Sopenharmony_ci{
10380922886Sopenharmony_ci    SLOGI("Estimate bundle audio playback status, bundleName=%{public}s", bundleName.c_str());
10480922886Sopenharmony_ci    AppExecFwk::AbilityInfo abilityInfo;
10580922886Sopenharmony_ci    bool flag = false;
10680922886Sopenharmony_ci    if (bundleMgrProxy->GetAbilityInfo(bundleName, abilityName, abilityInfo)) {
10780922886Sopenharmony_ci        flag = static_cast<int32_t>(abilityInfo.backgroundModes) == backgroundModeDemand ? true : false;
10880922886Sopenharmony_ci    }
10980922886Sopenharmony_ci    return flag;
11080922886Sopenharmony_ci}
11180922886Sopenharmony_ci
11280922886Sopenharmony_civoid BundleStatusAdapter::NotifyBundleRemoved(const std::string bundleName, const int32_t userId)
11380922886Sopenharmony_ci{
11480922886Sopenharmony_ci    auto bundleStatusListener = bundleStatusListeners_.find(std::make_pair(bundleName, userId));
11580922886Sopenharmony_ci    if (bundleStatusListener == bundleStatusListeners_.end()) {
11680922886Sopenharmony_ci        return;
11780922886Sopenharmony_ci    }
11880922886Sopenharmony_ci    bundleStatusListener->second(bundleName, userId);
11980922886Sopenharmony_ci    SLOGI("erase bundle status callback, bundleName=%{public}s, userId=%{public}d", bundleName.c_str(), userId);
12080922886Sopenharmony_ci    bundleStatusListeners_.erase(bundleStatusListener);
12180922886Sopenharmony_ci}
12280922886Sopenharmony_ci
12380922886Sopenharmony_cistd::string BundleStatusAdapter::GetBundleNameFromUid(const int32_t uid)
12480922886Sopenharmony_ci{
12580922886Sopenharmony_ci    std::string bundleName {""};
12680922886Sopenharmony_ci    if (bundleMgrProxy != nullptr) {
12780922886Sopenharmony_ci        bundleMgrProxy->GetNameForUid(uid, bundleName);
12880922886Sopenharmony_ci    }
12980922886Sopenharmony_ci    return bundleName;
13080922886Sopenharmony_ci}
13180922886Sopenharmony_ci
13280922886Sopenharmony_cibool BundleStatusAdapter::CheckBundleSupport(std::string& profile)
13380922886Sopenharmony_ci{
13480922886Sopenharmony_ci    nlohmann::json profileValues = nlohmann::json::parse(profile, nullptr, false);
13580922886Sopenharmony_ci    CHECK_AND_RETURN_RET_LOG(!profileValues.is_discarded(), false, "json object is null");
13680922886Sopenharmony_ci    CHECK_AND_RETURN_RET_LOG(profileValues.contains("insightIntents"), false, "json do not contains insightIntents");
13780922886Sopenharmony_ci    for (const auto& value : profileValues["insightIntents"]) {
13880922886Sopenharmony_ci        std::string insightName = value["intentName"];
13980922886Sopenharmony_ci        CHECK_AND_RETURN_RET_LOG(value.contains("uiAbility"), false, "json do not contains uiAbility");
14080922886Sopenharmony_ci        nlohmann::json abilityValue = value["uiAbility"];
14180922886Sopenharmony_ci        if (insightName != PLAY_MUSICLIST && insightName != PLAY_AUDIO) {
14280922886Sopenharmony_ci            continue;
14380922886Sopenharmony_ci        }
14480922886Sopenharmony_ci        if (abilityValue.is_discarded()) {
14580922886Sopenharmony_ci            SLOGE("uiability discarded=%{public}d", abilityValue.is_discarded());
14680922886Sopenharmony_ci            return false;
14780922886Sopenharmony_ci        }
14880922886Sopenharmony_ci        CHECK_AND_RETURN_RET_LOG(abilityValue.contains("executeMode"), false, "json do not contains executeMode");
14980922886Sopenharmony_ci        auto modeValues = abilityValue["executeMode"];
15080922886Sopenharmony_ci        if (modeValues.is_discarded()) {
15180922886Sopenharmony_ci            SLOGE("executeMode discarded=%{public}d", modeValues.is_discarded());
15280922886Sopenharmony_ci            return false;
15380922886Sopenharmony_ci        }
15480922886Sopenharmony_ci        auto mode = std::find(modeValues.begin(), modeValues.end(), "background");
15580922886Sopenharmony_ci        return (mode != modeValues.end());
15680922886Sopenharmony_ci    }
15780922886Sopenharmony_ci    return false;
15880922886Sopenharmony_ci}
15980922886Sopenharmony_ci
16080922886Sopenharmony_ci__attribute__((no_sanitize("cfi"))) bool BundleStatusAdapter::IsSupportPlayIntent(const std::string& bundleName,
16180922886Sopenharmony_ci    std::string& supportModule, std::string& profile)
16280922886Sopenharmony_ci{
16380922886Sopenharmony_ci    if (bundleMgrProxy == nullptr) {
16480922886Sopenharmony_ci        return false;
16580922886Sopenharmony_ci    }
16680922886Sopenharmony_ci    AppExecFwk::BundleInfo bundleInfo;
16780922886Sopenharmony_ci    if (!bundleMgrProxy->GetBundleInfo(bundleName, getBundleInfoWithHapModule, bundleInfo, startUserId)) {
16880922886Sopenharmony_ci        SLOGE("GetBundleInfo=%{public}s fail", bundleName.c_str());
16980922886Sopenharmony_ci        return false;
17080922886Sopenharmony_ci    }
17180922886Sopenharmony_ci    bool isSupportIntent = false;
17280922886Sopenharmony_ci    for (std::string module : bundleInfo.moduleNames) {
17380922886Sopenharmony_ci        auto ret = bundleMgrProxy->GetJsonProfile(AppExecFwk::ProfileType::INTENT_PROFILE, bundleName, module,
17480922886Sopenharmony_ci            profile, startUserId);
17580922886Sopenharmony_ci        if (ret == 0) {
17680922886Sopenharmony_ci            SLOGI("GetJsonProfile success, profile=%{public}s", profile.c_str());
17780922886Sopenharmony_ci            isSupportIntent = true;
17880922886Sopenharmony_ci            supportModule = module;
17980922886Sopenharmony_ci            break;
18080922886Sopenharmony_ci        }
18180922886Sopenharmony_ci    }
18280922886Sopenharmony_ci    if (!isSupportIntent) {
18380922886Sopenharmony_ci        SLOGE("Bundle=%{public}s does not support insight", bundleName.c_str());
18480922886Sopenharmony_ci        return false;
18580922886Sopenharmony_ci    }
18680922886Sopenharmony_ci    return CheckBundleSupport(profile);
18780922886Sopenharmony_ci}
18880922886Sopenharmony_ci
18980922886Sopenharmony_ciBundleStatusCallbackImpl::BundleStatusCallbackImpl(
19080922886Sopenharmony_ci    const std::function<void(const std::string, const int32_t userId)>& callback, int32_t userId)
19180922886Sopenharmony_ci{
19280922886Sopenharmony_ci    SLOGI("Create bundle status instance with userId %{public}d", userId);
19380922886Sopenharmony_ci    callback_ = callback;
19480922886Sopenharmony_ci    userId_ = userId;
19580922886Sopenharmony_ci}
19680922886Sopenharmony_ci
19780922886Sopenharmony_ciBundleStatusCallbackImpl::~BundleStatusCallbackImpl()
19880922886Sopenharmony_ci{
19980922886Sopenharmony_ci    SLOGI("Destroy bundle status instance");
20080922886Sopenharmony_ci}
20180922886Sopenharmony_ci
20280922886Sopenharmony_civoid BundleStatusCallbackImpl::OnBundleStateChanged(const uint8_t installType, const int32_t resultCode,
20380922886Sopenharmony_ci    const std::string &resultMsg, const std::string &bundleName)
20480922886Sopenharmony_ci{
20580922886Sopenharmony_ci    if (installType == static_cast<uint8_t>(AppExecFwk::InstallType::UNINSTALL_CALLBACK)) {
20680922886Sopenharmony_ci        callback_(bundleName, userId_);
20780922886Sopenharmony_ci    }
20880922886Sopenharmony_ci}
20980922886Sopenharmony_ci}
210