Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[Android] Upgrade shouldInterceptLoadRequest API
Browse files Browse the repository at this point in the history
As current shouldInterceptLoadRequest misses lots of important context,
shouldInterceptLoadRequest need to be upgraded to Android L style.
To keep the backward compatibility, the old API still be usable.

So this commit adds the following to shouldInterceptLoadRequest params:
 - isMainFrame
 - hasUserGesture
 - method
 - request headers

And use WebResourceResponse to replace InterceptedRequestData, adds the
following:
 - status code
 - response phrase
 - response headers

The advantage of this implemention compared to android_webview is that it's
independent of the android sdk version, which means all the Crosswalk support
android verisons based application can use the new shouldInterceptLoadRequest
to get the newly added context.

BUG=XWALK-3934, XWALK-4255
  • Loading branch information
xzhan96 committed Nov 16, 2015
1 parent efbd75e commit 9d416af
Show file tree
Hide file tree
Showing 35 changed files with 1,019 additions and 432 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ public void setOnTouchListener(OnTouchListener l) {
}

//--------------------------------------------------------------------------------------------
private class XWalkIoThreadClientImpl implements XWalkContentsIoThreadClient {
private class XWalkIoThreadClientImpl extends XWalkContentsIoThreadClient {
// All methods are called on the IO thread.

@Override
Expand All @@ -674,28 +674,25 @@ public int getCacheMode() {
}

@Override
public InterceptedRequestData shouldInterceptRequest(final String url,
boolean isMainFrame) {
public XWalkWebResourceResponseInternal shouldInterceptRequest(
XWalkContentsClient.WebResourceRequestInner request) {

// Notify a resource load is started. This is not the best place to start the callback
// but it's a workable way.
mContentsClientBridge.getCallbackHelper().postOnResourceLoadStarted(url);
mContentsClientBridge.getCallbackHelper().postOnResourceLoadStarted(request.url);

WebResourceResponse webResourceResponse = mContentsClientBridge.shouldInterceptRequest(url);
InterceptedRequestData interceptedRequestData = null;
XWalkWebResourceResponseInternal xwalkWebResourceResponse =
mContentsClientBridge.shouldInterceptRequest(request);

if (webResourceResponse == null) {
mContentsClientBridge.getCallbackHelper().postOnLoadResource(url);
if (xwalkWebResourceResponse == null) {
mContentsClientBridge.getCallbackHelper().postOnLoadResource(request.url);
} else {
if (isMainFrame && webResourceResponse.getData() == null) {
if (request.isMainFrame && xwalkWebResourceResponse.getData() == null) {
mContentsClientBridge.getCallbackHelper().postOnReceivedError(
XWalkResourceClientInternal.ERROR_UNKNOWN, null, url);
XWalkResourceClientInternal.ERROR_UNKNOWN, null, request.url);
}
interceptedRequestData = new InterceptedRequestData(webResourceResponse.getMimeType(),
webResourceResponse.getEncoding(),
webResourceResponse.getData());
}
return interceptedRequestData;
return xwalkWebResourceResponse;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
import android.view.View;
import android.webkit.ConsoleMessage;
import android.webkit.ValueCallback;
import android.webkit.WebResourceResponse;

import java.security.KeyStore.PrivateKeyEntry;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;

import org.chromium.content.browser.ContentViewClient;
import org.chromium.content_public.browser.WebContents;
Expand Down Expand Up @@ -133,16 +133,32 @@ final XWalkContentsClientCallbackHelper getCallbackHelper() {
}

//--------------------------------------------------------------------------------------------
// XWalkViewInternal specific methods that map directly to XWalkViewClient / XWalkWebChromeClient
// XWalkViewInternal specific methods that map directly to XWalkViewClient/XWalkWebChromeClient
//--------------------------------------------------------------------------------------------

/**
* Parameters for the {@link XWalkContentsClient#shouldInterceptRequest} method.
*/
public static class WebResourceRequestInner {
// Url of the request.
public String url;
// Is this for the main frame or a child iframe?
public boolean isMainFrame;
// Was a gesture associated with the request? Don't trust can easily be spoofed.
public boolean hasUserGesture;
// Method used (GET/POST/OPTIONS)
public String method;
// Headers that would have been sent to server.
public HashMap<String, String> requestHeaders;
}
public abstract void getVisitedHistory(ValueCallback<String[]> callback);

public abstract void doUpdateVisitedHistory(String url, boolean isReload);

public abstract void onProgressChanged(int progress);

public abstract WebResourceResponse shouldInterceptRequest(String url);
public abstract XWalkWebResourceResponseInternal shouldInterceptRequest(
WebResourceRequestInner request);

public abstract void onResourceLoadStarted(String url);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

import javax.security.auth.x500.X500Principal;

Expand Down Expand Up @@ -244,9 +247,36 @@ public void onProgressChanged(int progress) {
}

@Override
public WebResourceResponse shouldInterceptRequest(String url) {
public XWalkWebResourceResponseInternal shouldInterceptRequest(
WebResourceRequestInner request) {
if (isOwnerActivityRunning()) {
return mXWalkResourceClient.shouldInterceptLoadRequest(mXWalkView, url);
//For compatibility with the old shouldInterceptLoadRequest.
WebResourceResponse response =
mXWalkResourceClient.shouldInterceptLoadRequest(mXWalkView, request.url);
if (response == null) {
XWalkWebResourceResponseInternal xwalkResponse =
mXWalkResourceClient.shouldInterceptLoadRequest(mXWalkView,
new XWalkWebResourceRequestHandlerInternal(request));
if (xwalkResponse == null) return null;

// XWalkWebResourceResponse should support null headers.
Map<String, String> responseHeaders = xwalkResponse.getResponseHeaders();
if (responseHeaders == null) responseHeaders = new HashMap<String, String>();

//To Investigate: return xwalkResponse directly will fail, don't know why yet.
return new XWalkWebResourceResponseInternal(
xwalkResponse.getMimeType(),
xwalkResponse.getEncoding(),
xwalkResponse.getData(),
xwalkResponse.getStatusCode(),
xwalkResponse.getReasonPhrase(),
responseHeaders);
} else {
return new XWalkWebResourceResponseInternal(
response.getMimeType(),
response.getEncoding(),
response.getData());
}
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,56 @@

package org.xwalk.core.internal;

import java.util.HashMap;

import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;

/**
* Delegate for handling callbacks. All methods are called on the IO thread.
*/
@JNINamespace("xwalk")
interface XWalkContentsIoThreadClient {
public abstract class XWalkContentsIoThreadClient {
@CalledByNative
public int getCacheMode();
public abstract int getCacheMode();

@CalledByNative
public InterceptedRequestData shouldInterceptRequest(String url, boolean isMainFrame);
public abstract boolean shouldBlockContentUrls();

@CalledByNative
public boolean shouldBlockContentUrls();
public abstract boolean shouldBlockFileUrls();

@CalledByNative
public boolean shouldBlockFileUrls();
public abstract boolean shouldBlockNetworkLoads();

@CalledByNative
public boolean shouldBlockNetworkLoads();
public abstract void onDownloadStart(String url,
String userAgent,
String contentDisposition,
String mimeType,
long contentLength);

@CalledByNative
public void onDownloadStart(String url,
String userAgent,
String contentDisposition,
String mimeType,
long contentLength);
public abstract void newLoginRequest(String realm, String account, String args);

public abstract XWalkWebResourceResponseInternal shouldInterceptRequest(
XWalkContentsClient.WebResourceRequestInner request);

// Protected methods ---------------------------------------------------------------------------
@CalledByNative
public void newLoginRequest(String realm, String account, String args);
protected XWalkWebResourceResponseInternal shouldInterceptRequest(String url, boolean isMainFrame,
boolean hasUserGesture, String method, String[] requestHeaderNames,
String[] requestHeaderValues) {
XWalkContentsClient.WebResourceRequestInner request =
new XWalkContentsClient.WebResourceRequestInner();
request.url = url;
request.isMainFrame = isMainFrame;
request.hasUserGesture = hasUserGesture;
request.method = method;
request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
for (int i = 0; i < requestHeaderNames.length; ++i) {
request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
}
return shouldInterceptRequest(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
import android.widget.LinearLayout;
import android.widget.Toast;

import java.io.InputStream;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Map;


/**
* This class notifies the embedder resource events/callbacks.
Expand Down Expand Up @@ -191,13 +194,37 @@ public void onProgressChanged(XWalkViewInternal view, int progressInPercent) {
* @return A {@link android.webkit.WebResourceResponse} containing the
* response information or null if the XWalkViewInternal should load the
* resource itself.
* @deprecated Use
* {@link #shouldInterceptLoadRequest(XWalkViewInternal, XWalkWebResourceRequestInternal)}
* instead.
* @since 1.0
*/
@XWalkAPI
public WebResourceResponse shouldInterceptLoadRequest(XWalkViewInternal view, String url) {
return null;
}

/**
* Notify the client of a resource request and allow the client to return
* the data. If the return value is null, the XWalkViewInternal
* will continue to load the resource as usual. Otherwise, the return
* response and data will be used. NOTE: This method is called by the
* network thread so clients should exercise caution when accessing private
* data.
* @param view The owner XWalkViewInternal instance that is requesting the
* resource.
* @param request Object containing the details of the request..
* @return A {@link org.xwalk.core.XWalkWebResourceResponse} containing the
* response information or null if the XWalkViewInternal should load the
* resource itself.
* @since 6.0
*/
@XWalkAPI
public XWalkWebResourceResponseInternal shouldInterceptLoadRequest(XWalkViewInternal view,
XWalkWebResourceRequestInternal request) {
return null;
}

/**
* Report an error to the client.
* @param view the owner XWalkViewInternal instance.
Expand Down Expand Up @@ -357,4 +384,32 @@ public void onCancel(DialogInterface dialog) {
}
}).create().show();
}

/**
* Construct an instance of XWalkWebResourceResponseInternal
* for application usage.
*
* @return XWalkWebResourceResponseInternal.
* @since 6.0
*/
@XWalkAPI
public XWalkWebResourceResponseInternal createXWalkWebResourceResponse(
String mimeType, String encoding, InputStream data) {
return new XWalkWebResourceResponseInternal(mimeType, encoding, data);
}

/**
* Construct an instance of XWalkWebResourceResponseInternal
* for application usage.
*
* @return XWalkWebResourceResponseInternal.
* @since 6.0
*/
@XWalkAPI
public XWalkWebResourceResponseInternal createXWalkWebResourceResponse(
String mimeType, String encoding, InputStream data, int statusCode,
String reasonPhrase, Map<String, String> responseHeaders) {
return new XWalkWebResourceResponseInternal(
mimeType, encoding, data, statusCode, reasonPhrase, responseHeaders);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.xwalk.core.internal;

import android.net.Uri;

import java.util.Map;

@XWalkAPI(impl = XWalkWebResourceRequestInternal.class, createInternally = true)
public class XWalkWebResourceRequestHandlerInternal implements XWalkWebResourceRequestInternal {
private final XWalkContentsClientBridge.WebResourceRequestInner mRequest;

// Never use this constructor.
// It is only used in WebResourceRequestHandlerBridge.
XWalkWebResourceRequestHandlerInternal() {
mRequest = null;
}

XWalkWebResourceRequestHandlerInternal(
XWalkContentsClientBridge.WebResourceRequestInner request) {
mRequest = request;
}

@XWalkAPI
public Uri getUrl() {
return Uri.parse(mRequest.url);
}

@XWalkAPI
public boolean isForMainFrame() {
return mRequest.isMainFrame;
}

@XWalkAPI
public boolean hasGesture() {
return mRequest.hasUserGesture;
}

@XWalkAPI
public String getMethod() {
return mRequest.method;
}

@XWalkAPI
public Map<String, String> getRequestHeaders() {
return mRequest.requestHeaders;
}
}
Loading

0 comments on commit 9d416af

Please sign in to comment.