1 /*
2 * Copyright (c) 2024 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_interface.h"
17 #include "ability_manager_client.h"
18 #include "bundle_mgr_proxy.h"
19 #include "iremote_stub.h"
20 #include "iservice_registry.h"
21 #include "array_wrapper.h"
22 #include "string_wrapper.h"
23 #include "want_params_wrapper.h"
24 #include "system_ability_definition.h"
25
26 #include "avsession_dynamic_insight.h"
27 #include "avsession_errors.h"
28 #include "avsession_log.h"
29
30 namespace OHOS::AVSession {
31
InsightAdapter()32 InsightAdapter::InsightAdapter()
33 {
34 SLOGI("construct");
35 }
36
~InsightAdapter()37 InsightAdapter::~InsightAdapter()
38 {
39 SLOGI("destroy");
40 }
41
GetInsightAdapterInstance()42 InsightAdapter& InsightAdapter::GetInsightAdapterInstance()
43 {
44 static InsightAdapter insightAdapter;
45 return insightAdapter;
46 }
47
CheckBundleSupport(std::string & profile)48 bool InsightAdapter::CheckBundleSupport(std::string& profile)
49 {
50 nlohmann::json profileValues = nlohmann::json::parse(profile, nullptr, false);
51 CHECK_AND_RETURN_RET_LOG(!profileValues.is_discarded(), false, "json object is null");
52 CHECK_AND_RETURN_RET_LOG(profileValues.contains("insightIntents"), false, "json do not contains insightIntents");
53 for (const auto& value : profileValues["insightIntents"]) {
54 std::string insightName = value["intentName"];
55 CHECK_AND_RETURN_RET_LOG(value.contains("uiAbility"), false, "json do not contains uiAbility");
56 nlohmann::json abilityValue = value["uiAbility"];
57 if (insightName != PLAY_MUSICLIST && insightName != PLAY_AUDIO) {
58 continue;
59 }
60 if (abilityValue.is_discarded()) {
61 SLOGE("uiability discarded=%{public}d", abilityValue.is_discarded());
62 return false;
63 }
64 CHECK_AND_RETURN_RET_LOG(abilityValue.contains("executeMode"), false, "json do not contains executeMode");
65 auto modeValues = abilityValue["executeMode"];
66 if (modeValues.is_discarded()) {
67 SLOGE("executeMode discarded=%{public}d", modeValues.is_discarded());
68 return false;
69 }
70 auto mode = std::find(modeValues.begin(), modeValues.end(), "background");
71 return (mode != modeValues.end());
72 }
73 return false;
74 }
75
IsSupportPlayIntent(const std::string & bundleName,std::string & supportModule,std::string & profile)76 __attribute__((no_sanitize("cfi"))) bool InsightAdapter::IsSupportPlayIntent(const std::string& bundleName,
77 std::string& supportModule, std::string& profile)
78 {
79 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
80 if (!systemAbilityManager) {
81 SLOGI("fail to get system ability mgr");
82 return false;
83 }
84
85 auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
86 if (!remoteObject) {
87 SLOGI("fail to get bundle manager proxy");
88 return false;
89 }
90
91 sptr<AppExecFwk::BundleMgrProxy> bundleMgrProxy = iface_cast<AppExecFwk::BundleMgrProxy>(remoteObject);
92 if (bundleMgrProxy == nullptr) {
93 return false;
94 }
95 SLOGI("get bundle manager proxy success");
96
97 AppExecFwk::BundleInfo bundleInfo;
98 if (!bundleMgrProxy->GetBundleInfo(bundleName, getBundleInfoWithHapModule, bundleInfo, startUserId)) {
99 SLOGE("GetBundleInfo=%{public}s fail", bundleName.c_str());
100 return false;
101 }
102 bool isSupportIntent = false;
103 for (const std::string& module : bundleInfo.moduleNames) {
104 auto ret = bundleMgrProxy->GetJsonProfile(AppExecFwk::ProfileType::INTENT_PROFILE, bundleName, module,
105 profile, startUserId);
106 if (ret == 0) {
107 SLOGI("GetJsonProfile success, profile=%{public}s", profile.c_str());
108 isSupportIntent = true;
109 supportModule = module;
110 break;
111 }
112 }
113 if (!isSupportIntent) {
114 SLOGE("Bundle=%{public}s does not support insight", bundleName.c_str());
115 return false;
116 }
117 return CheckBundleSupport(profile);
118 }
119
GetPlayIntentParam(const std::string & bundleName,const std::string & assetId,AppExecFwk::InsightIntentExecuteParam & executeParam)120 bool InsightAdapter::GetPlayIntentParam(const std::string& bundleName, const std::string& assetId,
121 AppExecFwk::InsightIntentExecuteParam &executeParam)
122 {
123 std::string supportModule;
124 std::string profile;
125 if (!IsSupportPlayIntent(bundleName, supportModule, profile)) {
126 SLOGE("bundle=%{public}s does not support play insights", bundleName.c_str());
127 return false;
128 }
129 SLOGD("GetJsonProfile profile=%{public}s", profile.c_str());
130 nlohmann::json profileValues = nlohmann::json::parse(profile, nullptr, false);
131 CHECK_AND_RETURN_RET_LOG(!profileValues.is_discarded(), false, "json object is null");
132 CHECK_AND_RETURN_RET_LOG(profileValues.contains("insightIntents"), false, "json do not contains insightIntents");
133 auto res = false;
134 for (const auto& value : profileValues["insightIntents"]) {
135 std::string insightName = value["intentName"];
136 nlohmann::json abilityValue = value["uiAbility"];
137 SLOGD(" insightName=%{public}s", insightName.c_str());
138 if (insightName != PLAY_MUSICLIST && insightName != PLAY_AUDIO) {
139 continue;
140 }
141 if (!value.contains("uiAbility") || abilityValue.is_discarded()) {
142 SLOGE("uiability discarded=%{public}d", abilityValue.is_discarded());
143 continue;
144 }
145 SLOGD("insightName=%{public}s", insightName.c_str());
146 executeParam.bundleName_ = bundleName;
147 executeParam.moduleName_ = supportModule;
148 executeParam.abilityName_ = abilityValue["ability"];
149 executeParam.insightIntentName_ = insightName;
150 executeParam.executeMode_ = AppExecFwk::ExecuteMode::UI_ABILITY_BACKGROUND;
151 std::shared_ptr<AppExecFwk::WantParams> wantParam = std::make_shared<AppExecFwk::WantParams>();
152 if (insightName == PLAY_MUSICLIST) {
153 // construct items array
154 AppExecFwk::WantParams innerParams;
155 innerParams.SetParam("entityId", OHOS::AAFwk::String::Box(assetId));
156 sptr<OHOS::AAFwk::IArray> array = new (std::nothrow) OHOS::AAFwk::Array(1, OHOS::AAFwk::g_IID_IWantParams);
157 array->Set(0, OHOS::AAFwk::WantParamWrapper::Box(innerParams));
158 wantParam->SetParam("items", array);
159 res = true;
160 }
161 if (insightName == PLAY_AUDIO) {
162 wantParam->SetParam("entityId", AppExecFwk::WantParams::GetInterfaceByType(interfaceType, assetId));
163 res = true;
164 }
165 executeParam.insightIntentParam_ = wantParam;
166 }
167 return res;
168 }
169
StartAVPlayback(AppExecFwk::InsightIntentExecuteParam & executeParam)170 int32_t InsightAdapter::StartAVPlayback(AppExecFwk::InsightIntentExecuteParam &executeParam)
171 {
172 SLOGI("bundleName=%{public}s abilityName=%{public}s moduleName=%{public}s IntentName=%{public}s",
173 executeParam.bundleName_.c_str(), executeParam.abilityName_.c_str(),
174 executeParam.moduleName_.c_str(), executeParam.insightIntentName_.c_str());
175
176 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
177 if (systemManager == nullptr) {
178 SLOGE("Fail to get registry");
179 return AVSESSION_ERROR;
180 }
181 sptr<IRemoteObject> remote = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
182 if (remote == nullptr) {
183 SLOGE("Fail to connect ability manager service");
184 return AVSESSION_ERROR;
185 }
186
187 auto ret = AAFwk::AbilityManagerClient::GetInstance()->ExecuteIntent((uint64_t) AVSESSION_SERVICE_ID,
188 remote, executeParam);
189 if (ret != AVSESSION_SUCCESS) {
190 SLOGE("ExecuteIntent insightIntent=%{public}s fail", executeParam.insightIntentName_.c_str());
191 return AVSESSION_ERROR;
192 }
193 return AVSESSION_SUCCESS;
194 }
195
IsSupportPlayIntent(const std::string & bundleName,const std::string & assetId)196 extern "C" bool IsSupportPlayIntent(const std::string& bundleName, const std::string& assetId)
197 {
198 AppExecFwk::InsightIntentExecuteParam executeParam;
199 return InsightAdapter::GetInsightAdapterInstance().GetPlayIntentParam(bundleName, assetId, executeParam);
200 }
201
StartAVPlayback(const std::string & bundleName,const std::string & assetId)202 extern "C" int32_t StartAVPlayback(const std::string& bundleName, const std::string& assetId)
203 {
204 AppExecFwk::InsightIntentExecuteParam executeParam;
205 bool isSupport = InsightAdapter::GetInsightAdapterInstance().GetPlayIntentParam(bundleName, assetId, executeParam);
206 if (isSupport) {
207 return InsightAdapter::GetInsightAdapterInstance().StartAVPlayback(executeParam);
208 }
209 return AVSESSION_SUCCESS;
210 }
211 }
212