Bug 1535013: [geckoview] Add default impls to all interfaces. r=snorp

This also upgrades apilint to 0.1.8 to enforce that all interfaces have default
impls.

Differential Revision: https://phabricator.services.mozilla.com/D23324

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Agi Sferro 2019-03-14 16:48:57 +00:00
parent b5a365766b
commit 3960667956
6 changed files with 141 additions and 123 deletions

View File

@ -81,7 +81,7 @@ buildscript {
}
dependencies {
classpath 'org.mozilla.apilint:apilint:0.1.7'
classpath 'org.mozilla.apilint:apilint:0.1.8'
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2'
classpath 'org.apache.commons:commons-exec:1.3'

View File

@ -71,7 +71,7 @@ package org.mozilla.geckoview {
}
public static interface ContentBlocking.Delegate {
method @android.support.annotation.UiThread public void onContentBlocked(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.ContentBlocking.BlockEvent);
method @android.support.annotation.UiThread default public void onContentBlocked(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.ContentBlocking.BlockEvent);
}
@android.support.annotation.AnyThread public static class ContentBlocking.Settings extends org.mozilla.geckoview.RuntimeSettings {
@ -124,9 +124,9 @@ package org.mozilla.geckoview {
}
public static interface DynamicToolbarAnimator.ToolbarChromeProxy {
method @android.support.annotation.UiThread @android.support.annotation.Nullable public android.graphics.Bitmap getBitmapOfToolbarChrome();
method @android.support.annotation.UiThread public boolean isToolbarChromeVisible();
method @android.support.annotation.UiThread public void toggleToolbarChrome(boolean);
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public android.graphics.Bitmap getBitmapOfToolbarChrome();
method @android.support.annotation.UiThread default public boolean isToolbarChromeVisible();
method @android.support.annotation.UiThread default public void toggleToolbarChrome(boolean);
}
public class GeckoDisplay {
@ -345,14 +345,14 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.ContentDelegate {
method @android.support.annotation.UiThread public void onCloseRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread public void onContextMenu(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement);
method @android.support.annotation.UiThread public void onCrash(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread public void onExternalResponse(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.WebResponseInfo);
method @android.support.annotation.UiThread public void onFirstComposite(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread public void onFocusRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread public void onFullScreen(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread public void onTitleChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread default public void onCloseRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread default public void onContextMenu(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement);
method @android.support.annotation.UiThread default public void onCrash(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread default public void onExternalResponse(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.WebResponseInfo);
method @android.support.annotation.UiThread default public void onFirstComposite(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread default public void onFocusRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread default public void onFullScreen(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread default public void onTitleChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String);
}
public static class GeckoSession.ContentDelegate.ContextElement {
@ -382,8 +382,8 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.HistoryDelegate {
method @android.support.annotation.UiThread @android.support.annotation.Nullable public org.mozilla.geckoview.GeckoResult<boolean[]> getVisited(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String[]);
method @android.support.annotation.UiThread @android.support.annotation.Nullable public org.mozilla.geckoview.GeckoResult<java.lang.Boolean> onVisited(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String, @android.support.annotation.Nullable java.lang.String, int);
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public org.mozilla.geckoview.GeckoResult<boolean[]> getVisited(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String[]);
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public org.mozilla.geckoview.GeckoResult<java.lang.Boolean> onVisited(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String, @android.support.annotation.Nullable java.lang.String, int);
field public static final int VISIT_REDIRECT_PERMANENT = 4;
field public static final int VISIT_REDIRECT_SOURCE = 8;
field public static final int VISIT_REDIRECT_SOURCE_PERMANENT = 16;
@ -396,17 +396,17 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.MediaDelegate {
method @android.support.annotation.UiThread public void onMediaAdd(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement);
method @android.support.annotation.UiThread public void onMediaRemove(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement);
method @android.support.annotation.UiThread default public void onMediaAdd(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement);
method @android.support.annotation.UiThread default public void onMediaRemove(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement);
}
public static interface GeckoSession.NavigationDelegate {
method @android.support.annotation.UiThread public void onCanGoBack(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread public void onCanGoForward(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread @android.support.annotation.Nullable public org.mozilla.geckoview.GeckoResult<java.lang.String> onLoadError(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.WebRequestError);
method @android.support.annotation.UiThread @android.support.annotation.Nullable public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onLoadRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.NavigationDelegate.LoadRequest);
method @android.support.annotation.UiThread public void onLocationChange(@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.GeckoSession> onNewSession(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String);
method @android.support.annotation.UiThread default public void onCanGoBack(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread default public void onCanGoForward(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public org.mozilla.geckoview.GeckoResult<java.lang.String> onLoadError(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, @android.support.annotation.NonNull org.mozilla.geckoview.WebRequestError);
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onLoadRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.NavigationDelegate.LoadRequest);
method @android.support.annotation.UiThread default public void onLocationChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.GeckoSession> onNewSession(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String);
field public static final int LOAD_REQUEST_IS_REDIRECT = 8388608;
field public static final int TARGET_WINDOW_CURRENT = 1;
field public static final int TARGET_WINDOW_NEW = 2;
@ -425,22 +425,22 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.PermissionDelegate {
method @android.support.annotation.UiThread public void onAndroidPermissionsRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
method @android.support.annotation.UiThread public void onContentPermissionRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, int, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
method @android.support.annotation.UiThread public void onMediaPermissionRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String, @android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], @android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaCallback);
method @android.support.annotation.UiThread default public void onAndroidPermissionsRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
method @android.support.annotation.UiThread default public void onContentPermissionRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.Nullable java.lang.String, int, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
method @android.support.annotation.UiThread default public void onMediaPermissionRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String, @android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], @android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaCallback);
field public static final int PERMISSION_DESKTOP_NOTIFICATION = 1;
field public static final int PERMISSION_GEOLOCATION = 0;
}
public static interface GeckoSession.PermissionDelegate.Callback {
method @android.support.annotation.UiThread public void grant();
method @android.support.annotation.UiThread public void reject();
method @android.support.annotation.UiThread default public void grant();
method @android.support.annotation.UiThread default public void reject();
}
public static interface GeckoSession.PermissionDelegate.MediaCallback {
method @android.support.annotation.UiThread public void grant(@android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread public void grant(@android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource, @android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource);
method @android.support.annotation.UiThread public void reject();
method @android.support.annotation.UiThread default public void grant(@android.support.annotation.Nullable java.lang.String, @android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread default public void grant(@android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource, @android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource);
method @android.support.annotation.UiThread default public void reject();
}
public static class GeckoSession.PermissionDelegate.MediaSource {
@ -466,10 +466,10 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.ProgressDelegate {
method @android.support.annotation.UiThread public void onPageStart(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String);
method @android.support.annotation.UiThread public void onPageStop(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread public void onProgressChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int);
method @android.support.annotation.UiThread public void onSecurityChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.ProgressDelegate.SecurityInformation);
method @android.support.annotation.UiThread default public void onPageStart(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull java.lang.String);
method @android.support.annotation.UiThread default public void onPageStop(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, boolean);
method @android.support.annotation.UiThread default public void onProgressChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int);
method @android.support.annotation.UiThread default public void onSecurityChange(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.ProgressDelegate.SecurityInformation);
}
public static class GeckoSession.ProgressDelegate.SecurityInformation {
@ -494,15 +494,15 @@ 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 @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);
method @android.support.annotation.UiThread default 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 default 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 default 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 default 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 default 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 default 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 default 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 @android.support.annotation.Nullable default 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 default 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;
@ -516,16 +516,16 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.PromptDelegate.AlertCallback {
method @android.support.annotation.UiThread public void dismiss();
method @android.support.annotation.UiThread @android.support.annotation.Nullable public java.lang.String getCheckboxMessage();
method @android.support.annotation.UiThread public boolean getCheckboxValue();
method @android.support.annotation.UiThread public boolean hasCheckbox();
method @android.support.annotation.UiThread public void setCheckboxValue(boolean);
method @android.support.annotation.UiThread default public void dismiss();
method @android.support.annotation.UiThread @android.support.annotation.Nullable default public java.lang.String getCheckboxMessage();
method @android.support.annotation.UiThread default public boolean getCheckboxValue();
method @android.support.annotation.UiThread default public boolean hasCheckbox();
method @android.support.annotation.UiThread default public void setCheckboxValue(boolean);
}
public static interface GeckoSession.PromptDelegate.AuthCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.NonNull java.lang.String, @android.support.annotation.NonNull java.lang.String);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.NonNull java.lang.String, @android.support.annotation.NonNull java.lang.String);
}
public static class GeckoSession.PromptDelegate.AuthOptions {
@ -546,7 +546,7 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.PromptDelegate.ButtonCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
method @android.support.annotation.UiThread public void confirm(int);
method @android.support.annotation.UiThread default public void confirm(int);
}
public static class GeckoSession.PromptDelegate.Choice {
@ -564,34 +564,34 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.PromptDelegate.ChoiceCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.NonNull java.lang.String[]);
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice);
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[]);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.NonNull java.lang.String[]);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.Nullable org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[]);
}
public static interface GeckoSession.PromptDelegate.DatetimeType implements java.lang.annotation.Annotation {
}
public static interface GeckoSession.PromptDelegate.FileCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.Nullable android.content.Context, @android.support.annotation.Nullable android.net.Uri);
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.Nullable android.content.Context, @android.support.annotation.Nullable android.net.Uri[]);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.Nullable android.content.Context, @android.support.annotation.Nullable android.net.Uri);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.Nullable android.content.Context, @android.support.annotation.Nullable android.net.Uri[]);
}
public static interface GeckoSession.PromptDelegate.FileType implements java.lang.annotation.Annotation {
}
public static interface GeckoSession.PromptDelegate.TextCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
method @android.support.annotation.UiThread public void confirm(@android.support.annotation.Nullable java.lang.String);
method @android.support.annotation.UiThread default public void confirm(@android.support.annotation.Nullable java.lang.String);
}
public static interface GeckoSession.ScrollDelegate {
method @android.support.annotation.UiThread public void onScrollChanged(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int);
method @android.support.annotation.UiThread default public void onScrollChanged(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int);
}
public static interface GeckoSession.SelectionActionDelegate {
method @android.support.annotation.UiThread public void onHideAction(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int);
method @android.support.annotation.UiThread public void onShowActionRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.SelectionActionDelegate.Selection, java.lang.String[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoResponse<java.lang.String>);
method @android.support.annotation.UiThread default public void onHideAction(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int);
method @android.support.annotation.UiThread default public void onShowActionRequest(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession.SelectionActionDelegate.Selection, java.lang.String[], @android.support.annotation.NonNull org.mozilla.geckoview.GeckoResponse<java.lang.String>);
field public static final java.lang.String ACTION_COLLAPSE_TO_END = "org.mozilla.geckoview.COLLAPSE_TO_END";
field public static final java.lang.String ACTION_COLLAPSE_TO_START = "org.mozilla.geckoview.COLLAPSE_TO_START";
field public static final java.lang.String ACTION_COPY = "org.mozilla.geckoview.COPY";
@ -633,13 +633,13 @@ package org.mozilla.geckoview {
}
public static interface GeckoSession.TextInputDelegate {
method @android.support.annotation.UiThread public void hideSoftInput(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread public void notifyAutoFill(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int);
method @android.support.annotation.UiThread public void restartInput(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int);
method @android.support.annotation.UiThread public void showSoftInput(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread public void updateCursorAnchorInfo(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull android.view.inputmethod.CursorAnchorInfo);
method @android.support.annotation.UiThread public void updateExtractedText(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull android.view.inputmethod.ExtractedTextRequest, @android.support.annotation.NonNull android.view.inputmethod.ExtractedText);
method @android.support.annotation.UiThread public void updateSelection(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int, int, int);
method @android.support.annotation.UiThread default public void hideSoftInput(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread default public void notifyAutoFill(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int);
method @android.support.annotation.UiThread default public void restartInput(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int);
method @android.support.annotation.UiThread default public void showSoftInput(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession);
method @android.support.annotation.UiThread default public void updateCursorAnchorInfo(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull android.view.inputmethod.CursorAnchorInfo);
method @android.support.annotation.UiThread default public void updateExtractedText(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, @android.support.annotation.NonNull android.view.inputmethod.ExtractedTextRequest, @android.support.annotation.NonNull android.view.inputmethod.ExtractedText);
method @android.support.annotation.UiThread default public void updateSelection(@android.support.annotation.NonNull org.mozilla.geckoview.GeckoSession, int, int, int, int);
field public static final int AUTO_FILL_NOTIFY_CANCELED = 2;
field public static final int AUTO_FILL_NOTIFY_COMMITTED = 1;
field public static final int AUTO_FILL_NOTIFY_STARTED = 0;
@ -797,15 +797,15 @@ package org.mozilla.geckoview {
}
public static interface MediaElement.Delegate {
method @android.support.annotation.UiThread public void onError(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, int);
method @android.support.annotation.UiThread public void onFullscreenChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, boolean);
method @android.support.annotation.UiThread public void onLoadProgress(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement.LoadProgressInfo);
method @android.support.annotation.UiThread public void onMetadataChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement.Metadata);
method @android.support.annotation.UiThread public void onPlaybackRateChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, double);
method @android.support.annotation.UiThread public void onPlaybackStateChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, int);
method @android.support.annotation.UiThread public void onReadyStateChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, int);
method @android.support.annotation.UiThread public void onTimeChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, double);
method @android.support.annotation.UiThread public void onVolumeChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, double, boolean);
method @android.support.annotation.UiThread default public void onError(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, int);
method @android.support.annotation.UiThread default public void onFullscreenChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, boolean);
method @android.support.annotation.UiThread default public void onLoadProgress(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement.LoadProgressInfo);
method @android.support.annotation.UiThread default public void onMetadataChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, @android.support.annotation.NonNull org.mozilla.geckoview.MediaElement.Metadata);
method @android.support.annotation.UiThread default public void onPlaybackRateChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, double);
method @android.support.annotation.UiThread default public void onPlaybackStateChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, int);
method @android.support.annotation.UiThread default public void onReadyStateChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, int);
method @android.support.annotation.UiThread default public void onTimeChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, double);
method @android.support.annotation.UiThread default public void onVolumeChange(@android.support.annotation.NonNull org.mozilla.geckoview.MediaElement, double, boolean);
}
public static class MediaElement.LoadProgressInfo {

View File

@ -40,11 +40,15 @@ public final class DynamicToolbarAnimator {
public interface ToolbarChromeProxy {
@UiThread
public @Nullable Bitmap getBitmapOfToolbarChrome();
@Nullable default Bitmap getBitmapOfToolbarChrome() {
return null;
}
@UiThread
public boolean isToolbarChromeVisible();
default boolean isToolbarChromeVisible() {
return false;
}
@UiThread
public void toggleToolbarChrome(boolean aShow);
default void toggleToolbarChrome(boolean aShow) {}
}
private final Set<PinReason> mPinFlags = EnumSet.noneOf(PinReason.class);

View File

@ -3123,7 +3123,7 @@ public class GeckoSession implements Parcelable {
* must call dismiss() or confirm(), if available, when the prompt is dismissed.
*/
@UiThread
void dismiss();
default void dismiss() {}
/**
* Return whether the prompt shown should include a checkbox. For example, if
@ -3135,7 +3135,9 @@ public class GeckoSession implements Parcelable {
* @return True if prompt includes a checkbox.
*/
@UiThread
boolean hasCheckbox();
default boolean hasCheckbox() {
return false;
}
/**
* Return the message label for the optional checkbox.
@ -3143,7 +3145,9 @@ public class GeckoSession implements Parcelable {
* @return Checkbox message or null if none.
*/
@UiThread
@Nullable String getCheckboxMessage();
@Nullable default String getCheckboxMessage() {
return null;
}
/**
* Return the initial value for the optional checkbox.
@ -3151,7 +3155,9 @@ public class GeckoSession implements Parcelable {
* @return Initial checkbox value.
*/
@UiThread
boolean getCheckboxValue();
default boolean getCheckboxValue() {
return false;
}
/**
* Set the current value for the optional checkbox.
@ -3159,7 +3165,7 @@ public class GeckoSession implements Parcelable {
* @param value New checkbox value.
*/
@UiThread
void setCheckboxValue(boolean value);
default void setCheckboxValue(boolean value) {}
}
/**
@ -3188,7 +3194,7 @@ public class GeckoSession implements Parcelable {
* @param button Button result; one of BUTTON_TYPE_* constants.
*/
@UiThread
void confirm(int button);
default void confirm(int button) {}
}
static final int BUTTON_TYPE_POSITIVE = 0;
@ -3228,7 +3234,7 @@ public class GeckoSession implements Parcelable {
* @param text Text result.
*/
@UiThread
void confirm(@Nullable String text);
default void confirm(@Nullable String text) {}
}
/**
@ -3259,7 +3265,7 @@ public class GeckoSession implements Parcelable {
* @param password Entered password.
*/
@UiThread
void confirm(@Nullable String password);
default void confirm(@Nullable String password) {}
/**
* Called by the prompt implementation when a username/password prompt is
@ -3269,7 +3275,7 @@ public class GeckoSession implements Parcelable {
* @param password Entered password.
*/
@UiThread
void confirm(@NonNull String username, @NonNull String password);
default void confirm(@NonNull String username, @NonNull String password) {}
}
class AuthOptions {
@ -3483,7 +3489,7 @@ public class GeckoSession implements Parcelable {
* @param id ID of the selected item.
*/
@UiThread
void confirm(@Nullable String id);
default void confirm(@Nullable String id) {}
/**
* Called by the prompt implementation when the multiple-choice list is
@ -3492,7 +3498,7 @@ public class GeckoSession implements Parcelable {
* @param ids IDs of the selected items.
*/
@UiThread
void confirm(@NonNull String[] ids);
default void confirm(@NonNull String[] ids) {}
/**
* Called by the prompt implementation when the menu or single-choice list is
@ -3502,7 +3508,7 @@ public class GeckoSession implements Parcelable {
* Choice object that was passed to the implementation.
*/
@UiThread
void confirm(@NonNull Choice item);
default void confirm(@NonNull Choice item) {}
/**
* Called by the prompt implementation when the multiple-choice list is
@ -3512,7 +3518,7 @@ public class GeckoSession implements Parcelable {
* Choice objects that were passed to the implementation.
*/
@UiThread
void confirm(@Nullable Choice[] items);
default void confirm(@Nullable Choice[] items) {}
}
@ -3612,7 +3618,7 @@ public class GeckoSession implements Parcelable {
* @param uri The URI of the selected file.
*/
@UiThread
void confirm(@Nullable Context context, @Nullable Uri uri);
default void confirm(@Nullable Context context, @Nullable Uri uri) {}
/**
* Called by the prompt implementation when the user makes file selections in
@ -3622,7 +3628,7 @@ public class GeckoSession implements Parcelable {
* @param uris Array of URI objects for the selected files.
*/
@UiThread
void confirm(@Nullable Context context, @Nullable Uri[] uris);
default void confirm(@Nullable Context context, @Nullable Uri[] uris) {}
}
@Retention(RetentionPolicy.SOURCE)
@ -3882,14 +3888,14 @@ public class GeckoSession implements Parcelable {
* implementation must call either grant() or reject() for every request.
*/
@UiThread
void grant();
default void grant() {}
/**
* Called by the implementation when permissions are not granted; the
* implementation must call either grant() or reject() for every request.
*/
@UiThread
void reject();
default void reject() {}
}
/**
@ -4089,7 +4095,7 @@ public class GeckoSession implements Parcelable {
* or null when audio is not requested.
*/
@UiThread
void grant(final @Nullable String video, final @Nullable String audio);
default void grant(final @Nullable String video, final @Nullable String audio) {}
/**
* Called by the implementation after permissions are granted; the
@ -4103,14 +4109,14 @@ public class GeckoSession implements Parcelable {
* or null when audio is not requested.
*/
@UiThread
void grant(final @Nullable MediaSource video, final @Nullable MediaSource audio);
default void grant(final @Nullable MediaSource video, final @Nullable MediaSource audio) {}
/**
* Called by the implementation when permissions are not granted; the
* implementation must call one of grant() or reject() for every request.
*/
@UiThread
void reject();
default void reject() {}
}
/**
@ -4172,7 +4178,7 @@ public class GeckoSession implements Parcelable {
* @param reason Reason for the reset.
*/
@UiThread
void restartInput(@NonNull GeckoSession session, @RestartReason int reason);
default void restartInput(@NonNull GeckoSession session, @RestartReason int reason) {}
/**
* Display the soft input. May be called consecutively, even if the soft input is
@ -4182,7 +4188,7 @@ public class GeckoSession implements Parcelable {
* @see #hideSoftInput
* */
@UiThread
void showSoftInput(@NonNull GeckoSession session);
default void showSoftInput(@NonNull GeckoSession session) {}
/**
* Hide the soft input. May be called consecutively, even if the soft input is
@ -4192,7 +4198,7 @@ public class GeckoSession implements Parcelable {
* @see #showSoftInput
* */
@UiThread
void hideSoftInput(@NonNull GeckoSession session);
default void hideSoftInput(@NonNull GeckoSession session) {}
/**
* Update the soft input on the current selection. This method is <i>not</i> called
@ -4205,8 +4211,8 @@ public class GeckoSession implements Parcelable {
* @param compositionEnd Composition end offset, or -1 if there is no composition.
*/
@UiThread
void updateSelection(@NonNull GeckoSession session, int selStart, int selEnd,
int compositionStart, int compositionEnd);
default void updateSelection(@NonNull GeckoSession session, int selStart, int selEnd,
int compositionStart, int compositionEnd) {}
/**
* Update the soft input on the current extracted text, as requested through
@ -4218,9 +4224,9 @@ public class GeckoSession implements Parcelable {
* @param text The extracted text.
*/
@UiThread
void updateExtractedText(@NonNull GeckoSession session,
@NonNull ExtractedTextRequest request,
@NonNull ExtractedText text);
default void updateExtractedText(@NonNull GeckoSession session,
@NonNull ExtractedTextRequest request,
@NonNull ExtractedText text) {}
/**
* Update the cursor-anchor information as requested through
@ -4231,7 +4237,8 @@ public class GeckoSession implements Parcelable {
* @param info Cursor-anchor information.
*/
@UiThread
void updateCursorAnchorInfo(@NonNull GeckoSession session, @NonNull CursorAnchorInfo info);
default void updateCursorAnchorInfo(@NonNull GeckoSession session,
@NonNull CursorAnchorInfo info) {}
@Retention(RetentionPolicy.SOURCE)
@IntDef({AUTO_FILL_NOTIFY_STARTED, AUTO_FILL_NOTIFY_COMMITTED, AUTO_FILL_NOTIFY_CANCELED,
@ -4271,8 +4278,9 @@ public class GeckoSession implements Parcelable {
* with {@link SessionTextInput#autofill}.
*/
@UiThread
void notifyAutoFill(@NonNull GeckoSession session, @AutoFillNotification int notification,
int virtualId);
default void notifyAutoFill(@NonNull GeckoSession session,
@AutoFillNotification int notification,
int virtualId) {}
}
/* package */ void onSurfaceChanged(final Surface surface, final int x, final int y, final int width,

View File

@ -292,7 +292,8 @@ public class MediaElement {
* One of the {@link #MEDIA_STATE_PLAY MEDIA_STATE_*} flags.
*/
@UiThread
void onPlaybackStateChange(@NonNull MediaElement mediaElement, @MediaStateFlags int mediaState);
default void onPlaybackStateChange(@NonNull MediaElement mediaElement,
@MediaStateFlags int mediaState) {}
/**
* The readiness state of the media has changed.
@ -302,7 +303,8 @@ public class MediaElement {
* One of the {@link #MEDIA_READY_STATE_HAVE_NOTHING MEDIA_READY_STATE_*} flags.
*/
@UiThread
void onReadyStateChange(@NonNull MediaElement mediaElement, @ReadyStateFlags int readyState);
default void onReadyStateChange(@NonNull MediaElement mediaElement,
@ReadyStateFlags int readyState) {}
/**
* The media metadata has loaded or changed.
@ -311,7 +313,8 @@ public class MediaElement {
* @param metaData The MetaData values of the media.
*/
@UiThread
void onMetadataChange(@NonNull MediaElement mediaElement, @NonNull Metadata metaData);
default void onMetadataChange(@NonNull MediaElement mediaElement,
@NonNull Metadata metaData) {}
/**
* Indicates that a loading operation is in progress for the media.
@ -320,8 +323,8 @@ public class MediaElement {
* @param progressInfo Information about the load progress and buffered ranges.
*/
@UiThread
void onLoadProgress(@NonNull MediaElement mediaElement,
@NonNull LoadProgressInfo progressInfo);
default void onLoadProgress(@NonNull MediaElement mediaElement,
@NonNull LoadProgressInfo progressInfo) {}
/**
* The media audio volume has changed.
@ -331,7 +334,8 @@ public class MediaElement {
* @param muted True if the media is muted.
*/
@UiThread
void onVolumeChange(@NonNull MediaElement mediaElement, double volume, boolean muted);
default void onVolumeChange(@NonNull MediaElement mediaElement, double volume,
boolean muted) {}
/**
* The current playback time has changed. This event is usually dispatched every 250ms.
@ -340,7 +344,7 @@ public class MediaElement {
* @param time The current playback time in seconds.
*/
@UiThread
void onTimeChange(@NonNull MediaElement mediaElement, double time);
default void onTimeChange(@NonNull MediaElement mediaElement, double time) {}
/**
* The media playback speed has changed.
@ -349,7 +353,7 @@ public class MediaElement {
* @param rate The current playback rate. A value of 1.0 indicates normal speed.
*/
@UiThread
void onPlaybackRateChange(@NonNull MediaElement mediaElement, double rate);
default void onPlaybackRateChange(@NonNull MediaElement mediaElement, double rate) {}
/**
* A media element has entered or exited fullscreen mode.
@ -358,7 +362,7 @@ public class MediaElement {
* @param fullscreen True if the media has entered full screen mode.
*/
@UiThread
void onFullscreenChange(@NonNull MediaElement mediaElement, boolean fullscreen);
default void onFullscreenChange(@NonNull MediaElement mediaElement, boolean fullscreen) {}
/**
* An error has occurred.
@ -368,7 +372,7 @@ public class MediaElement {
* One of the {@link #MEDIA_ERROR_NETWORK_NO_SOURCE MEDIA_ERROR_*} flags.
*/
@UiThread
void onError(@NonNull MediaElement mediaElement, @MediaErrorFlags int errorCode);
default void onError(@NonNull MediaElement mediaElement, @MediaErrorFlags int errorCode) {}
}
/* package */ long getVideoId() {

View File

@ -88,6 +88,8 @@ exclude: true
- Add missing `@Nullable` annotation to return value for
`GeckoSession.PromptDelegate.ChoiceCallback.onPopupResult()`
- Added `default` implementations for all non-functional `interface`s.
## v66
- Removed redundant field `trackingMode` from [`SecurityInformation`][66.6].
Use `TrackingProtectionDelegate.onTrackerBlocked` for notification of blocked
@ -207,4 +209,4 @@ exclude: true
[65.24]: ../CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
[65.25]: ../GeckoResult.html
[api-version]: 577c3b0d000b0b1da57f9af32331f1e9045939b9
[api-version]: 09c473360eb5e17aa801fa0f966cd8671cf2f3d2