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 
24 namespace OHOS::AVSession {
25 static const std::string AVSESSION_DYNAMIC_INSIGHT_LIBRARY_PATH = std::string("libavsession_dynamic_insight.z.so");
26 
AbilityManagerAdapter(const std::string & bundleName,const std::string & abilityName)27 AbilityManagerAdapter::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 
~AbilityManagerAdapter()34 AbilityManagerAdapter::~AbilityManagerAdapter()
35 {}
36 
StartAbilityByCall(std::string & sessionId)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 
StartAbilityByCallDone(const std::string & sessionId)84 void 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
WaitForTimeout(uint32_t timeout)95 void 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