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 #include "adapter/ohos/osal/navigation_route_ohos.h"
16 #include "base/error/error_code.h"
17 
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20 
21 namespace OHOS::Ace {
22 
GetBundleManager()23 sptr<AppExecFwk::IBundleMgr> NavigationRouteOhos::GetBundleManager()
24 {
25     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
26     if (!systemAbilityMgr) {
27         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get system ability failed");
28         return nullptr;
29     }
30     auto bundleObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
31     if (!bundleObj) {
32         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get bundle service failed");
33         return nullptr;
34     }
35     return iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
36 }
37 
InitRouteMap()38 void NavigationRouteOhos::InitRouteMap()
39 {
40     auto bundleManager = GetBundleManager();
41     if (!bundleManager) {
42         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get bundle manager failed");
43         return;
44     }
45     AppExecFwk::BundleInfo bundleInfo;
46     if (bundleManager->GetBundleInfoForSelf(
47         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) +
48         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ROUTER_MAP),
49         bundleInfo) != 0) {
50         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get bundle info failed");
51         return;
52     }
53     allRouteItems_ = bundleInfo.routerArray;
54     moduleInfos_ = bundleInfo.hapModuleInfos;
55 }
56 
GetRouteItem(const std::string& name, NG::RouteItem& info)57 bool NavigationRouteOhos::GetRouteItem(const std::string& name, NG::RouteItem& info)
58 {
59     AppExecFwk::RouterItem routeItem;
60     if (!GetRouteItemFromBundle(name, routeItem)) {
61         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get route info %{public}s failed", name.c_str());
62         return false;
63     }
64     info.name = routeItem.name;
65     info.bundleName = routeItem.bundleName;
66     info.moduleName = routeItem.moduleName;
67     info.pageSourceFile = routeItem.pageSourceFile;
68     info.data = routeItem.data;
69     return true;
70 }
71 
GetRouteItemFromBundle(const std::string& name, AppExecFwk::RouterItem& routeItem)72 bool NavigationRouteOhos::GetRouteItemFromBundle(const std::string& name, AppExecFwk::RouterItem& routeItem)
73 {
74     for (auto moduleIter = allRouteItems_.begin(); moduleIter != allRouteItems_.end(); moduleIter++) {
75         if (moduleIter->name == name) {
76             routeItem = *moduleIter;
77             return true;
78         }
79     }
80     TAG_LOGE(AceLogTag::ACE_NAVIGATION, "can't find name in config file: %{public}s", name.c_str());
81     return false;
82 }
83 
LoadPage(const std::string& name)84 int32_t NavigationRouteOhos::LoadPage(const std::string& name)
85 {
86     AppExecFwk::RouterItem item;
87     if (!GetRouteItemFromBundle(name, item)) {
88         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get route name failed");
89         return ERROR_CODE_BUILDER_FUNCTION_NOT_REGISTERED;
90     }
91     if (callback_ == nullptr) {
92         return -1;
93     }
94     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "load navdestination %{public}s, ohmurl: %{public}s",
95         item.bundleName.c_str(), item.moduleName.c_str());
96     int32_t res = callback_(item.bundleName, item.moduleName, item.ohmurl, false);
97     if (res == 0) {
98         names_.emplace_back(name);
99     }
100     return LoadPageFromHapModule(name);
101 }
102 
IsNavigationItemExits(const std::string& name)103 bool NavigationRouteOhos::IsNavigationItemExits(const std::string& name)
104 {
105     if (HasLoaded(name)) {
106         return true;
107     }
108     AppExecFwk::RouterItem item;
109     if (GetRouteItemFromBundle(name, item)) {
110         return true;
111     }
112     return false;
113 }
114 
LoadPageFromHapModule(const std::string& name)115 int32_t NavigationRouteOhos::LoadPageFromHapModule(const std::string& name)
116 {
117     int32_t res = -1;
118     if (!callback_) {
119         return res;
120     }
121     for (auto hapIter = moduleInfos_.begin(); hapIter != moduleInfos_.end(); hapIter++) {
122         auto routerInfo = hapIter->routerArray;
123         for (auto routerIter = routerInfo.begin(); routerIter != routerInfo.end(); routerIter++) {
124             if (routerIter->name != name) {
125                 continue;
126             }
127             res = callback_(routerIter->bundleName, routerIter->moduleName, routerIter->ohmurl, false);
128             TAG_LOGD(AceLogTag::ACE_NAVIGATION, "load current destination name: %{public}s, ohmurl: %{public}s",
129                 name.c_str(), routerIter->ohmurl.c_str());
130             if (res == 0) {
131                 return 0;
132             }
133             break;
134         }
135     }
136     return res;
137 }
138 } // namespace OHOS::Ace