Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

SystemWebViewEngine.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. Licensed to the Apache Software Foundation (ASF) under one
  3. or more contributor license agreements. See the NOTICE file
  4. distributed with this work for additional information
  5. regarding copyright ownership. The ASF licenses this file
  6. to you under the Apache License, Version 2.0 (the
  7. "License"); you may not use this file except in compliance
  8. with the License. You may obtain a copy of the License at
  9. http://www.apache.org/licenses/LICENSE-2.0
  10. Unless required by applicable law or agreed to in writing,
  11. software distributed under the License is distributed on an
  12. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  13. KIND, either express or implied. See the License for the
  14. specific language governing permissions and limitations
  15. under the License.
  16. */
  17. package org.apache.cordova.engine;
  18. import android.annotation.SuppressLint;
  19. import android.annotation.TargetApi;
  20. import android.content.BroadcastReceiver;
  21. import android.content.Context;
  22. import android.content.Intent;
  23. import android.content.IntentFilter;
  24. import android.content.pm.ApplicationInfo;
  25. import android.os.Build;
  26. import android.view.View;
  27. import android.webkit.ValueCallback;
  28. import android.webkit.WebSettings;
  29. import android.webkit.WebSettings.LayoutAlgorithm;
  30. import android.webkit.WebView;
  31. import org.apache.cordova.CordovaBridge;
  32. import org.apache.cordova.CordovaInterface;
  33. import org.apache.cordova.CordovaPreferences;
  34. import org.apache.cordova.CordovaResourceApi;
  35. import org.apache.cordova.CordovaWebView;
  36. import org.apache.cordova.CordovaWebViewEngine;
  37. import org.apache.cordova.ICordovaCookieManager;
  38. import org.apache.cordova.LOG;
  39. import org.apache.cordova.NativeToJsMessageQueue;
  40. import org.apache.cordova.PluginManager;
  41. import java.lang.reflect.InvocationTargetException;
  42. import java.lang.reflect.Method;
  43. /**
  44. * Glue class between CordovaWebView (main Cordova logic) and SystemWebView (the actual View).
  45. * We make the Engine separate from the actual View so that:
  46. * A) We don't need to worry about WebView methods clashing with CordovaWebViewEngine methods
  47. * (e.g.: goBack() is void for WebView, and boolean for CordovaWebViewEngine)
  48. * B) Separating the actual View from the Engine makes API surfaces smaller.
  49. * Class uses two-phase initialization. However, CordovaWebView is responsible for calling .init().
  50. */
  51. public class SystemWebViewEngine implements CordovaWebViewEngine {
  52. public static final String TAG = "SystemWebViewEngine";
  53. protected final SystemWebView webView;
  54. protected final SystemCookieManager cookieManager;
  55. protected CordovaPreferences preferences;
  56. protected CordovaBridge bridge;
  57. protected CordovaWebViewEngine.Client client;
  58. protected CordovaWebView parentWebView;
  59. protected CordovaInterface cordova;
  60. protected PluginManager pluginManager;
  61. protected CordovaResourceApi resourceApi;
  62. protected NativeToJsMessageQueue nativeToJsMessageQueue;
  63. private BroadcastReceiver receiver;
  64. /** Used when created via reflection. */
  65. public SystemWebViewEngine(Context context, CordovaPreferences preferences) {
  66. this(new SystemWebView(context), preferences);
  67. }
  68. public SystemWebViewEngine(SystemWebView webView) {
  69. this(webView, null);
  70. }
  71. public SystemWebViewEngine(SystemWebView webView, CordovaPreferences preferences) {
  72. this.preferences = preferences;
  73. this.webView = webView;
  74. cookieManager = new SystemCookieManager(webView);
  75. }
  76. @Override
  77. public void init(CordovaWebView parentWebView, CordovaInterface cordova, CordovaWebViewEngine.Client client,
  78. CordovaResourceApi resourceApi, PluginManager pluginManager,
  79. NativeToJsMessageQueue nativeToJsMessageQueue) {
  80. if (this.cordova != null) {
  81. throw new IllegalStateException();
  82. }
  83. // Needed when prefs are not passed by the constructor
  84. if (preferences == null) {
  85. preferences = parentWebView.getPreferences();
  86. }
  87. this.parentWebView = parentWebView;
  88. this.cordova = cordova;
  89. this.client = client;
  90. this.resourceApi = resourceApi;
  91. this.pluginManager = pluginManager;
  92. this.nativeToJsMessageQueue = nativeToJsMessageQueue;
  93. webView.init(this, cordova);
  94. initWebViewSettings();
  95. nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() {
  96. @Override
  97. public void setNetworkAvailable(boolean value) {
  98. //sometimes this can be called after calling webview.destroy() on destroy()
  99. //thus resulting in a NullPointerException
  100. if(webView!=null) {
  101. webView.setNetworkAvailable(value);
  102. }
  103. }
  104. @Override
  105. public void runOnUiThread(Runnable r) {
  106. SystemWebViewEngine.this.cordova.getActivity().runOnUiThread(r);
  107. }
  108. }));
  109. nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.EvalBridgeMode(this, cordova));
  110. bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue);
  111. exposeJsInterface(webView, bridge);
  112. }
  113. @Override
  114. public CordovaWebView getCordovaWebView() {
  115. return parentWebView;
  116. }
  117. @Override
  118. public ICordovaCookieManager getCookieManager() {
  119. return cookieManager;
  120. }
  121. @Override
  122. public View getView() {
  123. return webView;
  124. }
  125. @SuppressLint({"NewApi", "SetJavaScriptEnabled"})
  126. @SuppressWarnings("deprecation")
  127. private void initWebViewSettings() {
  128. webView.setInitialScale(0);
  129. webView.setVerticalScrollBarEnabled(false);
  130. // Enable JavaScript
  131. final WebSettings settings = webView.getSettings();
  132. settings.setJavaScriptEnabled(true);
  133. settings.setJavaScriptCanOpenWindowsAutomatically(true);
  134. settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
  135. String manufacturer = android.os.Build.MANUFACTURER;
  136. LOG.d(TAG, "CordovaWebView is running on device made by: " + manufacturer);
  137. //We don't save any form data in the application
  138. settings.setSaveFormData(false);
  139. settings.setSavePassword(false);
  140. // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
  141. // while we do this
  142. settings.setAllowUniversalAccessFromFileURLs(true);
  143. settings.setMediaPlaybackRequiresUserGesture(false);
  144. // Enable database
  145. // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
  146. String databasePath = webView.getContext().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
  147. settings.setDatabaseEnabled(true);
  148. settings.setDatabasePath(databasePath);
  149. //Determine whether we're in debug or release mode, and turn on Debugging!
  150. ApplicationInfo appInfo = webView.getContext().getApplicationContext().getApplicationInfo();
  151. if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
  152. enableRemoteDebugging();
  153. }
  154. settings.setGeolocationDatabasePath(databasePath);
  155. // Enable DOM storage
  156. settings.setDomStorageEnabled(true);
  157. // Enable built-in geolocation
  158. settings.setGeolocationEnabled(true);
  159. // Enable AppCache
  160. // Fix for CB-2282
  161. settings.setAppCacheMaxSize(5 * 1048576);
  162. settings.setAppCachePath(databasePath);
  163. settings.setAppCacheEnabled(true);
  164. // Fix for CB-1405
  165. // Google issue 4641
  166. String defaultUserAgent = settings.getUserAgentString();
  167. // Fix for CB-3360
  168. String overrideUserAgent = preferences.getString("OverrideUserAgent", null);
  169. if (overrideUserAgent != null) {
  170. settings.setUserAgentString(overrideUserAgent);
  171. } else {
  172. String appendUserAgent = preferences.getString("AppendUserAgent", null);
  173. if (appendUserAgent != null) {
  174. settings.setUserAgentString(defaultUserAgent + " " + appendUserAgent);
  175. }
  176. }
  177. // End CB-3360
  178. IntentFilter intentFilter = new IntentFilter();
  179. intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
  180. if (this.receiver == null) {
  181. this.receiver = new BroadcastReceiver() {
  182. @Override
  183. public void onReceive(Context context, Intent intent) {
  184. settings.getUserAgentString();
  185. }
  186. };
  187. webView.getContext().registerReceiver(this.receiver, intentFilter);
  188. }
  189. // end CB-1405
  190. }
  191. private void enableRemoteDebugging() {
  192. try {
  193. WebView.setWebContentsDebuggingEnabled(true);
  194. } catch (IllegalArgumentException e) {
  195. LOG.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! ");
  196. e.printStackTrace();
  197. }
  198. }
  199. // Yeah, we know. It'd be great if lint was just a little smarter.
  200. @SuppressLint("AddJavascriptInterface")
  201. private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
  202. SystemExposedJsApi exposedJsApi = new SystemExposedJsApi(bridge);
  203. webView.addJavascriptInterface(exposedJsApi, "_cordovaNative");
  204. }
  205. /**
  206. * Load the url into the webview.
  207. */
  208. @Override
  209. public void loadUrl(final String url, boolean clearNavigationStack) {
  210. webView.loadUrl(url);
  211. }
  212. @Override
  213. public String getUrl() {
  214. return webView.getUrl();
  215. }
  216. @Override
  217. public void stopLoading() {
  218. webView.stopLoading();
  219. }
  220. @Override
  221. public void clearCache() {
  222. webView.clearCache(true);
  223. }
  224. @Override
  225. public void clearHistory() {
  226. webView.clearHistory();
  227. }
  228. @Override
  229. public boolean canGoBack() {
  230. return webView.canGoBack();
  231. }
  232. /**
  233. * Go to previous page in history. (We manage our own history)
  234. *
  235. * @return true if we went back, false if we are already at top
  236. */
  237. @Override
  238. public boolean goBack() {
  239. // Check webview first to see if there is a history
  240. // This is needed to support curPage#diffLink, since they are added to parentEngine's history, but not our history url array (JQMobile behavior)
  241. if (webView.canGoBack()) {
  242. webView.goBack();
  243. return true;
  244. }
  245. return false;
  246. }
  247. @Override
  248. public void setPaused(boolean value) {
  249. if (value) {
  250. webView.onPause();
  251. webView.pauseTimers();
  252. } else {
  253. webView.onResume();
  254. webView.resumeTimers();
  255. }
  256. }
  257. @Override
  258. public void destroy() {
  259. webView.chromeClient.destroyLastDialog();
  260. webView.destroy();
  261. // unregister the receiver
  262. if (receiver != null) {
  263. try {
  264. webView.getContext().unregisterReceiver(receiver);
  265. } catch (Exception e) {
  266. LOG.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e);
  267. }
  268. }
  269. }
  270. @Override
  271. public void evaluateJavascript(String js, ValueCallback<String> callback) {
  272. webView.evaluateJavascript(js, callback);
  273. }
  274. }