private static boolean needsSpecialsInAssetUrlFix(Uri uri) { if (CordovaResourceApi.getUriType(uri) != CordovaResourceApi.URI_TYPE_ASSET) { return false; } if (uri.getQuery() != null || uri.getFragment() != null) { return true; } if (!uri.toString().contains("%")) { return false; } switch(Build.VERSION.SDK_INT){ case Build.VERSION_CODES.ICE_CREAM_SANDWICH: case Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1: return true; } return false; }
private static boolean needsSpecialsInAssetUrlFix(Uri uri) { if (CordovaResourceApi.getUriType(uri) != CordovaResourceApi.URI_TYPE_ASSET) { return false; } if (uri.getQuery() != null || uri.getFragment() != null) { return true; } if (!uri.toString().contains("%")) { return false; } switch(android.os.Build.VERSION.SDK_INT){ case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH: case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1: return true; } return false; }
private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException { if (move) { String realSrcPath = srcFs.filesystemPathForURL(srcURL); if (realSrcPath != null) { File srcFile = new File(realSrcPath); if (srcFile.renameTo(destFile)) { return; } // Trying to rename the file failed. Possibly because we moved across file system on the device. } } CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(srcFs.toNativeUri(srcURL)); copyResource(offr, new FileOutputStream(destFile)); if (move) { srcFs.removeFileAtLocalURL(srcURL); } }
public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { // First, check to see that we can do it if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) { throw new NoModificationAllowedException("Cannot move file at source URL"); } final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory); Uri srcNativeUri = srcFs.toNativeUri(srcURL); CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcNativeUri); OutputStream os = null; try { os = getOutputStreamForURL(destination); } catch (IOException e) { ofrr.inputStream.close(); throw e; } // Closes streams. resourceApi.copyResource(ofrr, os); if (move) { srcFs.removeFileAtLocalURL(srcURL); } return getEntryForLocalURL(destination); }
private static boolean needsSpecialsInAssetUrlFix(Uri uri) { if (CordovaResourceApi.getUriType(uri) != CordovaResourceApi.URI_TYPE_ASSET) { return false; } if (uri.getQuery() != null || uri.getFragment() != null) { return true; } if (!uri.toString().contains("%")) { return false; } switch (android.os.Build.VERSION.SDK_INT) { case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH: case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1: return true; } return false; }
@Override public void init(CordovaWebView parentWebView, CordovaInterface cordova, CordovaWebViewEngine.Client client, CordovaResourceApi resourceApi, PluginManager pluginManager, NativeToJsMessageQueue nativeToJsMessageQueue) { if (this.cordova != null) { throw new IllegalStateException(); } // Needed when prefs are not passed by the constructor if (preferences == null) { preferences = parentWebView.getPreferences(); } this.parentWebView = parentWebView; this.cordova = cordova; this.client = client; this.resourceApi = resourceApi; this.pluginManager = pluginManager; this.nativeToJsMessageQueue = nativeToJsMessageQueue; webView.init(this, cordova); initWebViewSettings(); nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() { @Override public void setNetworkAvailable(boolean value) { webView.setNetworkAvailable(value); } @Override public void runOnUiThread(Runnable r) { SystemWebViewEngine.this.cordova.getActivity().runOnUiThread(r); } })); if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.EvalBridgeMode(this, cordova)); bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue); exposeJsInterface(webView, bridge); }
@TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { try { // Check the against the whitelist and lock out access to the WebView directory // Changing this will cause problems for your application if (!parentEngine.pluginManager.shouldAllowRequest(url)) { LOG.w(TAG, "URL blocked by whitelist: " + url); // Results in a 404. return new WebResourceResponse("text/plain", "UTF-8", null); } CordovaResourceApi resourceApi = parentEngine.resourceApi; Uri origUri = Uri.parse(url); // Allow plugins to intercept WebView requests. Uri remappedUri = resourceApi.remapUri(origUri); if (!origUri.equals(remappedUri) || needsSpecialsInAssetUrlFix(origUri) || needsKitKatContentUrlFix(origUri)) { CordovaResourceApi.OpenForReadResult result = resourceApi.openForRead(remappedUri, true); return new WebResourceResponse(result.mimeType, "UTF-8", result.inputStream); } // If we don't need to special-case the request, let the browser load it. return null; } catch (IOException e) { if (!(e instanceof FileNotFoundException)) { LOG.e(TAG, "Error occurred while loading a file (returning a 404).", e); } // Results in a 404. return new WebResourceResponse("text/plain", "UTF-8", null); } }
private void startActivity(String action, Uri uri, String type, Map<String, String> extras, boolean bExpectResult, int requestCode, CallbackContext callbackContext) { // Credit: https://github.com/chrisekelley/cordova-webintent Intent i = (uri != null ? new Intent(action, uri) : new Intent(action)); if (type != null && uri != null) { i.setDataAndType(uri, type); //Fix the crash problem with android 2.3.6 } else { if (type != null) { i.setType(type); } if (uri != null) { i.setData(uri); } } for (String key : extras.keySet()) { String value = extras.get(key); // If type is text html, the extra text must sent as HTML if (key.equals(Intent.EXTRA_TEXT) && type.equals("text/html")) { i.putExtra(key, Html.fromHtml(value)); } else if (key.equals(Intent.EXTRA_STREAM)) { // allowes sharing of images as attachments. // value in this case should be a URI of a file final CordovaResourceApi resourceApi = webView.getResourceApi(); i.putExtra(key, resourceApi.remapUri(Uri.parse(value))); } else if (key.equals(Intent.EXTRA_EMAIL)) { // allows to add the email address of the receiver i.putExtra(Intent.EXTRA_EMAIL, new String[] { value }); } else { i.putExtra(key, value); } } i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); if (i.resolveActivityInfo(this.cordova.getActivity().getPackageManager(), 0) != null) { if (bExpectResult) { cordova.setActivityResultCallback(this); ((CordovaActivity) this.cordova.getActivity()).startActivityForResult(i, requestCode); } else { ((CordovaActivity)this.cordova.getActivity()).startActivity(i); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); } } else { // Return an error as there is no app to handle this intent callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR)); } }
@Override public void init(CordovaWebView parentWebView, CordovaInterface cordova, Client client, CordovaResourceApi resourceApi, PluginManager pluginManager, NativeToJsMessageQueue nativeToJsMessageQueue) { if (this.cordova != null) { throw new IllegalStateException(); } // Needed when prefs are not passed by the constructor if (preferences == null) { preferences = parentWebView.getPreferences(); } this.parentWebView = parentWebView; this.cordova = cordova; this.client = client; this.resourceApi = resourceApi; this.pluginManager = pluginManager; this.nativeToJsMessageQueue = nativeToJsMessageQueue; webView.init(this, cordova); initWebViewSettings(); nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() { @Override public void setNetworkAvailable(boolean value) { webView.setNetworkAvailable(value); } @Override public void runOnUiThread(Runnable r) { X5WebViewEngine.this.cordova.getActivity().runOnUiThread(r); } })); bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue); exposeJsInterface(webView, bridge); }
private static void copyResource(CordovaResourceApi.OpenForReadResult input, OutputStream outputStream) throws IOException { try { InputStream inputStream = input.inputStream; if (inputStream instanceof FileInputStream && outputStream instanceof FileOutputStream) { FileChannel inChannel = ((FileInputStream)input.inputStream).getChannel(); FileChannel outChannel = ((FileOutputStream)outputStream).getChannel(); long offset = 0; long length = input.length; if (input.assetFd != null) { offset = input.assetFd.getStartOffset(); } // transferFrom()'s 2nd arg is a relative position. Need to set the absolute // position first. inChannel.position(offset); outChannel.transferFrom(inChannel, 0, length); } else { final int BUFFER_SIZE = 8192; byte[] buffer = new byte[BUFFER_SIZE]; for (;;) { int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE); if (bytesRead <= 0) { break; } outputStream.write(buffer, 0, bytesRead); } } } finally { input.inputStream.close(); if (outputStream != null) { outputStream.close(); } } }