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 "ability_manager_adapter.h"
17
18#include "avsession_dynamic_loader.h"
19#include "avsession_errors.h"
20#include "avsession_log.h"
21#include "bundle_status_adapter.h"
22#include "ability_connect_helper.h"
23
24namespace OHOS::AVSession {
25static const std::string AVSESSION_DYNAMIC_INSIGHT_LIBRARY_PATH = std::string("libavsession_dynamic_insight.z.so");
26
27AbilityManagerAdapter::AbilityManagerAdapter(const std::string& bundleName, const std::string& abilityName)
28{
29    SLOGI("construct bundleName=%{public}s abilityName=%{public}s", bundleName.c_str(), abilityName.c_str());
30    bundleName_ = bundleName;
31    abilityName_ = abilityName;
32}
33
34AbilityManagerAdapter::~AbilityManagerAdapter()
35{}
36
37__attribute__((no_sanitize("cfi"))) int32_t AbilityManagerAdapter::StartAbilityByCall(std::string& sessionId)
38{
39    if (status_.load() != Status::ABILITY_STATUS_INIT) {
40        SLOGE("Start Ability is running");
41        return ERR_START_ABILITY_IS_RUNNING;
42    }
43    status_.store(Status::ABILITY_STATUS_RUNNING);
44    int32_t ret = AVSESSION_ERROR;
45    bool isSupport = false;
46
47    std::unique_ptr<AVSessionDynamicLoader> dynamicLoader = std::make_unique<AVSessionDynamicLoader>();
48    typedef bool (*IsSupportPlayIntentFunc)(const std::string& bundleName, const std::string& assetId);
49    IsSupportPlayIntentFunc isSupportPlayIntent =
50        reinterpret_cast<IsSupportPlayIntentFunc>(dynamicLoader->GetFuntion(
51            AVSESSION_DYNAMIC_INSIGHT_LIBRARY_PATH, "IsSupportPlayIntent"));
52    if (isSupportPlayIntent) {
53        isSupport = (*isSupportPlayIntent)(bundleName_, "");
54    }
55
56    if (isSupport) {
57        SLOGI("Start Ability mediaintent");
58        typedef int32_t (*StartAVPlaybackFunc)(const std::string& bundleName, const std::string& assetId);
59        StartAVPlaybackFunc startAVPlayback =
60            reinterpret_cast<StartAVPlaybackFunc>(dynamicLoader->GetFuntion(
61                AVSESSION_DYNAMIC_INSIGHT_LIBRARY_PATH, "StartAVPlayback"));
62        if (startAVPlayback) {
63            ret = (*startAVPlayback)(bundleName_, "");
64        }
65    } else {
66        ret = AbilityConnectHelper::GetInstance().StartAbilityByCall(bundleName_, abilityName_);
67    }
68    if (ret != AVSESSION_SUCCESS) {
69        SLOGE("Start Ability failed: %{public}d", ret);
70        status_.store(Status::ABILITY_STATUS_INIT);
71        return ret;
72    }
73
74    WaitForTimeout(ABILITY_START_TIMEOUT_MS);
75    ret = ERR_START_ABILITY_TIMEOUT;
76    if (status_.load() == Status::ABILITY_STATUS_SUCCESS) {
77        ret = AVSESSION_SUCCESS;
78        sessionId = sessionId_;
79    }
80    status_.store(Status::ABILITY_STATUS_INIT);
81    return ret;
82}
83
84void AbilityManagerAdapter::StartAbilityByCallDone(const std::string& sessionId)
85{
86    if (status_.load() != Status::ABILITY_STATUS_RUNNING) {
87        SLOGI("no need to notify");
88        return;
89    }
90    sessionId_ = sessionId;
91    syncCon_.notify_one();
92}
93
94// LCOV_EXCL_START
95void AbilityManagerAdapter::WaitForTimeout(uint32_t timeout)
96{
97    std::unique_lock<std::mutex> lock(syncMutex_);
98    auto waitStatus = syncCon_.wait_for(lock, std::chrono::milliseconds(timeout));
99    if (waitStatus == std::cv_status::timeout) {
100        SLOGE("StartAbilityByCall timeout");
101        status_.store(Status::ABILITY_STATUS_FAILED);
102        return;
103    }
104    status_.store(Status::ABILITY_STATUS_SUCCESS);
105}
106// LCOV_EXCL_STOP
107} // namespace OHOS::AVSession
108