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 #ifndef WEBVIEW_JAVA_SCRIPT_RESULT_CALLBACK_H
17 #define WEBVIEW_JAVA_SCRIPT_RESULT_CALLBACK_H
18 
19 #include <string>
20 
21 #include "webview_ffi.h"
22 #include "nweb.h"
23 #include "nweb_javascript_result_callback.h"
24 #include "nweb_web_message.h"
25 #include "webview_log.h"
26 
27 
28 namespace OHOS::Webview {
29 
30 class JavaScriptOb {
31 public:
32     // to be compatible with older webcotroller, be sure to the same as ace and core
33     enum class JavaScriptObjIdErrorCode : int32_t { WEBCONTROLLERERROR = -2, WEBVIEWCONTROLLERERROR = -1, END = 0 };
34 
35     typedef int32_t ObjectID;
36 
CreateNamed(std::vector<std::function<char * (const char *)>> cjFuncs)37     static std::shared_ptr<JavaScriptOb> CreateNamed(std::vector<std::function<char*(const char*)>> cjFuncs)
38     {
39         return std::make_shared<JavaScriptOb>(cjFuncs);
40     }
41 
JavaScriptOb(std::vector<std::function<char * (const char *)>> cjFuncs)42     explicit JavaScriptOb(std::vector<std::function<char*(const char*)>> cjFuncs) : cjFuncs_(cjFuncs), namesCount_(0)
43     {}
44 
IsNamed()45     bool IsNamed()
46     {
47         return namesCount_ > 0;
48     }
AddName()49     void AddName()
50     {
51         ++namesCount_;
52     }
RemoveName()53     void RemoveName()
54     {
55         --namesCount_;
56     }
57 
GetMethodNames()58     std::vector<std::string> GetMethodNames()
59     {
60         return methods_;
61     }
62 
GetFuncs()63     std::vector<std::function<char*(const char*)>> GetFuncs()
64     {
65         return cjFuncs_;
66     }
67 
HasMethod(const std::string & methodName)68     int HasMethod(const std::string& methodName)
69     {
70         if (methodName.empty()) {
71             WEBVIEWLOGE("HasMethod methodName null");
72             return -1;
73         }
74 
75         if (!isMethodsSetup_) {
76             return -1;
77         }
78         int size = static_cast<int>(methods_.size());
79         for (int i = 0; i < size; i++) {
80             if (methodName == methods_[i]) {
81                 return i;
82             }
83         }
84         return -1;
85     }
86 
FindMethod(const std::string & methodName)87     std::function<char*(const char*)> FindMethod(const std::string& methodName)
88     {
89         if (!isMethodsSetup_) {
90             return nullptr;
91         }
92         auto index = HasMethod(methodName);
93         if (index != -1) {
94             return cjFuncs_[index];
95         }
96         return nullptr;
97     }
98 
SetMethods(std::vector<std::string> methods_name)99     void SetMethods(std::vector<std::string> methods_name)
100     {
101         std::unique_lock<std::mutex> lock(mutex_);
102         methods_ = methods_name;
103         isMethodsSetup_ = true;
104     }
105 
106 private:
107 
108     std::vector<std::function<char*(const char*)>> cjFuncs_;
109 
110     std::vector<std::string> methods_;
111 
112     int namesCount_;
113 
114     bool isMethodsSetup_ = false;
115 
116     std::mutex mutex_;
117 };
118 
119 class WebviewJavaScriptResultCallBackImpl : public NWeb::NWebJavaScriptResultCallBack {
120 public:
121     typedef std::unordered_map<std::string, JavaScriptOb::ObjectID> NamedObjectMap;
122     typedef std::unordered_map<JavaScriptOb::ObjectID, std::shared_ptr<JavaScriptOb>> ObjectMap;
123 
WebviewJavaScriptResultCallBackImpl()124     WebviewJavaScriptResultCallBackImpl() {}
125 
126     explicit WebviewJavaScriptResultCallBackImpl(int32_t nwebId);
127 
128     ~WebviewJavaScriptResultCallBackImpl() override;
129 
130     std::shared_ptr<NWeb::NWebValue> GetJavaScriptResult(std::vector<std::shared_ptr<NWeb::NWebValue>> args,
131         const std::string& method, const std::string& objName, int32_t routingId, int32_t objectId) override;
132 
133     std::shared_ptr<NWeb::NWebValue> GetJavaScriptResultFlowbuf(std::vector<std::shared_ptr<NWeb::NWebValue>> args,
134         const std::string& method, const std::string& objName, int fd, int32_t routingId, int32_t objectId) override;
135 
136     bool HasJavaScriptObjectMethods(int32_t objectId, const std::string& methodName) override;
137 
138     std::shared_ptr<NWeb::NWebValue> GetJavaScriptObjectMethods(int32_t objectId) override;
139 
140     std::shared_ptr<JavaScriptOb> FindObject(JavaScriptOb::ObjectID objectId);
141 
142     bool FindObjectIdInJsTd(
143         const std::vector<std::function<char*(const char*)>>& cjFuncs,
144         const std::vector<std::string>& methodList, JavaScriptOb::ObjectID& objectId);
145 
146     JavaScriptOb::ObjectID AddObject(const std::vector<std::function<char*(const char*)>>& cjFuncs);
147 
148     JavaScriptOb::ObjectID RegisterJavaScriptProxy(
149         const std::vector<std::function<char*(const char*)>>& cjFuncs,
150         const std::string& objName, const std::vector<std::string>& methodList);
151 
152     void RemoveJavaScriptObjectHolder(int32_t holder, JavaScriptOb::ObjectID objectId) override;
153 
154     void RemoveTransientJavaScriptObject() override;
155 
GetNWebId()156     int32_t GetNWebId()
157     {
158         return nwebId_;
159     }
160 
161 private:
162     bool RemoveNamedObject(const std::string& name);
163 
164     JavaScriptOb::ObjectID AddNamedObject(const std::vector<std::function<char*(const char*)>>& cjFuncs,
165         const std::vector<std::string>& methodList, const std::string& objName);
166 
167     std::shared_ptr<NWeb::NWebValue> GetJavaScriptResultSelf(std::vector<std::shared_ptr<NWeb::NWebValue>> args,
168         const std::string& method, const std::string& objName, int32_t routingId, int32_t objectId);
169 
170     bool ConstructArgv(void* ashmem, std::vector<std::shared_ptr<NWeb::NWebValue>> args,
171     	std::vector<std::string>& argv, std::shared_ptr<JavaScriptOb> jsObj, int32_t routingId);
172 
173     char* FlowbufStrAtIndex(void* mem, int flowbufIndex, int* argIndex, int* strLen);
174 
175     std::shared_ptr<NWeb::NWebValue> GetJavaScriptResultSelfHelper(std::shared_ptr<JavaScriptOb> jsObj,
176         const std::string& method, int32_t routingId, std::vector<std::string> argv);
177 
178     std::shared_ptr<NWeb::NWebValue> GetJavaScriptResultSelfFlowbuf(std::vector<std::shared_ptr<NWeb::NWebValue>> args,
179         const std::string& method, const std::string& objName, int fd, int32_t routingId, int32_t objectId);
180 
181     int32_t nwebId_ = -1;
182 
183     JavaScriptOb::ObjectID nextObjectId_ = 1;
184     NamedObjectMap namedObjects_;
185     ObjectMap objects_;
186 };
187 
188 } // namespace OHOS::Webview
189 #endif
190