Bug 1498721 - Add default methods to GeckoView delegate interfaces r=geckoview-reviewers,agi
authorJames Willcox <snorp@snorp.net>
Tue, 12 Mar 2019 14:19:45 +0000
changeset 521583 3504d6975a6d
parent 521582 7b997d966c3c
child 521584 01aa96181b7b
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgeckoview-reviewers, agi
bugs1498721
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1498721 - Add default methods to GeckoView delegate interfaces r=geckoview-reviewers,agi Differential Revision: https://phabricator.services.mozilla.com/D23016
mobile/android/geckoview/api.txt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -496,17 +496,17 @@ package org.mozilla.geckoview {
   public static interface GeckoSession.PromptDelegate {
     method @android.support.annotation.UiThread public void onAlert(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback);
     method @android.support.annotation.UiThread public void onAuthPrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthOptions, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthCallback);
     method @android.support.annotation.UiThread public void onButtonPrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.ButtonCallback);
     method @android.support.annotation.UiThread public void onChoicePrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, int, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.ChoiceCallback);
     method @android.support.annotation.UiThread public void onColorPrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
     method @android.support.annotation.UiThread public void onDateTimePrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, int, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
     method @android.support.annotation.UiThread public void onFilePrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, int, @android.support.annotation.Nullable java.lang.String[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.FileCallback);
-    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onPopupRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String);
+    method @android.support.annotation.UiThread @android.support.annotation.Nullable public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onPopupRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String);
     method @android.support.annotation.UiThread public void onTextPrompt(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
     field public static final int BUTTON_TYPE_NEGATIVE = 2;
     field public static final int BUTTON_TYPE_NEUTRAL = 1;
     field public static final int BUTTON_TYPE_POSITIVE = 0;
     field public static final int DATETIME_TYPE_DATE = 1;
     field public static final int DATETIME_TYPE_DATETIME_LOCAL = 5;
     field public static final int DATETIME_TYPE_MONTH = 2;
     field public static final int DATETIME_TYPE_TIME = 4;
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
@@ -380,17 +380,17 @@ class GeckoSessionTestRuleTest : BaseSes
         assertThat("Callback count should be correct", counter, equalTo(1))
     }
 
     @Test(expected = AssertionError::class)
     fun forCallbacksDuringWait_throwOnAnyMethodNotCalled() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
-        sessionRule.forCallbacksDuringWait(GeckoSession.ScrollDelegate { _, _, _ -> })
+        sessionRule.forCallbacksDuringWait(object : GeckoSession.ScrollDelegate {})
     }
 
     @Test fun forCallbacksDuringWait_specificMethod() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
         var counter = 0
 
@@ -431,18 +431,21 @@ class GeckoSessionTestRuleTest : BaseSes
         assertThat("Callback count should be correct", counter, equalTo(4))
     }
 
     @Test(expected = AssertionError::class)
     fun forCallbacksDuringWait_throwOnSpecificMethodNotCalled() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
-        sessionRule.forCallbacksDuringWait(
-                GeckoSession.ScrollDelegate @AssertCalled { _, _, _ -> })
+        sessionRule.forCallbacksDuringWait(object : GeckoSession.ScrollDelegate {
+            @AssertCalled
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
     }
 
     @Test fun forCallbacksDuringWait_specificCount() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.session.reload()
         sessionRule.waitForPageStops(2)
 
         var counter = 0
@@ -542,18 +545,21 @@ class GeckoSessionTestRuleTest : BaseSes
             }
         })
     }
 
     @Test fun forCallbacksDuringWait_notCalled() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
-        sessionRule.forCallbacksDuringWait(
-                GeckoSession.ScrollDelegate @AssertCalled(false) { _, _, _ -> })
+        sessionRule.forCallbacksDuringWait(object : GeckoSession.ScrollDelegate {
+            @AssertCalled(false)
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
     }
 
     @Test(expected = AssertionError::class)
     fun forCallbacksDuringWait_throwOnCallingNoCall() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.ProgressDelegate {
@@ -562,18 +568,21 @@ class GeckoSessionTestRuleTest : BaseSes
             }
         })
     }
 
     @Test fun forCallbacksDuringWait_zeroCountEqualsNotCalled() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
