1 /*
2  * Copyright (c) 2021 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 "frameworks/bridge/js_frontend/frontend_delegate.h"
17 
18 #include "core/pipeline_ng/pipeline_context.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 #include "frameworks/core/components_ng/base/inspector.h"
21 
22 namespace OHOS::Ace::Framework {
23 namespace {
24 
25 const char SLASH = '/';
26 const char SLASHSTR[] = "/";
27 const char SUPDIRECTORY[] = "../";
28 
GetFileInfo(const std::string & fileUri,std::string & fileName,std::string & filePath)29 void GetFileInfo(const std::string& fileUri, std::string& fileName, std::string& filePath)
30 {
31     size_t slashPos = fileUri.find_last_of(SLASH);
32     if (slashPos == std::string::npos) {
33         fileName = fileUri;
34     } else {
35         fileName = fileUri.substr(slashPos + 1);
36         filePath = fileUri.substr(0, slashPos + 1);
37     }
38 
39     if (StartWith(filePath, SLASHSTR)) {
40         filePath = filePath.substr(1);
41     }
42 }
43 
ParseWorkerUri(const RefPtr<AssetManager> & assetManager,const std::string & fileUri,std::string & assetsFilePath)44 bool ParseWorkerUri(const RefPtr<AssetManager>& assetManager, const std::string& fileUri, std::string& assetsFilePath)
45 {
46     if (!assetManager || fileUri.empty() || (fileUri.length() > PATH_MAX)) {
47         return false;
48     }
49 
50     std::string fileName;
51     std::string filePath;
52     GetFileInfo(fileUri, fileName, filePath);
53     if (StartWith(filePath, SUPDIRECTORY)) {
54         filePath = filePath.substr(3); // 3 : offset of filePath
55     }
56     std::vector<std::string> files;
57     assetManager->GetAssetList(filePath, files);
58 
59     bool fileExist = false;
60     for (const auto& file : files) {
61         size_t filePos = file.find_last_of(SLASH);
62         if (filePos != std::string::npos) {
63             if (file.substr(filePos + 1) == fileName) {
64                 assetsFilePath = filePath + fileName;
65                 fileExist = true;
66                 break;
67             }
68         }
69     }
70     return fileExist;
71 }
72 
ParseFileUri(const RefPtr<AssetManager> & assetManager,const std::string & fileUri,std::string & assetsFilePath)73 bool ParseFileUri(const RefPtr<AssetManager>& assetManager, const std::string& fileUri, std::string& assetsFilePath)
74 {
75     if (!assetManager || fileUri.empty() || (fileUri.length() > PATH_MAX)) {
76         return false;
77     }
78 
79     std::string fileName;
80     std::string filePath;
81     GetFileInfo(fileUri, fileName, filePath);
82     std::vector<std::string> files;
83     assetManager->GetAssetList(filePath, files);
84 
85     bool fileExist = false;
86     for (const auto& file : files) {
87         bool startWithSlash = StartWith(file, SLASHSTR);
88         if ((startWithSlash && (file.substr(1) == fileName)) || (!startWithSlash && (file == fileName))) {
89             assetsFilePath = filePath + file;
90             fileExist = true;
91             break;
92         }
93     }
94 
95     return fileExist;
96 }
97 
98 } // namespace
99 
100 template<typename T>
GetResourceData(const std::string & fileUri,T & content)101 bool FrontendDelegate::GetResourceData(const std::string& fileUri, T& content)
102 {
103     std::string targetFilePath;
104     if (!ParseFileUri(assetManager_, fileUri, targetFilePath)) {
105         LOGE("GetResourceData parse file uri failed.");
106         return false;
107     }
108     if (!GetAssetContentAllowEmpty(assetManager_, targetFilePath, content)) {
109         LOGE("GetResourceData GetAssetContent failed.");
110         return false;
111     }
112 
113     return true;
114 }
115 
GetRectangleById(const std::string & key,NG::Rectangle & rectangle)116 void FrontendDelegate::GetRectangleById(const std::string& key, NG::Rectangle& rectangle)
117 {
118     NG::Inspector::GetRectangleById(key, rectangle);
119 }
120 
ResetFocus()121 void FrontendDelegate::ResetFocus()
122 {
123     TAG_LOGI(AceLogTag::ACE_FOCUS, "Lost focus to view root scope by user");
124     NG::FocusHub::LostFocusToViewRoot();
125 }
126 
RequestFocus(const std::string & value,bool isSyncRequest)127 bool FrontendDelegate::RequestFocus(const std::string& value, bool isSyncRequest)
128 {
129     auto pipeline = NG::PipelineContext::GetCurrentContext();
130     CHECK_NULL_RETURN(pipeline, false);
131     return pipeline->RequestFocus(value, isSyncRequest);
132 }
133 
SetRequestFocusCallback(std::function<void (NG::RequestFocusResult result)> callback)134 void FrontendDelegate::SetRequestFocusCallback(
135     std::function<void(NG::RequestFocusResult result)> callback)
136 {
137     auto pipeline = NG::PipelineContext::GetCurrentContext();
138     CHECK_NULL_VOID(pipeline);
139     auto focusManager = pipeline->GetOrCreateFocusManager();
140     CHECK_NULL_VOID(focusManager);
141     focusManager->SetRequestFocusCallback(callback);
142 }
143 
ResetRequestFocusCallback()144 void FrontendDelegate::ResetRequestFocusCallback()
145 {
146     auto pipeline = NG::PipelineContext::GetCurrentContext();
147     CHECK_NULL_VOID(pipeline);
148     auto focusManager = pipeline->GetOrCreateFocusManager();
149     CHECK_NULL_VOID(focusManager);
150     focusManager->ResetRequestFocusCallback();
151 }
152 
SetAutoFocusTransfer(bool isAutoFocusTransfer)153 void FrontendDelegate::SetAutoFocusTransfer(bool isAutoFocusTransfer)
154 {
155     auto pipeline = NG::PipelineContext::GetCurrentContext();
156     CHECK_NULL_VOID(pipeline);
157     auto focusManager = pipeline->GetOrCreateFocusManager();
158     CHECK_NULL_VOID(focusManager);
159     focusManager->SetIsAutoFocusTransfer(isAutoFocusTransfer);
160 }
161 
Activate(bool isActive,bool autoInactive)162 bool FrontendDelegate::Activate(bool isActive, bool autoInactive)
163 {
164     auto pipeline = NG::PipelineContext::GetCurrentContext();
165     CHECK_NULL_RETURN(pipeline, false);
166     return pipeline->SetIsFocusActive(isActive, NG::FocusActiveReason::USE_API, autoInactive);
167 }
168 
169 template<typename T>
GetResourceData(const std::string & fileUri,T & content,std::string & ami)170 bool FrontendDelegate::GetResourceData(const std::string& fileUri, T& content, std::string& ami)
171 {
172     std::string targetFilePath;
173     if (!ParseWorkerUri(assetManager_, fileUri, targetFilePath)) {
174         LOGE("GetResourceData parse file uri failed.");
175         return false;
176     }
177     ami = assetManager_->GetAssetPath(targetFilePath, true) + targetFilePath;
178     LOGI("GetResourceData ami: %{private}s.", ami.c_str());
179     if (!GetAssetContentAllowEmpty(assetManager_, targetFilePath, content)) {
180         LOGE("GetResourceData GetAssetContent failed.");
181         return false;
182     }
183     return true;
184 }
185 
186 template<typename T>
GetResourceData(const std::string & fileUri,const RefPtr<AssetManager> & assetManager,T & content)187 bool FrontendDelegate::GetResourceData(const std::string& fileUri, const RefPtr<AssetManager>& assetManager, T& content)
188 {
189     std::string targetFilePath;
190     if (!ParseFileUri(assetManager, fileUri, targetFilePath)) {
191         LOGE("GetResourceData parse file uri failed.");
192         return false;
193     }
194     if (!GetAssetContentAllowEmpty(assetManager, targetFilePath, content)) {
195         LOGE("GetResourceData GetAssetContent failed.");
196         return false;
197     }
198 
199     return true;
200 }
201 
202 template bool FrontendDelegate::GetResourceData(const std::string& fileUri, std::string& content);
203 template bool FrontendDelegate::GetResourceData(const std::string& fileUri, std::vector<uint8_t>& content);
204 template bool FrontendDelegate::GetResourceData(
205     const std::string& fileUri, std::vector<uint8_t>& content, std::string& ami);
206 template bool FrontendDelegate::GetResourceData(
207     const std::string& fileUri, const RefPtr<AssetManager>& assetManager, std::vector<uint8_t>& content);
208 
209 } // namespace OHOS::Ace::Framework
210