text: /*
         Licensed to the Apache Software Foundation (ASF) under one
         or more contributor license agreements.  See the NOTICE file
         distributed with this work for additional information
         regarding copyright ownership.  The ASF licenses this file
         to you under the Apache License, Version 2.0 (the
         "License"); you may not use this file except in compliance
         with the License.  You may obtain a copy of the License at
  
           http://www.apache.org/licenses/LICENSE-2.0
  
         Unless required by applicable law or agreed to in writing,
         software distributed under the License is distributed on an
         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
         KIND, either express or implied.  See the License for the
         specific language governing permissions and limitations
         under the License.
  */
  package org.crosswalk.engine;
  
  import android.content.pm.ApplicationInfo;
  import android.content.pm.PackageManager;
  import android.net.Uri;
  import android.net.http.SslError;
  import android.webkit.ValueCallback;
  import android.webkit.WebResourceResponse;
  
  import org.apache.cordova.CordovaResourceApi;
  import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
  import org.apache.cordova.LOG;
  import org.apache.cordova.PluginManager;
  import org.xwalk.core.ClientCertRequest;
  import org.xwalk.core.XWalkHttpAuthHandler;
  import org.xwalk.core.XWalkResourceClient;
  import org.xwalk.core.XWalkView;
  
  import java.io.FileNotFoundException;
  import java.io.IOException;
  
  public class XWalkCordovaResourceClient extends XWalkResourceClient {
  
  	private static final String TAG = "XWalkCordovaResourceClient";
      protected XWalkWebViewEngine parentEngine;
  
      public XWalkCordovaResourceClient(XWalkWebViewEngine parentEngine) {
          super(parentEngine.webView);
          this.parentEngine = parentEngine;
      }
  
      /**
      * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable).
      * The errorCode parameter corresponds to one of the ERROR_* constants.
      *
      * @param view          The WebView that is initiating the callback.
      * @param errorCode     The error code corresponding to an ERROR_* value.
      * @param description   A String describing the error.
      * @param failingUrl    The url that failed to load.
      */
      @Override
      public void onReceivedLoadError(XWalkView view, int errorCode, String description,
             String failingUrl) {
          LOG.d(TAG, "CordovaWebViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl);
  
          parentEngine.client.onReceivedError(errorCode, description, failingUrl);
      }
  
      @Override
      public WebResourceResponse shouldInterceptLoadRequest(XWalkView view, String url) {
          try {
              // Check the against the white-list.
              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)) {
                  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);
          }
      }
  
      @Override
      public boolean shouldOverrideUrlLoading(XWalkView view, String url) {
          return parentEngine.client.onNavigationAttempt(url);
      }
  
  
      /**
      * Notify the host application that an SSL error occurred while loading a
      * resource. The host application must call either callback.onReceiveValue(true)
      * or callback.onReceiveValue(false). Note that the decision may be
      * retained for use in response to future SSL errors. The default behavior
      * is to pop up a dialog.
      */
      @Override
      public void onReceivedSslError(XWalkView view, ValueCallback<Boolean> callback, SslError error) {
          final String packageName = parentEngine.cordova.getActivity().getPackageName();
          final PackageManager pm = parentEngine.cordova.getActivity().getPackageManager();
  
          ApplicationInfo appInfo;
          try {
              appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
              if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                  // debug = true
                  callback.onReceiveValue(true);
              } else {
                  // debug = false
                  callback.onReceiveValue(false);
              }
          } catch (PackageManager.NameNotFoundException e) {
              // When it doubt, lock it out!
              callback.onReceiveValue(false);
          }
      }
  
      @Override
      public void onReceivedHttpAuthRequest(XWalkView view, XWalkHttpAuthHandler handler,
              String host, String realm) {
          // Check if there is some plugin which can resolve this auth challenge
          PluginManager pluginManager = parentEngine.pluginManager;
          if (pluginManager != null && pluginManager.onReceivedHttpAuthRequest(
                  parentEngine.parentWebView,
                  new XWalkCordovaHttpAuthHandler(handler), host, realm)) {
              parentEngine.client.clearLoadTimeoutTimer();
              return;
          }
  
          // By default handle 401 like we'd normally do!
          super.onReceivedHttpAuthRequest(view, handler, host, realm);
      }
  
      @Override
      public void onReceivedClientCertRequest(XWalkView view, ClientCertRequest request) {
          // Check if there is some plugin which can resolve this certificate request
          PluginManager pluginManager = parentEngine.pluginManager;
          if (pluginManager != null && pluginManager.onReceivedClientCertRequest(
                  parentEngine.parentWebView, new XWalkCordovaClientCertRequest(request))) {
              parentEngine.client.clearLoadTimeoutTimer();
              return;
          }
  
          super.onReceivedClientCertRequest(view, request);
      }
  }
  