-        sessionRule.forCallbacksDuringWait(
-                GeckoSession.ScrollDelegate @AssertCalled(count = 0) { _, _, _ -> })
+        sessionRule.forCallbacksDuringWait(object : GeckoSession.ScrollDelegate {
+            @AssertCalled(count = 0)
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
     }
 
     @Test(expected = AssertionError::class)
     fun forCallbacksDuringWait_throwOnCallingZeroCount() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.ProgressDelegate {
@@ -699,24 +708,30 @@ class GeckoSessionTestRuleTest : BaseSes
 
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
         assertThat("Callback count should be correct", counter, equalTo(2))
     }
 
     @Test fun delegateUntilTestEnd_notCalled() {
-        sessionRule.delegateUntilTestEnd(
-                GeckoSession.ScrollDelegate @AssertCalled(false) { _, _, _ -> })
+        sessionRule.delegateUntilTestEnd(object : GeckoSession.ScrollDelegate {
+            @AssertCalled(false)
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
     }
 
     @Test(expected = AssertionError::class)
     fun delegateUntilTestEnd_throwOnNotCalled() {
-        sessionRule.delegateUntilTestEnd(
-                GeckoSession.ScrollDelegate @AssertCalled(count = 1) { _, _, _ -> })
+        sessionRule.delegateUntilTestEnd(object : GeckoSession.ScrollDelegate {
+            @AssertCalled(count = 1)
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
         sessionRule.performTestEndCheck()
     }
 
     @Test(expected = AssertionError::class)
     fun delegateUntilTestEnd_throwOnCallingNoCall() {
         sessionRule.delegateUntilTestEnd(object : Callbacks.ProgressDelegate {
             @AssertCalled(false)
             override fun onPageStop(session: GeckoSession, success: Boolean) {
@@ -783,26 +798,32 @@ class GeckoSessionTestRuleTest : BaseSes
         sessionRule.session.reload()
         sessionRule.waitForPageStop()
 
         assertThat("Delegate should be cleared", counter, equalTo(2))
     }
 
     @Test(expected = AssertionError::class)
     fun delegateDuringNextWait_throwOnNotCalled() {
-        sessionRule.delegateDuringNextWait(
-                GeckoSession.ScrollDelegate @AssertCalled(count = 1) { _, _, _ -> })
+        sessionRule.delegateDuringNextWait(object : GeckoSession.ScrollDelegate {
+            @AssertCalled(count = 1)
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
     }
 
     @Test(expected = AssertionError::class)
     fun delegateDuringNextWait_throwOnNotCalledAtTestEnd() {
-        sessionRule.delegateDuringNextWait(
-                GeckoSession.ScrollDelegate @AssertCalled(count = 1) { _, _, _ -> })
+        sessionRule.delegateDuringNextWait(object : GeckoSession.ScrollDelegate {
+            @AssertCalled(count = 1)
+            override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
+            }
+        })
         sessionRule.performTestEndCheck()
     }
 
     @Test fun delegateDuringNextWait_hasPrecedence() {
         var testCounter = 0
         var waitCounter = 0
 
         sessionRule.delegateUntilTestEnd(object : Callbacks.ProgressDelegate,
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
@@ -23,176 +23,26 @@ class Callbacks private constructor() {
     object Default : All
 
     interface All : ContentBlockingDelegate, ContentDelegate,
                     HistoryDelegate, MediaDelegate,
                     NavigationDelegate, PermissionDelegate, ProgressDelegate,
                     PromptDelegate, ScrollDelegate, SelectionActionDelegate,
                     TextInputDelegate
 
-    interface ContentDelegate : GeckoSession.ContentDelegate {
-        override fun onTitleChange(session: GeckoSession, title: String?) {
-        }
-
-        override fun onFocusRequest(session: GeckoSession) {
-        }
-
-        override fun onCloseRequest(session: GeckoSession) {
-        }
-
-        override fun onFullScreen(session: GeckoSession, fullScreen: Boolean) {
-        }
-
-        override fun onContextMenu(session: GeckoSession,
-                                   screenX: Int, screenY: Int,
-                                   element: ContextElement) {
-        }
-
-        override fun onExternalResponse(session: GeckoSession, response: GeckoSession.WebResponseInfo) {
-        }
-
-        override fun onCrash(session: GeckoSession) {
-        }
-
-        override fun onFirstComposite(session: GeckoSession) {
-        }
-    }
-
-    interface NavigationDelegate : GeckoSession.NavigationDelegate {
-        override fun onLocationChange(session: GeckoSession, url: String?) {
-        }
-
-        override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) {
-        }
-
-        override fun onCanGoForward(session: GeckoSession, canGoForward: Boolean) {
-        }
-
-        override fun onLoadRequest(session: GeckoSession,
-                                   request: LoadRequest): GeckoResult<AllowOrDeny>? {
-            return null
-        }
-
-        override fun onNewSession(session: GeckoSession, uri: String): GeckoResult<GeckoSession>? {
-            return null
-        }
-
-        override fun onLoadError(session: GeckoSession, uri: String?,
-                                 error: WebRequestError): GeckoResult<String>? {
-            return null
-        }
-    }
-
-    interface PermissionDelegate : GeckoSession.PermissionDelegate {
-        override fun onAndroidPermissionsRequest(
-                session: GeckoSession, permissions: Array<out String>?,
-                callback: GeckoSession.PermissionDelegate.Callback) {
-            callback.reject()
-        }
-
-        override fun onContentPermissionRequest(
-                session: GeckoSession, uri: String?, type: Int,
-                callback: GeckoSession.PermissionDelegate.Callback) {
-            callback.reject()
-        }
-
-        override fun onMediaPermissionRequest(
-                session: GeckoSession, uri: String,
-                video: Array<out GeckoSession.PermissionDelegate.MediaSource>?,
-                audio: Array<out GeckoSession.PermissionDelegate.MediaSource>?,
-                callback: GeckoSession.PermissionDelegate.MediaCallback) {
-            callback.reject()
-        }
-    }
-
-    interface ProgressDelegate : GeckoSession.ProgressDelegate {
-        override fun onPageStart(session: GeckoSession, url: String) {
-        }
-
-        override fun onPageStop(session: GeckoSession, success: Boolean) {
-        }
-
-        override fun onProgressChange(session: GeckoSession, progress: Int) {
-        }
-
-        override fun onSecurityChange(session: GeckoSession, securityInfo: GeckoSession.ProgressDelegate.SecurityInformation) {
-        }
-    }
-
-    interface PromptDelegate : GeckoSession.PromptDelegate {
-        override fun onAlert(session: GeckoSession, title: String?, msg: String?,
-                             callback: GeckoSession.PromptDelegate.AlertCallback) {
-            callback.dismiss()
-        }
-
-        override fun onButtonPrompt(session: GeckoSession, title: String?, msg: String?,
-                                    btnMsg: Array<out String>?,
-                                    callback: GeckoSession.PromptDelegate.ButtonCallback) {
-            callback.dismiss()
-        }
-
-        override fun onTextPrompt(session: GeckoSession, title: String?, msg: String?,
-                                  value: String?,
-                                  callback: GeckoSession.PromptDelegate.TextCallback) {
-            callback.dismiss()
-        }
-
-        override fun onAuthPrompt(session: GeckoSession, title: String?, msg: String?,
-                                  options: GeckoSession.PromptDelegate.AuthOptions,
-                                  callback: GeckoSession.PromptDelegate.AuthCallback) {
-            callback.dismiss()
-        }
-
-        override fun onChoicePrompt(session: GeckoSession, title: String?, msg: String?, type: Int,
-                                    choices: Array<out GeckoSession.PromptDelegate.Choice>,
-                                    callback: GeckoSession.PromptDelegate.ChoiceCallback) {
-            callback.dismiss()
-        }
-
-        override fun onColorPrompt(session: GeckoSession, title: String?, value: String?,
-                                   callback: GeckoSession.PromptDelegate.TextCallback) {
-            callback.dismiss()
-        }
-
-        override fun onDateTimePrompt(session: GeckoSession, title: String?, type: Int,
-                                      value: String?, min: String?, max: String?,
-                                      callback: GeckoSession.PromptDelegate.TextCallback) {
-            callback.dismiss()
-        }
-
-        override fun onFilePrompt(session: GeckoSession, title: String?, type: Int,
-                                  mimeTypes: Array<out String>?,
-                                  callback: GeckoSession.PromptDelegate.FileCallback) {
-            callback.dismiss()
-        }
-
-        override fun onPopupRequest(session: GeckoSession, targetUri: String?)
-                : GeckoResult<AllowOrDeny>? {
-            return null
-        }
-    }
-
-    interface ScrollDelegate : GeckoSession.ScrollDelegate {
-        override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
-        }
-    }
-
-    interface ContentBlockingDelegate : ContentBlocking.Delegate {
-        override fun onContentBlocked(session: GeckoSession,
-                                      event: ContentBlocking.BlockEvent) {
-        }
-    }
-
-    interface SelectionActionDelegate : GeckoSession.SelectionActionDelegate {
-        override fun onShowActionRequest(session: GeckoSession, selection: GeckoSession.SelectionActionDelegate.Selection, actions: Array<out String>, response: GeckoResponse<String>) {
-        }
-
-        override fun onHideAction(session: GeckoSession, reason: Int) {
-        }
-    }
+    interface ContentDelegate : GeckoSession.ContentDelegate {}
+    interface NavigationDelegate : GeckoSession.NavigationDelegate {}
+    interface PermissionDelegate : GeckoSession.PermissionDelegate {}
+    interface ProgressDelegate : GeckoSession.ProgressDelegate {}
+    interface PromptDelegate : GeckoSession.PromptDelegate {}
+    interface ScrollDelegate : GeckoSession.ScrollDelegate {}
+    interface ContentBlockingDelegate : ContentBlocking.Delegate {}
+    interface SelectionActionDelegate : GeckoSession.SelectionActionDelegate {}
+    interface MediaDelegate: GeckoSession.MediaDelegate {}
+    interface HistoryDelegate : GeckoSession.HistoryDelegate {}
 
     interface TextInputDelegate : GeckoSession.TextInputDelegate {
         override fun restartInput(session: GeckoSession, reason: Int) {
         }
 
         override fun showSoftInput(session: GeckoSession) {
         }
 
@@ -206,29 +56,9 @@ class Callbacks private constructor() {
         }
 
         override fun updateCursorAnchorInfo(session: GeckoSession, info: CursorAnchorInfo) {
         }
 
         override fun notifyAutoFill(session: GeckoSession, notification: Int, virtualId: Int) {
         }
     }
-
-    interface MediaDelegate: GeckoSession.MediaDelegate {
-        override fun onMediaAdd(session: GeckoSession, element: MediaElement) {
-        }
-
-        override fun onMediaRemove(session: GeckoSession, element: MediaElement) {
-        }
-    }
-
-    interface HistoryDelegate : GeckoSession.HistoryDelegate {
-        override fun onVisited(session: GeckoSession, url: String, lastVisitedURL: String?,
-                               flags: Int): GeckoResult<Boolean>? {
-            return null
-        }
-
-        override fun getVisited(session: GeckoSession,
-                                urls: Array<out String>): GeckoResult<BooleanArray>? {
-            return null
-        }
-    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java
@@ -368,18 +368,18 @@ public class ContentBlocking {
          * A content element has been blocked from loading.
          * Set blocked element categories via {@link GeckoRuntimeSettings} and
          * enable content blocking via {@link GeckoSessionSettings}.
          *
         * @param session The GeckoSession that initiated the callback.
         * @param event The {@link BlockEvent} details.
         */
         @UiThread
-        void onContentBlocked(@NonNull GeckoSession session,
-                              @NonNull BlockEvent event);
+        default void onContentBlocked(@NonNull GeckoSession session,
+                                      @NonNull BlockEvent event) {}
     }
 
 
     private static final String TEST = "test-track-simple";
     private static final String AD = "ads-track-digest256";
     private static final String ANALYTIC = "analytics-track-digest256";
     private static final String SOCIAL = "social-track-digest256";
     private static final String CONTENT = "content-track-digest256";
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -2523,42 +2523,42 @@ public class GeckoSession implements Par
         }
 
         /**
         * A View has started loading content from the network.
         * @param session GeckoSession that initiated the callback.
         * @param url The resource being loaded.
         */
         @UiThread
-        void onPageStart(@NonNull GeckoSession session, @NonNull String url);
+        default void onPageStart(@NonNull GeckoSession session, @NonNull String url) {}
 
         /**
         * A View has finished loading content from the network.
         * @param session GeckoSession that initiated the callback.
         * @param success Whether the page loaded successfully or an error occurred.
         */
         @UiThread
-        void onPageStop(@NonNull GeckoSession session, boolean success);
+        default void onPageStop(@NonNull GeckoSession session, boolean success) {}
 
         /**
          * Page loading has progressed.
          * @param session GeckoSession that initiated the callback.
          * @param progress Current page load progress value [0, 100].
          */
         @UiThread
-        void onProgressChange(@NonNull GeckoSession session, int progress);
+        default void onProgressChange(@NonNull GeckoSession session, int progress) {}
 
         /**
         * The security status has been updated.
         * @param session GeckoSession that initiated the callback.
         * @param securityInfo The new security information.
         */
         @UiThread
-        void onSecurityChange(@NonNull GeckoSession session,
-                              @NonNull SecurityInformation securityInfo);
+        default void onSecurityChange(@NonNull GeckoSession session,
+                                      @NonNull SecurityInformation securityInfo) {}
     }
 
     /**
      * WebResponseInfo contains information about a single web response.
      */
     @AnyThread
     static public class WebResponseInfo {
         /**
@@ -2607,43 +2607,43 @@ public class GeckoSession implements Par
     public interface ContentDelegate {
         /**
         * A page title was discovered in the content or updated after the content
         * loaded.
         * @param session The GeckoSession that initiated the callback.
         * @param title The title sent from the content.
         */
         @UiThread
-        void onTitleChange(@NonNull GeckoSession session, @Nullable String title);
+        default void onTitleChange(@NonNull GeckoSession session, @Nullable String title) {}
 
         /**
         * A page has requested focus. Note that window.focus() in content will not result
         * in this being called.
         * @param session The GeckoSession that initiated the callback.
         */
         @UiThread
-        void onFocusRequest(@NonNull GeckoSession session);
+        default void onFocusRequest(@NonNull GeckoSession session) {}
 
         /**
         * A page has requested to close
         * @param session The GeckoSession that initiated the callback.
         */
         @UiThread
-        void onCloseRequest(@NonNull GeckoSession session);
+        default void onCloseRequest(@NonNull GeckoSession session) {}
 
         /**
          * A page has entered or exited full screen mode. Typically, the implementation
          * would set the Activity containing the GeckoSession to full screen when the page is
          * in full screen mode.
          *
          * @param session The GeckoSession that initiated the callback.
          * @param fullScreen True if the page is in full screen mode.
          */
         @UiThread
-        void onFullScreen(@NonNull GeckoSession session, boolean fullScreen);
+        default void onFullScreen(@NonNull GeckoSession session, boolean fullScreen) {}
 
         /**
          * Element details for onContextMenu callbacks.
          */
         public static class ContextElement {
             @Retention(RetentionPolicy.SOURCE)
             @IntDef({TYPE_NONE, TYPE_IMAGE, TYPE_VIDEO, TYPE_AUDIO})
             /* package */ @interface Type {}
@@ -2717,50 +2717,51 @@ public class GeckoSession implements Par
          * elements.
          *
          * @param session The GeckoSession that initiated the callback.
          * @param screenX The screen coordinates of the press.
          * @param screenY The screen coordinates of the press.
          * @param element The details for the pressed element.
          */
         @UiThread
-        void onContextMenu(@NonNull GeckoSession session,
-                           int screenX, int screenY,
-                           @NonNull ContextElement element);
+        default void onContextMenu(@NonNull GeckoSession session,
+                                   int screenX, int screenY,
+                                   @NonNull ContextElement element) {}
 
         /**
          * This is fired when there is a response that cannot be handled
          * by Gecko (e.g., a download).
          *
          * @param session the GeckoSession that received the external response.
          * @param response the WebResponseInfo for the external response
          */
         @UiThread
-        void onExternalResponse(@NonNull GeckoSession session, @NonNull WebResponseInfo response);
+        default void onExternalResponse(@NonNull GeckoSession session,
+                                        @NonNull WebResponseInfo response) {}
 
         /**
          * The content process hosting this GeckoSession has crashed. The
          * GeckoSession is now closed and unusable. You may call
          * {@link #open(GeckoRuntime)} to recover the session, but no state
          * is preserved. Most applications will want to call
          * {@link #loadUri(Uri)} or {@link #restoreState(SessionState)} at this point.
          *
          * @param session The GeckoSession that crashed.
          */
         @UiThread
-        void onCrash(@NonNull GeckoSession session);
+        default void onCrash(@NonNull GeckoSession session) {}
 
         /**
          * Notification that the first content composition has occurred.
          * This callback is invoked for the first content composite after either
          * a start or a restart of the compositor.
          * @param session The GeckoSession that had a first paint event.
          */
         @UiThread
-        void onFirstComposite(@NonNull GeckoSession session);
+        default void onFirstComposite(@NonNull GeckoSession session) {}
     }
 
     public interface SelectionActionDelegate {
         @Retention(RetentionPolicy.SOURCE)
         @IntDef(flag = true, value = {FLAG_IS_COLLAPSED,
                                       FLAG_IS_EDITABLE})
         /* package */ @interface Flag {}
 
@@ -2903,18 +2904,18 @@ public class GeckoSession implements Par
          * @param selection Current selection attributes.
          * @param actions Array of built-in actions available; possible values
          * come from the {@link #ACTION_HIDE ACTION_*} constants.
          * @param response Callback object for performing built-in actions. For example,
          * {@code response.respond(actions[0])} performs the first action. May be used
          * multiple times to perform multiple actions at once.
          */
         @UiThread
-        void onShowActionRequest(@NonNull GeckoSession session, @NonNull Selection selection,
-                                 @Action String[] actions, @NonNull GeckoResponse<String> response);
+        default void onShowActionRequest(@NonNull GeckoSession session, @NonNull Selection selection,
+                                         @Action String[] actions, @NonNull GeckoResponse<String> response) {}
 
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({HIDE_REASON_NO_SELECTION,
                  HIDE_REASON_INVISIBLE_SELECTION,
                  HIDE_REASON_ACTIVE_SELECTION,
                  HIDE_REASON_ACTIVE_SCROLL})
         /* package */ @interface HideReason {}
 
@@ -2945,43 +2946,43 @@ public class GeckoSession implements Par
          * Previous actions are no longer available due to the user interacting with the
          * page. Applications typically hide the action toolbar in response.
          *
          * @param session The GeckoSession that initiated the callback.
          * @param reason The reason that actions are no longer available, as one of the
          * {@link #HIDE_REASON_NO_SELECTION HIDE_REASON_*} constants.
          */
         @UiThread
-        void onHideAction(@NonNull GeckoSession session, @HideReason int reason);
+        default void onHideAction(@NonNull GeckoSession session, @HideReason int reason) {}
     }
 
     public interface NavigationDelegate {
         /**
         * A view has started loading content from the network.
         * @param session The GeckoSession that initiated the callback.
         * @param url The resource being loaded.
         */
         @UiThread
-        void onLocationChange(@NonNull GeckoSession session, @Nullable String url);
+        default void onLocationChange(@NonNull GeckoSession session, @Nullable String url) {}
 
         /**
         * The view's ability to go back has changed.
         * @param session The GeckoSession that initiated the callback.
         * @param canGoBack The new value for the ability.
         */
         @UiThread
-        void onCanGoBack(@NonNull GeckoSession session, boolean canGoBack);
+        default void onCanGoBack(@NonNull GeckoSession session, boolean canGoBack) {}
 
         /**
         * The view's ability to go forward has changed.
         * @param session The GeckoSession that initiated the callback.
         * @param canGoForward The new value for the ability.
         */
         @UiThread
-        void onCanGoForward(@NonNull GeckoSession session, boolean canGoForward);
+        default void onCanGoForward(@NonNull GeckoSession session, boolean canGoForward) {}
 
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({TARGET_WINDOW_NONE, TARGET_WINDOW_CURRENT, TARGET_WINDOW_NEW})
         /* package */ @interface TargetWindow {}
         public static final int TARGET_WINDOW_NONE = 0;
         public static final int TARGET_WINDOW_CURRENT = 1;
         public static final int TARGET_WINDOW_NEW = 2;
 
@@ -3060,44 +3061,54 @@ public class GeckoSession implements Par
          * @param request The {@link LoadRequest} containing the request details.
          *
          * @return A {@link GeckoResult} with a AllowOrDeny value which indicates whether
          *         or not the load was handled. If unhandled, Gecko will continue the
          *         load as normal. If handled (true value), Gecko will abandon the load.
          *         A null return value is interpreted as false (unhandled).
          */
         @UiThread
-        @Nullable GeckoResult<AllowOrDeny> onLoadRequest(@NonNull GeckoSession session,
-                                                         @NonNull LoadRequest request);
+        default @Nullable GeckoResult<AllowOrDeny> onLoadRequest(@NonNull GeckoSession session,
+                                                                 @NonNull LoadRequest request)
+        {
+            return null;
+        }
 
         /**
         * A request has been made to open a new session. The URI is provided only for
         * informational purposes. Do not call GeckoSession.loadUri() here. Additionally, the
         * returned GeckoSession must be a newly-created one.
         *
         * @param session The GeckoSession that initiated the callback.
         * @param uri The URI to be loaded.
         *
         * @return A {@link GeckoResult} which holds the returned GeckoSession. May be null, in
          *        which case the request for a new window by web content will fail. e.g.,
          *        <code>window.open()</code> will return null.
         */
         @UiThread
-        @Nullable GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession session, @NonNull String uri);
+        default @Nullable GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession session,
+                                                                 @NonNull String uri)
+        {
+            return null;
+        }
 
         /**
          * @param session The GeckoSession that initiated the callback.
          * @param uri The URI that failed to load.
          * @param error A WebRequestError containing details about the error
          * @return A URI to display as an error. Returning null will halt the load entirely.
          */
         @UiThread
-        @Nullable GeckoResult<String> onLoadError(@NonNull GeckoSession session,
-                                                  @Nullable String uri,
-                                                  @NonNull WebRequestError error);
+        default @Nullable GeckoResult<String> onLoadError(@NonNull GeckoSession session,
+                                                          @Nullable String uri,
+                                                          @NonNull WebRequestError error)
+        {
+            return null;
+        }
     }
 
     /**
      * GeckoSession applications implement this interface to handle prompts triggered by
      * content in the GeckoSession, such as alerts, authentication dialogs, and select list
      * pickers.
      **/
     public interface PromptDelegate {
@@ -3155,18 +3166,21 @@ public class GeckoSession implements Par
          * Display a simple message prompt.
          *
          * @param session GeckoSession that triggered the prompt
          * @param title Title for the prompt dialog.
          * @param msg Message for the prompt dialog.
          * @param callback Callback interface.
          */
         @UiThread
-        void onAlert(@NonNull GeckoSession session, @Nullable String title, @Nullable String msg,
-                     @NonNull AlertCallback callback);
+        default void onAlert(@NonNull GeckoSession session, @Nullable String title, @Nullable String msg,
+                             @NonNull AlertCallback callback)
+        {
+            callback.dismiss();
+        }
 
         /**
          * Callback interface for notifying the result of a button prompt.
          */
         interface ButtonCallback extends AlertCallback {
             /**
              * Called by the prompt implementation when the button prompt is dismissed by
              * the user pressing one of the buttons.
@@ -3190,19 +3204,22 @@ public class GeckoSession implements Par
          * @param btnMsg Array of 3 elements indicating labels for the individual buttons.
          *               btnMsg[BUTTON_TYPE_POSITIVE] is the label for the "positive" button.
          *               btnMsg[BUTTON_TYPE_NEUTRAL] is the label for the "neutral" button.
          *               btnMsg[BUTTON_TYPE_NEGATIVE] is the label for the "negative" button.
          *               The button is hidden if the corresponding label is null.
          * @param callback Callback interface.
          */
         @UiThread
-        void onButtonPrompt(@NonNull GeckoSession session, @Nullable String title,
-                            @Nullable String msg, @Nullable String[] btnMsg,
-                            @NonNull ButtonCallback callback);
+        default void onButtonPrompt(@NonNull GeckoSession session, @Nullable String title,
+                                    @Nullable String msg, @Nullable String[] btnMsg,
+                                    @NonNull ButtonCallback callback)
+        {
+            callback.dismiss();
+        }
 
         /**
          * Callback interface for notifying the result of prompts that have text results,
          * including color and date/time pickers.
          */
         interface TextCallback extends AlertCallback {
             /**
              * Called by the prompt implementation when the text prompt is confirmed by
@@ -3219,19 +3236,22 @@ public class GeckoSession implements Par
          *
          * @param session GeckoSession that triggered the prompt
          * @param title Title for the prompt dialog.
          * @param msg Message for the prompt dialog.
          * @param value Default input text for the prompt.
          * @param callback Callback interface.
          */
         @UiThread
-        void onTextPrompt(@NonNull GeckoSession session, @Nullable String title,
-                          @Nullable String msg, @Nullable String value,
-                          @NonNull TextCallback callback);
+        default void onTextPrompt(@NonNull GeckoSession session, @Nullable String title,
+                                  @Nullable String msg, @Nullable String value,
+                                  @NonNull TextCallback callback)
+        {
+            callback.dismiss();
+        }
 
         /**
          * Callback interface for notifying the result of authentication prompts.
          */
         interface AuthCallback extends AlertCallback {
             /**
              * Called by the prompt implementation when a password-only prompt is
              * confirmed by the user.
@@ -3348,19 +3368,22 @@ public class GeckoSession implements Par
          *
          * @param session GeckoSession that triggered the prompt
          * @param title Title for the prompt dialog.
          * @param msg Message for the prompt dialog.
          * @param options AuthOptions containing options for the prompt
          * @param callback Callback interface.
          */
         @UiThread
-        void onAuthPrompt(@NonNull GeckoSession session, @Nullable String title,
-                          @Nullable String msg, @NonNull AuthOptions options,
-                          @NonNull AuthCallback callback);
+        default void onAuthPrompt(@NonNull GeckoSession session, @Nullable String title,
+                                  @Nullable String msg, @NonNull AuthOptions options,
+                                  @NonNull AuthCallback callback)
+        {
+            callback.dismiss();
+        }
 
         class Choice {
             @Retention(RetentionPolicy.SOURCE)
             @IntDef({CHOICE_TYPE_MENU, CHOICE_TYPE_SINGLE, CHOICE_TYPE_MULTIPLE})
             /* package */ @interface ChoiceType {}
 
             /**
              * Display choices in a menu that dismisses as soon as an item is chosen.
@@ -3499,32 +3522,38 @@ public class GeckoSession implements Par
          * @param session GeckoSession that triggered the prompt
          * @param title Title for the prompt dialog, or null for no title.
          * @param msg Message for the prompt dialog, or null for no message.
          * @param type One of CHOICE_TYPE_* indicating the type of prompt.
          * @param choices Array of Choices each representing an item or group.
          * @param callback Callback interface.
          */
         @UiThread
-        void onChoicePrompt(@NonNull GeckoSession session, @Nullable String title,
-                            @Nullable String msg, @Choice.ChoiceType int type,
-                            @NonNull Choice[] choices, @NonNull ChoiceCallback callback);
+        default void onChoicePrompt(@NonNull GeckoSession session, @Nullable String title,
+                                    @Nullable String msg, @Choice.ChoiceType int type,
+                                    @NonNull Choice[] choices, @NonNull ChoiceCallback callback)
+        {
+            callback.dismiss();
+        }
 
         /**
          * Display a color prompt.
          *
          * @param session GeckoSession that triggered the prompt
          * @param title Title for the prompt dialog.
          * @param value Initial color value in HTML color format.
          * @param callback Callback interface; the result passed to confirm() must be in
          *                 HTML color format.
          */
         @UiThread
-        void onColorPrompt(@NonNull GeckoSession session, @Nullable String title,
-                           @Nullable String value, @NonNull TextCallback callback);
+        default void onColorPrompt(@NonNull GeckoSession session, @Nullable String title,
+                                   @Nullable String value, @NonNull TextCallback callback)
+        {
+            callback.dismiss();
+        }
 
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({DATETIME_TYPE_DATE, DATETIME_TYPE_MONTH, DATETIME_TYPE_WEEK,
                  DATETIME_TYPE_TIME, DATETIME_TYPE_DATETIME_LOCAL})
         /* package */ @interface DatetimeType {}
 
         /**
          * Prompt for year, month, and day.
@@ -3559,19 +3588,22 @@ public class GeckoSession implements Par
          * @param type One of DATETIME_TYPE_* indicating the type of prompt.
          * @param value Initial date/time value in HTML date/time format.
          * @param min Minimum date/time value in HTML date/time format.
          * @param max Maximum date/time value in HTML date/time format.
          * @param callback Callback interface; the result passed to confirm() must be in
          *                 HTML date/time format.
          */
         @UiThread
-        void onDateTimePrompt(@NonNull GeckoSession session, @Nullable String title,
-                              @DatetimeType int type, @Nullable String value, @Nullable String min,
-                              @Nullable String max, @NonNull TextCallback callback);
+        default void onDateTimePrompt(@NonNull GeckoSession session, @Nullable String title,
+                                      @DatetimeType int type, @Nullable String value, @Nullable String min,
+                                      @Nullable String max, @NonNull TextCallback callback)
+        {
+            callback.dismiss();
+        }
 
         /**
          * Callback interface for notifying the result of file prompts.
          */
         interface FileCallback extends AlertCallback {
             /**
              * Called by the prompt implementation when the user makes a file selection in
              * single-selection mode.
@@ -3607,48 +3639,54 @@ public class GeckoSession implements Par
          * @param type One of FILE_TYPE_* indicating the prompt type.
          * @param mimeTypes Array of permissible MIME types or extensions for the selected
          *                  files. MIME types are of the form "type/subtype", where "type"
          *                  and/or "subtype" can be "*" to indicate any value. Extensions
          *                  are of the form ".ext".
          * @param callback Callback interface.
          */
         @UiThread
-        void onFilePrompt(@NonNull GeckoSession session, @Nullable String title, @FileType int type,
-                          @Nullable String[] mimeTypes, @NonNull FileCallback callback);
+        default void onFilePrompt(@NonNull GeckoSession session, @Nullable String title, @FileType int type,
+                                  @Nullable String[] mimeTypes, @NonNull FileCallback callback)
+        {
+            callback.dismiss();
+        }
 
         /**
          * Display a popup request prompt; this occurs when content attempts to open
          * a new window in a way that doesn't appear to be the result of user input.
          *
          * @param session GeckoSession that triggered the prompt
          * @param targetUri The target URI for the popup
          *
          * @return A {@link GeckoResult} resolving to a AllowOrDeny which indicates
          *         whether or not the popup should be allowed to open.
          */
         @UiThread
-        GeckoResult<AllowOrDeny> onPopupRequest(@NonNull GeckoSession session,
-                                                @Nullable String targetUri);
+        default @Nullable GeckoResult<AllowOrDeny> onPopupRequest(@NonNull GeckoSession session,
+                                                                  @Nullable String targetUri)
+        {
+            return null;
+        }
     }
 
     /**
      * GeckoSession applications implement this interface to handle content scroll
      * events.
      **/
     public interface ScrollDelegate {
         /**
          * The scroll position of the content has changed.
          *
         * @param session GeckoSession that initiated the callback.
         * @param scrollX The new horizontal scroll position in pixels.
         * @param scrollY The new vertical scroll position in pixels.
         */
         @UiThread
-        public void onScrollChanged(@NonNull GeckoSession session, int scrollX, int scrollY);
+        default void onScrollChanged(@NonNull GeckoSession session, int scrollX, int scrollY) {}
     }
 
     /**
      * Get the PanZoomController instance for this session.
      *
      * @return PanZoomController instance.
      */
     @UiThread
@@ -3861,33 +3899,39 @@ public class GeckoSession implements Par
          * @param permissions List of permissions to request; possible values are,
          *                    android.Manifest.permission.ACCESS_COARSE_LOCATION
          *                    android.Manifest.permission.ACCESS_FINE_LOCATION
          *                    android.Manifest.permission.CAMERA
          *                    android.Manifest.permission.RECORD_AUDIO
          * @param callback Callback interface.
          */
         @UiThread
-        void onAndroidPermissionsRequest(@NonNull GeckoSession session,
-                                         @Nullable String[] permissions,
-                                         @NonNull Callback callback);
+        default void onAndroidPermissionsRequest(@NonNull GeckoSession session,
+                                                 @Nullable String[] permissions,
+                                                 @NonNull Callback callback)
+        {
+            callback.reject();
+        }
 
         /**
          * Request content permission.
          *
          * @param session GeckoSession instance requesting the permission.
          * @param uri The URI of the content requesting the permission.
          * @param type The type of the requested permission; possible values are,
          *             PERMISSION_GEOLOCATION
          *             PERMISSION_DESKTOP_NOTIFICATION
          * @param callback Callback interface.
          */
         @UiThread
-        void onContentPermissionRequest(@NonNull GeckoSession session, @Nullable String uri,
-                                        @Permission int type, @NonNull Callback callback);
+        default void onContentPermissionRequest(@NonNull GeckoSession session, @Nullable String uri,
+                                                @Permission int type, @NonNull Callback callback)
+        {
+            callback.reject();
+        }
 
         class MediaSource {
             @Retention(RetentionPolicy.SOURCE)
             @IntDef({SOURCE_CAMERA, SOURCE_SCREEN, SOURCE_APPLICATION,
                      SOURCE_WINDOW, SOURCE_BROWSER, SOURCE_MICROPHONE,
                      SOURCE_AUDIOCAPTURE, SOURCE_OTHER})
             /* package */ @interface Source {}
 
@@ -4080,19 +4124,22 @@ public class GeckoSession implements Par
          *
          * @param session GeckoSession instance requesting the permission.
          * @param uri The URI of the content requesting the permission.
          * @param video List of video sources, or null if not requesting video.
          * @param audio List of audio sources, or null if not requesting audio.
          * @param callback Callback interface.
          */
         @UiThread
-        void onMediaPermissionRequest(@NonNull GeckoSession session, @NonNull String uri,
-                                      @Nullable MediaSource[] video, @Nullable MediaSource[] audio,
-                                      @NonNull MediaCallback callback);
+        default void onMediaPermissionRequest(@NonNull GeckoSession session, @NonNull String uri,
+                                              @Nullable MediaSource[] video, @Nullable MediaSource[] audio,
+                                              @NonNull MediaCallback callback)
+        {
+            callback.reject();
+        }
     }
 
     /**
      * Interface that SessionTextInput uses for performing operations such as opening and closing
      * the software keyboard. If the delegate is not set, these operations are forwarded to the
      * system {@link android.view.inputmethod.InputMethodManager} automatically.
      */
     public interface TextInputDelegate {
@@ -4465,24 +4512,25 @@ public class GeckoSession implements Par
      */
     public interface MediaDelegate {
         /**
          * An HTMLMediaElement has been created.
          * @param session Session instance.
          * @param element The media element that was just created.
          */
         @UiThread
-        void onMediaAdd(@NonNull GeckoSession session, @NonNull MediaElement element);
+        default void onMediaAdd(@NonNull GeckoSession session, @NonNull MediaElement element) {}
+
         /**
          * An HTMLMediaElement has been unloaded.
          * @param session Session instance.
          * @param element The media element that was unloaded.
          */
         @UiThread
-        void onMediaRemove(@NonNull GeckoSession session, @NonNull MediaElement element);
+        default void onMediaRemove(@NonNull GeckoSession session, @NonNull MediaElement element) {}
     }
 
     /**
      * An interface for recording new history visits and fetching the visited
      * status for links.
      */
     public interface HistoryDelegate {
         @Retention(RetentionPolicy.SOURCE)
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -80,16 +80,19 @@ exclude: true
 [67.18]: https://developer.android.com/reference/android/view/Surface
 [67.19]: https://developer.android.com/reference/java/lang/IllegalStateException
 
 - Added API to capture a screenshot to [`GeckoDisplay`][67.20]. [`capturePixels`][67.21] returns a ['GeckoResult'][65.25] that completes to a [`Bitmap`][67.16] of the current [`Surface`][67.17] contents, or an [`IllegalStateException`][67.18] if the [`GeckoSession`][65.9] is not ready to render content.
 
 [67.20]: ../GeckoDisplay.html
 [67.21]: ../GeckoDisplay.html#capturePixels
 
+- Add missing `@Nullable` annotation to return value for
+  `GeckoSession.PromptDelegate.ChoiceCallback.onPopupResult()`
+
 ## v66
 - Removed redundant field `trackingMode` from [`SecurityInformation`][66.6].
   Use `TrackingProtectionDelegate.onTrackerBlocked` for notification of blocked
   elements during page load.
 
 [66.6]: ../GeckoSession.ProgressDelegate.SecurityInformation.html
 
 - Added [`@NonNull`][66.1] or [`@Nullable`][66.2] to all APIs.
@@ -199,9 +202,9 @@ exclude: true
 [65.23]: ../GeckoSession.FinderResult.html
 
 - Update [`CrashReporter#sendCrashReport`][65.24] to return the crash ID as a
   [`GeckoResult<String>`][65.25].
 
 [65.24]: ../CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
 [65.25]: ../GeckoResult.html
 
-[api-version]: 0bcb9f0f763b746bb6f27f5d275c351818ab971b
+[api-version]: 577c3b0d000b0b1da57f9af32331f1e9045939b9