• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bundle_mgr_proxy.h"
17 #include "iremote_stub.h"
18 #include "iservice_registry.h"
19 #include "array_wrapper.h"
20 #include "string_wrapper.h"
21 #include "want_params_wrapper.h"
22 #include "system_ability_definition.h"
23 
24 #include "avsession_dynamic_insight.h"
25 #include "avsession_errors.h"
26 #include "avsession_log.h"
27 
28 namespace OHOS::AVSession {
29 
InsightAdapter()30 InsightAdapter::InsightAdapter()
31 {
32     SLOGI("construct");
33 }
34 
~InsightAdapter()35 InsightAdapter::~InsightAdapter()
36 {
37     SLOGI("destroy");
38 }
39 
GetInsightAdapterInstance()40 InsightAdapter& InsightAdapter::GetInsightAdapterInstance()
41 {
42     static InsightAdapter insightAdapter;
43     return insightAdapter;
44 }
45 
CheckBundleSupport(std::string & profile)46 bool InsightAdapter::CheckBundleSupport(std::string& profile)
47 {
48     cJSON* profileValues = cJSON_Parse(profile.c_str());
49     CHECK_AND_RETURN_RET_LOG(profileValues != nullptr, false, "parse profile fail");
50     if (cJSON_IsInvalid(profileValues)) {
51         SLOGE("parse profile not valid json");
52         cJSON_Delete(profileValues);
53         return false;
54     }
55     cJSON* insightIntentsArray = cJSON_GetObjectItem(profileValues, "insightIntents");
56     if (insightIntentsArray == nullptr || !cJSON_IsArray(insightIntentsArray)) {
57         SLOGE("json do not contain insightIntentsArray");
58         cJSON_Delete(profileValues);
59         return false;
60     }
61 
62     cJSON* insightIntentsItem = nullptr;
63     cJSON_ArrayForEach(insightIntentsItem, insightIntentsArray) {
64         cJSON* intentNameItem = cJSON_GetObjectItem(insightIntentsItem, "intentName");
65         if (intentNameItem == nullptr || !cJSON_IsString(intentNameItem)) {
66             SLOGE("json do not contain intentName");
67             continue;
68         }
69         const char* insightName = intentNameItem->valuestring;
70         if (insightName != nullptr &&
71             strcmp(insightName, PLAY_MUSICLIST.c_str()) != 0 && strcmp(insightName, PLAY_AUDIO.c_str()) != 0) {
72             continue;
73         }
74 
75         cJSON* uiAbilityItem = cJSON_GetObjectItem(insightIntentsItem, "uiAbility");
76         if (uiAbilityItem == nullptr) {
77             SLOGE("json do not contain uiAbility");
78             cJSON_Delete(profileValues);
79             return false;
80         }
81         cJSON* executeModeArray = cJSON_GetObjectItem(uiAbilityItem, "executeMode");
82         if (executeModeArray == nullptr || !cJSON_IsArray(executeModeArray)) {
83             SLOGE("json do not contain executeMode");
84             cJSON_Delete(profileValues);
85             return false;
86         }
87         cJSON* modeItem = nullptr;
88         cJSON_ArrayForEach(modeItem, executeModeArray) {
89             if (cJSON_IsString(modeItem) && modeItem->valuestring != nullptr &&
90                 strcmp(modeItem->valuestring, "background") == 0) {
91                 cJSON_Delete(profileValues);
92                 return true;
93             }
94         }
95     }
96     cJSON_Delete(profileValues);
97     return false;
98 }
99 
IsSupportPlayIntent(const std::string & bundleName,std::string & supportModule,std::string & profile)100 __attribute__((no_sanitize("cfi"))) bool InsightAdapter::IsSupportPlayIntent(const std::string& bundleName,
101     std::string& supportModule, std::string& profile)
102 {
103     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
104     if (!systemAbilityManager) {
105         SLOGI("fail to get system ability mgr");
106         return false;
107     }
108 
109     auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
110     if (!remoteObject) {
111         SLOGI("fail to get bundle manager proxy");
112         return false;
113     }
114 
115     sptr<AppExecFwk::BundleMgrProxy> bundleMgrProxy = iface_cast<AppExecFwk::BundleMgrProxy>(remoteObject);
116     if (bundleMgrProxy == nullptr) {
117         return false;
118     }
119     SLOGI("get bundle manager proxy success");
120 
121     AppExecFwk::BundleInfo bundleInfo;
122     if (!bundleMgrProxy->GetBundleInfo(bundleName, getBundleInfoWithHapModule, bundleInfo, startUserId)) {
123         SLOGE("GetBundleInfo=%{public}s fail", bundleName.c_str());
124         return false;
125     }
126     bool isSupportIntent = false;
127     for (const std::string& module : bundleInfo.moduleNames) {
128         auto ret = bundleMgrProxy->GetJsonProfile(AppExecFwk::ProfileType::INTENT_PROFILE, bundleName, module,
129             profile, startUserId);
130         if (ret == 0) {
131             SLOGI("GetJsonProfile success, profile=%{public}s", profile.c_str());
132             isSupportIntent = true;
133             supportModule = module;
134             break;
135         }
136     }
137     if (!isSupportIntent) {
138         SLOGE("Bundle=%{public}s does not support insight", bundleName.c_str());
139         return false;
140     }
141     return CheckBundleSupport(profile);
142 }
143 
SetStartPlayInfoToParam(const StartPlayInfo startPlayInfo,StartPlayType startPlayType,std::shared_ptr<AppExecFwk::WantParams> & wantParam)144 void InsightAdapter::SetStartPlayInfoToParam(const StartPlayInfo startPlayInfo, StartPlayType startPlayType,
145     std::shared_ptr<AppExecFwk::WantParams> &wantParam)
146 {
147     AppExecFwk::WantParams startPlayInfoParam;
148     startPlayInfoParam.SetParam("startPlayBundleName", OHOS::AAFwk::String::Box(startPlayInfo.getBundleName()));
149     startPlayInfoParam.SetParam("deviceId", OHOS::AAFwk::String::Box(startPlayInfo.getDeviceId()));
150 
151     if (wantParam == nullptr) {
152         SLOGE("wantParam is null when SetStartPlayInfoToParam");
153         return;
154     }
155     wantParam->SetParam("startPlayInfo", OHOS::AAFwk::WantParamWrapper::Box(startPlayInfoParam));
156     wantParam->SetParam("startPlayType", OHOS::AAFwk::String::Box(StartPlayTypeToString.at(startPlayType)));
157 }
158 
GetPlayIntentParamWithWantProcess(std::string & insightName,const std::string & assetId,const StartPlayInfo startPlayInfo,StartPlayType startPlayType,bool & res)159 std::shared_ptr<AppExecFwk::WantParams> InsightAdapter::GetPlayIntentParamWithWantProcess(std::string& insightName,
160     const std::string& assetId, const StartPlayInfo startPlayInfo, StartPlayType startPlayType, bool& res)
161 {
162     std::shared_ptr<AppExecFwk::WantParams> wantParam = std::make_shared<AppExecFwk::WantParams>();
163     if (insightName == PLAY_MUSICLIST) {
164         AppExecFwk::WantParams innerParams; // construct items array
165         innerParams.SetParam("entityId", OHOS::AAFwk::String::Box(assetId));
166         sptr<OHOS::AAFwk::IArray> array = new (std::nothrow) OHOS::AAFwk::Array(1, OHOS::AAFwk::g_IID_IWantParams);
167         CHECK_AND_RETURN_RET_LOG(array != nullptr, wantParam, "new Array is null");
168         array->Set(0, OHOS::AAFwk::WantParamWrapper::Box(innerParams));
169         wantParam->SetParam("items", array);
170         SetStartPlayInfoToParam(startPlayInfo, startPlayType, wantParam);
171         res = true;
172     }
173     if (insightName == PLAY_AUDIO) {
174         wantParam->SetParam("entityId", AppExecFwk::WantParams::GetInterfaceByType(interfaceType, assetId));
175         SetStartPlayInfoToParam(startPlayInfo, startPlayType, wantParam);
176         res = true;
177     }
178     return wantParam;
179 }
180 
GetPlayIntentParam(const std::string & bundleName,const std::string & assetId,AppExecFwk::InsightIntentExecuteParam & executeParam,const StartPlayInfo startPlayInfo,StartPlayType startPlayType)181 bool InsightAdapter::GetPlayIntentParam(const std::string& bundleName, const std::string& assetId,
182     AppExecFwk::InsightIntentExecuteParam &executeParam, const StartPlayInfo startPlayInfo, StartPlayType startPlayType)
183 {
184     std::string supportModule;
185     std::string profile;
186     if (!IsSupportPlayIntent(bundleName, supportModule, profile)) {
187         SLOGE("bundle=%{public}s does not support play insights", bundleName.c_str());
188         return false;
189     }
190     SLOGD("GetJsonProfile profile=%{public}s", profile.c_str());
191     cJSON* profileValues = cJSON_Parse(profile.c_str());
192     CHECK_AND_RETURN_RET_LOG(profileValues != nullptr && !cJSON_IsInvalid(profileValues), false, "parse profile fail");
193     cJSON* insightIntentsArray = cJSON_GetObjectItem(profileValues, "insightIntents");
194     if (insightIntentsArray == nullptr || !cJSON_IsArray(insightIntentsArray)) {
195         SLOGE("json do not contain insightIntentsArray");
196         cJSON_Delete(profileValues);
197         return false;
198     }
199     bool res = false;
200     cJSON* insightIntentsItem = nullptr;
201     cJSON_ArrayForEach(insightIntentsItem, insightIntentsArray) {
202         cJSON* intentNameItem = cJSON_GetObjectItem(insightIntentsItem, "intentName");
203         if (intentNameItem == nullptr || !cJSON_IsString(intentNameItem)) {
204             SLOGE("json do not contain intentName");
205             continue;
206         }
207         std::string insightName(intentNameItem->valuestring);
208         if (insightName != PLAY_MUSICLIST && insightName != PLAY_AUDIO) {
209             continue;
210         }
211         cJSON* uiAbilityItem = cJSON_GetObjectItem(insightIntentsItem, "uiAbility");
212         if (uiAbilityItem == nullptr) {
213             SLOGE("json do not contain uiAbility");
214             continue;
215         }
216         cJSON* abilityItem = cJSON_GetObjectItem(uiAbilityItem, "ability");
217         if (abilityItem == nullptr || !cJSON_IsString(abilityItem)) {
218             SLOGE("json do not contain ability");
219             continue;
220         }
221         executeParam.bundleName_ = bundleName;
222         executeParam.moduleName_ = supportModule;
223         executeParam.abilityName_.assign(abilityItem->valuestring);
224         executeParam.insightIntentName_ = insightName;
225         executeParam.executeMode_ = AppExecFwk::ExecuteMode::UI_ABILITY_BACKGROUND;
226         std::shared_ptr<AppExecFwk::WantParams> wantParam =
227             GetPlayIntentParamWithWantProcess(insightName, assetId, startPlayInfo, startPlayType, res);
228         executeParam.insightIntentParam_ = wantParam;
229     }
230     cJSON_Delete(profileValues);
231     return res;
232 }
233 
ExecuteIntentFromAVSession(uint64_t key,const sptr<IRemoteObject> & callerToken,AppExecFwk::InsightIntentExecuteParam & param)234 bool InsightAdapter::ExecuteIntentFromAVSession(uint64_t key, const sptr<IRemoteObject> &callerToken,
235     AppExecFwk::InsightIntentExecuteParam &param)
236 {
237     MessageParcel data;
238     MessageParcel reply;
239     MessageOption option;
240     if (!data.WriteInterfaceToken(ABILITY_MANAGER_INTERFACE_TOKEN)) {
241         SLOGE("write interface token failed");
242         return false;
243     }
244     if (!data.WriteUint64(key)) {
245         SLOGE("write key fail");
246         return false;
247     }
248     if (!data.WriteRemoteObject(callerToken)) {
249         SLOGE("write callerToken fail");
250         return false;
251     }
252     if (!data.WriteParcelable(&param)) {
253         SLOGE("write param fail");
254         return false;
255     }
256 
257     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
258     if (systemManager == nullptr) {
259         SLOGE("Fail to get registry");
260         return false;
261     }
262     sptr<IRemoteObject> remote = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
263     if (remote == nullptr) {
264         SLOGE("Fail to connect ability manager service");
265         return false;
266     }
267     SLOGI("Connect ability manager service success");
268 
269     if (remote->SendRequest(static_cast<uint32_t>(AVSESSION_EXECUTE_INTENT_CODE),
270         data, reply, option) != 0) {
271         SLOGE("Send request error");
272         return false;
273     }
274     return reply.ReadInt32() == ERR_OK;
275 }
276 
StartAVPlayback(AppExecFwk::InsightIntentExecuteParam & executeParam)277 int32_t InsightAdapter::StartAVPlayback(AppExecFwk::InsightIntentExecuteParam &executeParam)
278 {
279     SLOGI("bundleName=%{public}s abilityName=%{public}s moduleName=%{public}s IntentName=%{public}s",
280         executeParam.bundleName_.c_str(), executeParam.abilityName_.c_str(),
281         executeParam.moduleName_.c_str(), executeParam.insightIntentName_.c_str());
282 
283     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
284     if (systemManager == nullptr) {
285         SLOGE("Fail to get registry");
286         return AVSESSION_ERROR;
287     }
288     sptr<IRemoteObject> remote = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
289     if (remote == nullptr) {
290         SLOGE("Fail to connect ability manager service");
291         return AVSESSION_ERROR;
292     }
293 
294     bool ret = ExecuteIntentFromAVSession((uint64_t) AVSESSION_SERVICE_ID, remote, executeParam);
295     if (!ret) {
296         SLOGE("ExecuteIntent insightIntent=%{public}s fail", executeParam.insightIntentName_.c_str());
297         return AVSESSION_ERROR;
298     }
299     return AVSESSION_SUCCESS;
300 }
301 
IsSupportPlayIntent(const std::string & bundleName,const std::string & assetId)302 extern "C" bool IsSupportPlayIntent(const std::string& bundleName, const std::string& assetId)
303 {
304     AppExecFwk::InsightIntentExecuteParam executeParam;
305     return InsightAdapter::GetInsightAdapterInstance().GetPlayIntentParam(bundleName, assetId, executeParam);
306 }
307 
StartAVPlaybackWithId(const std::string & bundleName,const std::string & assetId,const StartPlayInfo startPlayInfo,StartPlayType startPlayType)308 extern "C" int32_t StartAVPlaybackWithId(const std::string& bundleName, const std::string& assetId,
309     const StartPlayInfo startPlayInfo, StartPlayType startPlayType)
310 {
311     AppExecFwk::InsightIntentExecuteParam executeParam;
312     bool isSupport = InsightAdapter::GetInsightAdapterInstance().GetPlayIntentParam(bundleName, assetId,
313         executeParam, startPlayInfo, startPlayType);
314     if (isSupport) {
315         return InsightAdapter::GetInsightAdapterInstance().StartAVPlayback(executeParam);
316     }
317     return AVSESSION_SUCCESS;
318 }
319 
StartAVPlayback(const std::string & bundleName,const std::string & assetId)320 extern "C" int32_t StartAVPlayback(const std::string& bundleName, const std::string& assetId)
321 {
322     AppExecFwk::InsightIntentExecuteParam executeParam;
323     bool isSupport = InsightAdapter::GetInsightAdapterInstance().GetPlayIntentParam(bundleName, assetId, executeParam);
324     if (isSupport) {
325         return InsightAdapter::GetInsightAdapterInstance().StartAVPlayback(executeParam);
326     }
327     return AVSESSION_SUCCESS;
328 }
329 }
330