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