Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion java/org/cef/CefClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import org.cef.callback.CefDragData;
import org.cef.callback.CefFileDialogCallback;
import org.cef.callback.CefJSDialogCallback;
import org.cef.callback.CefMediaAccessCallback;
import org.cef.callback.CefMenuModel;
import org.cef.callback.CefPermissionPromptCallback;
import org.cef.callback.CefPrintDialogCallback;
import org.cef.callback.CefPrintJobCallback;
import org.cef.handler.CefClientHandler;
Expand All @@ -30,6 +32,7 @@
import org.cef.handler.CefKeyboardHandler;
import org.cef.handler.CefLifeSpanHandler;
import org.cef.handler.CefLoadHandler;
import org.cef.handler.CefPermissionHandler;
import org.cef.handler.CefPrintHandler;
import org.cef.handler.CefRenderHandler;
import org.cef.handler.CefRequestHandler;
Expand Down Expand Up @@ -70,7 +73,8 @@ public class CefClient extends CefClientHandler
implements CefContextMenuHandler, CefDialogHandler, CefDisplayHandler, CefDownloadHandler,
CefDragHandler, CefFindHandler, CefFocusHandler, CefFrameHandler,
CefJSDialogHandler, CefKeyboardHandler, CefLifeSpanHandler, CefLoadHandler,
CefPrintHandler, CefRenderHandler, CefRequestHandler, CefWindowHandler {
CefPermissionHandler, CefPrintHandler, CefRenderHandler, CefRequestHandler,
CefWindowHandler {
private HashMap<Integer, CefBrowser> browser_ = new HashMap<Integer, CefBrowser>();
private CefContextMenuHandler contextMenuHandler_ = null;
private CefDialogHandler dialogHandler_ = null;
Expand All @@ -84,6 +88,7 @@ public class CefClient extends CefClientHandler
private CefKeyboardHandler keyboardHandler_ = null;
private CefLifeSpanHandler lifeSpanHandler_ = null;
private CefLoadHandler loadHandler_ = null;
private CefPermissionHandler permissionHandler_ = null;
private CefPrintHandler printHandler_ = null;
private CefRequestHandler requestHandler_ = null;
private boolean isDisposed_ = false;
Expand Down Expand Up @@ -239,6 +244,11 @@ protected CefLoadHandler getLoadHandler() {
return this;
}

@Override
protected CefPermissionHandler getPermissionHandler() {
return this;
}

@Override
protected CefPrintHandler getPrintHandler() {
return this;
Expand Down Expand Up @@ -718,6 +728,7 @@ private void cleanupBrowser(int identifier) {
removeKeyboardHandler(this);
removeLifeSpanHandler(this);
removeLoadHandler(this);
removePermissionHandler(this);
removePrintHandler(this);
removeRenderHandler(this);
removeRequestHandler(this);
Expand Down Expand Up @@ -766,6 +777,43 @@ public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode,
loadHandler_.onLoadError(browser, frame, errorCode, errorText, failedUrl);
}

// CefPermissionHandler

public CefClient addPermissionHandler(CefPermissionHandler handler) {
if (permissionHandler_ == null) permissionHandler_ = handler;
return this;
}

public void removePermissionHandler() {
permissionHandler_ = null;
}

@Override
public boolean onRequestMediaAccessPermission(CefBrowser browser, CefFrame frame,
String requestingOrigin, int requestedPermissions,
CefMediaAccessCallback callback) {
if (permissionHandler_ != null && browser != null)
return permissionHandler_.onRequestMediaAccessPermission(
browser, frame, requestingOrigin, requestedPermissions, callback);
return false;
}

@Override
public boolean onShowPermissionPrompt(CefBrowser browser, long promptId,
String requestingOrigin, int requestedPermissions,
CefPermissionPromptCallback callback) {
if (permissionHandler_ != null && browser != null)
return permissionHandler_.onShowPermissionPrompt(
browser, promptId, requestingOrigin, requestedPermissions, callback);
return false;
}

@Override
public void onDismissPermissionPrompt(CefBrowser browser, long promptId, int result) {
if (permissionHandler_ != null && browser != null)
permissionHandler_.onDismissPermissionPrompt(browser, promptId, result);
}

// CefPrintHandler

public CefClient addPrintHandler(CefPrintHandler handler) {
Expand Down
28 changes: 28 additions & 0 deletions java/org/cef/callback/CefMediaAccessCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2026 The Chromium Embedded Framework 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.cef.callback;

/**
* Callback interface used for asynchronous continuation of media access
* permission requests.
*/
public interface CefMediaAccessCallback {
/**
* Call to allow or deny media access. If this callback was initiated in
* response to a getUserMedia request then allowedPermissions must match
* the requestedPermissions passed to
* CefPermissionHandler.onRequestMediaAccessPermission. See
* CefPermissionHandler.MediaAccessPermissionType for the supported bit
* flags.
*
* @param allowedPermissions the permissions to allow.
*/
public void Continue(int allowedPermissions);

/**
* Cancel the media access request.
*/
public void Cancel();
}
36 changes: 36 additions & 0 deletions java/org/cef/callback/CefMediaAccessCallback_N.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2026 The Chromium Embedded Framework 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.cef.callback;

class CefMediaAccessCallback_N extends CefNativeAdapter implements CefMediaAccessCallback {
CefMediaAccessCallback_N() {}

@Override
protected void finalize() throws Throwable {
Cancel();
super.finalize();
}

@Override
public void Continue(int allowedPermissions) {
try {
N_Continue(getNativeRef(null), allowedPermissions);
} catch (UnsatisfiedLinkError ule) {
ule.printStackTrace();
}
}

@Override
public void Cancel() {
try {
N_Cancel(getNativeRef(null));
} catch (UnsatisfiedLinkError ule) {
ule.printStackTrace();
}
}

private final native void N_Continue(long self, int allowedPermissions);
private final native void N_Cancel(long self);
}
20 changes: 20 additions & 0 deletions java/org/cef/callback/CefPermissionPromptCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2026 The Chromium Embedded Framework 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.cef.callback;

/**
* Callback interface used for asynchronous continuation of permission
* prompts.
*/
public interface CefPermissionPromptCallback {
/**
* Complete the permissions request with the specified result. See
* CefPermissionHandler.PermissionRequestResult for the supported
* values.
*
* @param result the result to complete the request with.
*/
public void Continue(int result);
}
29 changes: 29 additions & 0 deletions java/org/cef/callback/CefPermissionPromptCallback_N.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2026 The Chromium Embedded Framework 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.cef.callback;

import org.cef.handler.CefPermissionHandler;

class CefPermissionPromptCallback_N
extends CefNativeAdapter implements CefPermissionPromptCallback {
CefPermissionPromptCallback_N() {}

@Override
protected void finalize() throws Throwable {
Continue(CefPermissionHandler.PermissionRequestResult.IGNORE);
super.finalize();
}

@Override
public void Continue(int result) {
try {
N_Continue(getNativeRef(null), result);
} catch (UnsatisfiedLinkError ule) {
ule.printStackTrace();
}
}

private final native void N_Continue(long self, int result);
}
16 changes: 16 additions & 0 deletions java/org/cef/handler/CefClientHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ protected void dispose() {
*/
abstract protected CefLoadHandler getLoadHandler();

/**
* Return the handler for permission requests.
* This method is a callback method and is called by
* the native code.
*/
abstract protected CefPermissionHandler getPermissionHandler();

/**
* Return the handler for printing on Linux. If a print handler is not
* provided then printing will not be supported on the Linux platform.
Expand Down Expand Up @@ -313,6 +320,14 @@ protected void removeLoadHandler(CefLoadHandler h) {
}
}

protected void removePermissionHandler(CefPermissionHandler h) {
try {
N_removePermissionHandler(h);
} catch (UnsatisfiedLinkError err) {
err.printStackTrace();
}
}

protected void removePrintHandler(CefPrintHandler h) {
try {
N_removePrintHandler(h);
Expand Down Expand Up @@ -368,6 +383,7 @@ protected void removeWindowHandler(CefWindowHandler h) {
private final native void N_removeKeyboardHandler(CefKeyboardHandler h);
private final native void N_removeLifeSpanHandler(CefLifeSpanHandler h);
private final native void N_removeLoadHandler(CefLoadHandler h);
private final native void N_removePermissionHandler(CefPermissionHandler h);
private final native void N_removePrintHandler(CefPrintHandler h);
private final native void N_removeMessageRouter(CefMessageRouter h);
private final native void N_removeRenderHandler(CefRenderHandler h);
Expand Down
89 changes: 89 additions & 0 deletions java/org/cef/handler/CefPermissionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2026 The Chromium Embedded Framework 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.cef.handler;

import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.callback.CefMediaAccessCallback;
import org.cef.callback.CefPermissionPromptCallback;

/**
* Implement this interface to handle events related to permission requests.
* The methods of this class will be called on the browser process UI thread.
*/
public interface CefPermissionHandler {
/**
* Media access permissions used by onRequestMediaAccessPermission.
*/
public static final class MediaAccessPermissionType {
public final static int PERMISSION_NONE = 0;
public final static int PERMISSION_DEVICE_AUDIO_CAPTURE = 1 << 0;
public final static int PERMISSION_DEVICE_VIDEO_CAPTURE = 1 << 1;
public final static int PERMISSION_DESKTOP_AUDIO_CAPTURE = 1 << 2;
public final static int PERMISSION_DESKTOP_VIDEO_CAPTURE = 1 << 3;
}

/**
* Permission request results used by onDismissPermissionPrompt and
* CefPermissionPromptCallback.Continue.
*/
public static final class PermissionRequestResult {
/** Accept the permission request as an explicit user action. */
public final static int ACCEPT = 0;
/** Deny the permission request as an explicit user action. */
public final static int DENY = 1;
/** Dismiss the permission request as an explicit user action. */
public final static int DISMISS = 2;
/** Ignore the permission request. */
public final static int IGNORE = 3;
}

/**
* Called when a page requests permission to access media.
*
* @param browser The corresponding browser.
* @param frame The corresponding frame.
* @param requestingOrigin the URL origin requesting permission.
* @param requestedPermissions a combination of values from
* MediaAccessPermissionType that represent the requested permissions.
* @param callback execute callback methods either in this method or at
* a later time to continue or cancel the request.
* @return true to handle the request, or false to proceed with default
* handling (deny the request).
*/
public boolean onRequestMediaAccessPermission(CefBrowser browser, CefFrame frame,
String requestingOrigin, int requestedPermissions,
CefMediaAccessCallback callback);

/**
* Called when a page should show a permission prompt.
*
* @param browser The corresponding browser.
* @param promptId uniquely identifies the prompt.
* @param requestingOrigin the URL origin requesting permission.
* @param requestedPermissions a combination of CEF_PERMISSION_TYPE_*
* values (see cef_permission_request_types_t in CEF's cef_types.h) that
* represent the requested permissions.
* @param callback call Continue either in this method or at a later
* time to continue or cancel the request.
* @return true to handle the request, or false to proceed with default
* handling (CEF_PERMISSION_RESULT_IGNORE with Alloy style).
*/
public boolean onShowPermissionPrompt(CefBrowser browser, long promptId,
String requestingOrigin, int requestedPermissions,
CefPermissionPromptCallback callback);

/**
* Called when a permission prompt handled via onShowPermissionPrompt is
* dismissed. promptId will match the value that was passed to
* onShowPermissionPrompt. This method will not be called if
* onShowPermissionPrompt returned false for promptId.
*
* @param browser The corresponding browser.
* @param promptId uniquely identifies the prompt.
* @param result one of the PermissionRequestResult values.
*/
public void onDismissPermissionPrompt(CefBrowser browser, long promptId, int result);
}
34 changes: 34 additions & 0 deletions java/org/cef/handler/CefPermissionHandlerAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2026 The Chromium Embedded Framework 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.cef.handler;

import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.callback.CefMediaAccessCallback;
import org.cef.callback.CefPermissionPromptCallback;

/**
* An abstract adapter class for receiving permission events.
* The methods in this class are empty.
* This class exists as convenience for creating handler objects.
*/
public abstract class CefPermissionHandlerAdapter implements CefPermissionHandler {
@Override
public boolean onRequestMediaAccessPermission(CefBrowser browser, CefFrame frame,
String requestingOrigin, int requestedPermissions,
CefMediaAccessCallback callback) {
return false;
}

@Override
public boolean onShowPermissionPrompt(CefBrowser browser, long promptId,
String requestingOrigin, int requestedPermissions,
CefPermissionPromptCallback callback) {
return false;
}

@Override
public void onDismissPermissionPrompt(CefBrowser browser, long promptId, int result) {}
}
3 changes: 3 additions & 0 deletions java/tests/junittests/CefClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ void addAndRemoveEveryHandlerType() {
client.addLoadHandler(new CefLoadHandlerAdapter() {});
client.removeLoadHandler();

client.addPermissionHandler(new org.cef.handler.CefPermissionHandlerAdapter() {});
client.removePermissionHandler();

client.addPrintHandler(new CefPrintHandlerAdapter() {});
client.removePrintHandler();

Expand Down
Loading
Loading