Skip to content

Commit d048c6a

Browse files
S1artiemagreenblatt
authored andcommitted
Added support for new CefResourceHandler API
This upgrades the JCEF wrapper classes for CefResourceHandler to also include the newer Open/Skip/Read API. The new API methods have been added in addition to the old ProcessRequest/ReadResponse methods in the same way as this was done in the original CEF interface, thereby allowing for the same backwards compatibility to be provided by default, while enabling JCEF-based applications to use the new API in order to implement features that the old API doesn't allow for, such as correct handling of Range requests.
1 parent 1695c32 commit d048c6a

22 files changed

+565
-14
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.callback;
6+
7+
/**
8+
* Callback interface used for asynchronous resource reading.
9+
*/
10+
public interface CefResourceReadCallback {
11+
/**
12+
* Callback for asynchronous continuation of Read(). If |bytes_read| == 0
13+
* the response will be considered complete. If |bytes_read| > 0 then Read()
14+
* will be called again until the request is complete (based on either the
15+
* result or the expected content length). If |bytes_read| < 0 then the
16+
* request will fail and the |bytes_read| value will be treated as the error
17+
* code.
18+
*/
19+
void Continue(int bytes_read);
20+
21+
/**
22+
* Returns the byte buffer to write data into before calling #Continue(int).
23+
*/
24+
public byte[] getBuffer();
25+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.callback;
6+
7+
class CefResourceReadCallback_N extends CefNativeAdapter implements CefResourceReadCallback {
8+
// The native buffer where to copy the data to.
9+
private long N_NativeBufferRef;
10+
11+
// The Java buffer which the application is expected to fill with data.
12+
private byte[] N_JavaBuffer;
13+
14+
CefResourceReadCallback_N() {}
15+
16+
@Override
17+
protected void finalize() throws Throwable {
18+
super.finalize();
19+
}
20+
21+
public void setBufferRefs(long nativeBufferRef, byte[] javaBuffer) {
22+
N_NativeBufferRef = nativeBufferRef;
23+
N_JavaBuffer = javaBuffer;
24+
}
25+
26+
@Override
27+
public byte[] getBuffer() {
28+
return N_JavaBuffer;
29+
}
30+
31+
@Override
32+
public void Continue(int bytes_read) {
33+
try {
34+
if (N_NativeBufferRef != 0 && N_JavaBuffer != null) {
35+
N_Continue(getNativeRef(null), bytes_read, N_NativeBufferRef, N_JavaBuffer);
36+
N_NativeBufferRef = 0;
37+
N_JavaBuffer = null;
38+
}
39+
} catch (UnsatisfiedLinkError ule) {
40+
ule.printStackTrace();
41+
}
42+
}
43+
44+
private final native void N_Continue(
45+
long self, int bytes_read, long nativeBufferRef, byte[] javaBuffer);
46+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.callback;
6+
7+
/**
8+
* Callback interface used for asynchronous resource skipping.
9+
*/
10+
public interface CefResourceSkipCallback {
11+
/**
12+
* Callback for asynchronous continuation of Skip(). If |bytes_skipped| > 0
13+
* then either Skip() will be called again until the requested number of
14+
* bytes have been skipped or the request will proceed. If |bytes_skipped|
15+
* <= 0 the request will fail with ERR_REQUEST_RANGE_NOT_SATISFIABLE.
16+
*/
17+
void Continue(long bytes_skipped);
18+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.callback;
6+
7+
class CefResourceSkipCallback_N extends CefNativeAdapter implements CefResourceSkipCallback {
8+
CefResourceSkipCallback_N() {}
9+
10+
@Override
11+
protected void finalize() throws Throwable {
12+
super.finalize();
13+
}
14+
15+
@Override
16+
public void Continue(long bytes_skipped) {
17+
try {
18+
N_Continue(getNativeRef(null), bytes_skipped);
19+
} catch (UnsatisfiedLinkError ule) {
20+
ule.printStackTrace();
21+
}
22+
}
23+
24+
private final native void N_Continue(long self, long bytes_skipped);
25+
}

java/org/cef/handler/CefResourceHandler.java

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@
55
package org.cef.handler;
66

77
import org.cef.callback.CefCallback;
8+
import org.cef.callback.CefResourceReadCallback;
9+
import org.cef.callback.CefResourceSkipCallback;
10+
import org.cef.misc.BoolRef;
811
import org.cef.misc.IntRef;
12+
import org.cef.misc.LongRef;
913
import org.cef.misc.StringRef;
1014
import org.cef.network.CefCookie;
1115
import org.cef.network.CefRequest;
1216
import org.cef.network.CefResponse;
1317

1418
/**
15-
* Implement this interface to handle custom resource requests. The methods of
16-
* this class will always be called on the IO thread.
19+
* Implement this interface to handle custom resource requests. This interface is a "new" API and an
20+
* old API in one: the deprecated methods are part of the old API. The new API allows for parallel
21+
* processing of requests, because it does not channel all reads through a dedicated IO thread, and
22+
* it allows for skipping of bytes as part of handling Range requests.
1723
*/
1824
public interface CefResourceHandler {
1925
/**
@@ -23,9 +29,22 @@ public interface CefResourceHandler {
2329
* @param callback Callback to continue or cancel the request.
2430
* @return True to handle the request and call CefCallback.Continue() once the response header
2531
* information is available.
32+
* @deprecated Use open() instead
2633
*/
2734
boolean processRequest(CefRequest request, CefCallback callback);
2835

36+
/**
37+
* Open the response stream. This and related (getResponseHeaders, read, skip) methods will be
38+
* called in sequence but not from a dedicated thread. <p> For backwards compatibility set
39+
* |handleRequest| to false and return false and the processRequest() method will be called.
40+
* @param request The request itself. Cannot be modified in this callback. Instance only valid
41+
* within the scope of this method.
42+
* @param handleRequest Set to true to handle/cancel the request immediately
43+
* @param callback Callback to continue or cancel the request at a later time
44+
* @return True to handle the request
45+
*/
46+
boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback);
47+
2948
/**
3049
* Retrieve response header information. If the response length is not known set
3150
* |responseLength| to -1 and readResponse() will be called until it returns false. If the
@@ -49,9 +68,41 @@ public interface CefResourceHandler {
4968
* @param bytesRead Number of bytes written to the buffer.
5069
* @param callback Callback to execute if data will be available asynchronously.
5170
* @return True if more data is or will be available.
71+
* @deprecated Use read() instead
5272
*/
5373
boolean readResponse(byte[] dataOut, int bytesToRead, IntRef bytesRead, CefCallback callback);
5474

75+
/**
76+
* Read response data. If data is available immediately copy up to |bytesToRead| bytes into
77+
* |dataOut|, set |bytesRead| to the number of bytes copied, and return true. To read the data
78+
* at a later time store |dataOut|, set |bytesRead| to 0, return true and call the callback when
79+
* the data is available. To indicate response completion set |bytesRead| to 0 and return false.
80+
* To indicate failure set |bytesRead| to <0 (e.g. -2 for ERR_FAILED) and return false. <p> For
81+
* backwards compatibility set |bytesRead| to -1 and return false and the readResponse() method
82+
* will be called.
83+
* @param dataOut Write data to this buffer. Buffer remains valid until either an immediate
84+
* response is delivered (return true) or the callback is called later when data is
85+
* available (return false).
86+
* @param bytesToRead Size of the buffer.
87+
* @param bytesRead Number of bytes written to the buffer.
88+
* @param callback Callback to execute if data will be available asynchronously.
89+
* @return True if more data is or will be available.
90+
*/
91+
boolean read(
92+
byte[] dataOut, int bytesToRead, IntRef bytesRead, CefResourceReadCallback callback);
93+
94+
/**
95+
* Skip response data when requested by a Range header. Skip over and discard |bytesToSkip|
96+
* bytes of response data. If data is available immediately set |bytesSkipped| to the number of
97+
* bytes skipped and return true. To read the data at a later time set |bytesSkipped| to 0,
98+
* return true and execute |callback| when the data is available. To indicate failure set
99+
* |bytesSkipped| to < 0 (e.g. -2 for ERR_FAILED) and return false.
100+
* @param bytesToSkip Number of bytes to skip.
101+
* @param bytesSkipped Number of bytes skipped.
102+
* @param callback Callback to execute if data will be skipped asynchronously.
103+
*/
104+
boolean skip(long bytesToSkip, LongRef bytesSkipped, CefResourceSkipCallback callback);
105+
55106
/**
56107
* Request processing has been canceled.
57108
*/

java/org/cef/handler/CefResourceHandlerAdapter.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
package org.cef.handler;
66

77
import org.cef.callback.CefCallback;
8+
import org.cef.callback.CefResourceReadCallback;
9+
import org.cef.callback.CefResourceSkipCallback;
10+
import org.cef.misc.BoolRef;
811
import org.cef.misc.IntRef;
12+
import org.cef.misc.LongRef;
913
import org.cef.misc.StringRef;
1014
import org.cef.network.CefCookie;
1115
import org.cef.network.CefRequest;
@@ -22,6 +26,13 @@ public boolean processRequest(CefRequest request, CefCallback callback) {
2226
return false;
2327
}
2428

29+
@Override
30+
public boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback) {
31+
// Enables backwards compatibility by default by calling processRequest.
32+
handleRequest.set(false);
33+
return false;
34+
}
35+
2536
@Override
2637
public void getResponseHeaders(
2738
CefResponse response, IntRef responseLength, StringRef redirectUrl) {}
@@ -32,6 +43,20 @@ public boolean readResponse(
3243
return false;
3344
}
3445

46+
@Override
47+
public boolean read(
48+
byte[] dataOut, int bytesToRead, IntRef bytesRead, CefResourceReadCallback callback) {
49+
// Enables backwards compatibility by default by calling readResponse.
50+
bytesRead.set(-1);
51+
return false;
52+
}
53+
54+
@Override
55+
public boolean skip(long bytesToSkip, LongRef bytesSkipped, CefResourceSkipCallback callback) {
56+
bytesSkipped.set(-2);
57+
return false;
58+
}
59+
3560
@Override
3661
public void cancel() {}
3762
}

java/org/cef/misc/LongRef.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.misc;
6+
7+
/**
8+
* Helper class for passing long values by reference.
9+
*/
10+
public class LongRef {
11+
private long value_;
12+
13+
public LongRef() {}
14+
15+
public LongRef(long value) {
16+
value_ = value;
17+
}
18+
19+
public void set(long value) {
20+
value_ = value;
21+
}
22+
23+
public long get() {
24+
return value_;
25+
}
26+
}

java/tests/detailed/handler/ClientSchemeHandler.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
package tests.detailed.handler;
66

77
import org.cef.callback.CefCallback;
8+
import org.cef.callback.CefResourceReadCallback;
89
import org.cef.handler.CefResourceHandlerAdapter;
10+
import org.cef.misc.BoolRef;
911
import org.cef.misc.IntRef;
1012
import org.cef.misc.StringRef;
1113
import org.cef.network.CefRequest;
@@ -33,7 +35,8 @@ public ClientSchemeHandler() {
3335
}
3436

3537
@Override
36-
public synchronized boolean processRequest(CefRequest request, CefCallback callback) {
38+
public synchronized boolean open(
39+
CefRequest request, BoolRef handleRequest, CefCallback callback) {
3740
boolean handled = false;
3841
String url = request.getURL();
3942
if (url.indexOf("handler.html") != -1) {
@@ -77,9 +80,10 @@ public synchronized boolean processRequest(CefRequest request, CefCallback callb
7780
}
7881
}
7982

83+
// All requests are handled immediately
84+
handleRequest.set(true);
85+
8086
if (handled) {
81-
// Indicate the headers are available.
82-
callback.Continue();
8387
return true;
8488
}
8589

@@ -97,8 +101,8 @@ public void getResponseHeaders(
97101
}
98102

99103
@Override
100-
public synchronized boolean readResponse(
101-
byte[] data_out, int bytes_to_read, IntRef bytes_read, CefCallback callback) {
104+
public synchronized boolean read(byte[] data_out, int bytes_to_read, IntRef bytes_read,
105+
CefResourceReadCallback callback) {
102106
boolean has_data = false;
103107

104108
if (offset_ < data_.length) {

java/tests/detailed/handler/ResourceHandler.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package tests.detailed.handler;
22

33
import org.cef.callback.CefCallback;
4+
import org.cef.callback.CefResourceReadCallback;
45
import org.cef.handler.CefLoadHandler;
56
import org.cef.handler.CefResourceHandlerAdapter;
7+
import org.cef.misc.BoolRef;
68
import org.cef.misc.IntRef;
79
import org.cef.misc.StringRef;
810
import org.cef.network.CefRequest;
@@ -25,11 +27,11 @@ public class ResourceHandler extends CefResourceHandlerAdapter {
2527
+ "</html>");
2628

2729
@Override
28-
public boolean processRequest(CefRequest request, CefCallback callback) {
30+
public boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback) {
2931
System.out.println("processRequest: " + request);
3032

3133
startPos = 0;
32-
callback.Continue();
34+
handleRequest.set(true);
3335
return true;
3436
}
3537

@@ -44,8 +46,8 @@ public void getResponseHeaders(
4446
}
4547

4648
@Override
47-
public boolean readResponse(
48-
byte[] data_out, int bytes_to_read, IntRef bytes_read, CefCallback callback) {
49+
public boolean read(byte[] data_out, int bytes_to_read, IntRef bytes_read,
50+
CefResourceReadCallback callback) {
4951
int length = html.length();
5052
if (startPos >= length) return false;
5153

java/tests/detailed/handler/ResourceSetErrorHandler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
import org.cef.callback.CefCallback;
44
import org.cef.handler.CefLoadHandler.ErrorCode;
55
import org.cef.handler.CefResourceHandlerAdapter;
6+
import org.cef.misc.BoolRef;
67
import org.cef.misc.IntRef;
78
import org.cef.misc.StringRef;
89
import org.cef.network.CefRequest;
910
import org.cef.network.CefResponse;
1011

1112
public class ResourceSetErrorHandler extends CefResourceHandlerAdapter {
1213
@Override
13-
public boolean processRequest(CefRequest request, CefCallback callback) {
14+
public boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback) {
1415
System.out.println("processRequest: " + request);
15-
callback.Continue();
16+
handleRequest.set(true);
1617
return true;
1718
}
1819

0 commit comments

Comments
 (0)