Bug 1502118 - Add @UiThread to all Delegate interfaces. r=snorp,esawin
authorAgi Sferro <agi@mozilla.com>
Mon, 17 Dec 2018 22:31:29 +0000
changeset 510999 95951162d7754a91e19172596ff5cb635291adf7
parent 510998 d36a924cbed6c6c6710eeb0b4b719f880d27d6b3
child 511000 0d938252d0ed11c83387e1501aee8ebac8df894a
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp, esawin
bugs1502118
milestone66.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 1502118 - Add @UiThread to all Delegate interfaces. r=snorp,esawin Differential Revision: https://phabricator.services.mozilla.com/D13880
mobile/android/geckoview/CHANGELOG.md
mobile/android/geckoview/api.txt
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/MediaElement.java
--- a/mobile/android/geckoview/CHANGELOG.md
+++ b/mobile/android/geckoview/CHANGELOG.md
@@ -24,9 +24,9 @@
 - Added `ContentDelegate.ContextElement` to extend the information passed to
   `ContentDelegate#onContextMenu`. Extended information includes the element's
   title and alt attributes.
 - Changed `ContentDelegate.ContextElement` TYPE_ constants to public access.
   Changed `ContentDelegate.ContextElement` to non-final class.
 - Update `CrashReporter.sendCrashReport()` to return the crash ID as a
   GeckoResult<String>.
 
-[api-version]: d6c40ef4886c7818a446fb7b7a1cdbde706025ab
+[api-version]: 8dd1c9e76471e6a1ee520e6c607ed6d3f9156fc2
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -156,17 +156,17 @@ package org.mozilla.geckoview {
     field public static final android.os.Parcelable.Creator<org.mozilla.geckoview.GeckoRuntime> CREATOR;
     field public static final java.lang.String EXTRA_CRASH_FATAL = "fatal";
     field public static final java.lang.String EXTRA_EXTRAS_PATH = "extrasPath";
     field public static final java.lang.String EXTRA_MINIDUMP_PATH = "minidumpPath";
     field public static final java.lang.String EXTRA_MINIDUMP_SUCCESS = "minidumpSuccess";
   }
 
   public static interface GeckoRuntime.Delegate {
-    method public void onShutdown();
+    method @android.support.annotation.UiThread public void onShutdown();
   }
 
   public final class GeckoRuntimeSettings implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.String[] getArguments();
     method public boolean getBlockMalware();
     method public boolean getBlockPhishing();
     method public boolean getConsoleOutputEnabled();
@@ -316,24 +316,24 @@ package org.mozilla.geckoview {
     field public static final int LOAD_FLAGS_BYPASS_PROXY = 2;
     field public static final int LOAD_FLAGS_EXTERNAL = 4;
     field public static final int LOAD_FLAGS_NONE = 0;
     field protected final org.mozilla.geckoview.GeckoSession.Compositor mCompositor;
     field protected org.mozilla.geckoview.GeckoSession.Window mWindow;
   }
 
   public static interface GeckoSession.ContentDelegate {
-    method public void onCloseRequest(org.mozilla.geckoview.GeckoSession);
-    method public void onContextMenu(org.mozilla.geckoview.GeckoSession, int, int, org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement);
-    method public void onCrash(org.mozilla.geckoview.GeckoSession);
-    method public void onExternalResponse(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.WebResponseInfo);
-    method public void onFirstComposite(org.mozilla.geckoview.GeckoSession);
-    method public void onFocusRequest(org.mozilla.geckoview.GeckoSession);
-    method public void onFullScreen(org.mozilla.geckoview.GeckoSession, boolean);
-    method public void onTitleChange(org.mozilla.geckoview.GeckoSession, java.lang.String);
+    method @android.support.annotation.UiThread public void onCloseRequest(org.mozilla.geckoview.GeckoSession);
+    method @android.support.annotation.UiThread public void onContextMenu(org.mozilla.geckoview.GeckoSession, int, int, org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement);
+    method @android.support.annotation.UiThread public void onCrash(org.mozilla.geckoview.GeckoSession);
+    method @android.support.annotation.UiThread public void onExternalResponse(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.WebResponseInfo);
+    method @android.support.annotation.UiThread public void onFirstComposite(org.mozilla.geckoview.GeckoSession);
+    method @android.support.annotation.UiThread public void onFocusRequest(org.mozilla.geckoview.GeckoSession);
+    method @android.support.annotation.UiThread public void onFullScreen(org.mozilla.geckoview.GeckoSession, boolean);
+    method @android.support.annotation.UiThread public void onTitleChange(org.mozilla.geckoview.GeckoSession, java.lang.String);
   }
 
   public static class GeckoSession.ContentDelegate.ContextElement {
     ctor protected ContextElement(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
     field public static final int TYPE_AUDIO = 3;
     field public static final int TYPE_IMAGE = 1;
     field public static final int TYPE_NONE = 0;
     field public static final int TYPE_VIDEO = 2;
@@ -352,41 +352,41 @@ package org.mozilla.geckoview {
     field public final boolean found;
     field public final java.lang.String linkUri;
     field public final java.lang.String searchString;
     field public final int total;
     field public final boolean wrapped;
   }
 
   public static interface GeckoSession.HistoryDelegate {
-    method public org.mozilla.geckoview.GeckoResult<boolean[]> getVisited(org.mozilla.geckoview.GeckoSession, java.lang.String[]);
-    method public org.mozilla.geckoview.GeckoResult<java.lang.Boolean> onVisited(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, int);
+    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<boolean[]> getVisited(org.mozilla.geckoview.GeckoSession, java.lang.String[]);
+    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<java.lang.Boolean> onVisited(org.mozilla.geckoview.GeckoSession, java.lang.String, 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;
     field public static final int VISIT_REDIRECT_TEMPORARY = 2;
     field public static final int VISIT_TOP_LEVEL = 1;
     field public static final int VISIT_UNRECOVERABLE_ERROR = 32;
   }
 
   public static interface GeckoSession.HistoryDelegate.VisitFlags implements java.lang.annotation.Annotation {
   }
 
   public static interface GeckoSession.MediaDelegate {
-    method public void onMediaAdd(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.MediaElement);
-    method public void onMediaRemove(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.MediaElement);
+    method @android.support.annotation.UiThread public void onMediaAdd(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.MediaElement);
+    method @android.support.annotation.UiThread public void onMediaRemove(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.MediaElement);
   }
 
   public static interface GeckoSession.NavigationDelegate {
-    method public void onCanGoBack(org.mozilla.geckoview.GeckoSession, boolean);
-    method public void onCanGoForward(org.mozilla.geckoview.GeckoSession, boolean);
-    method public org.mozilla.geckoview.GeckoResult<java.lang.String> onLoadError(org.mozilla.geckoview.GeckoSession, java.lang.String, org.mozilla.geckoview.WebRequestError);
-    method public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onLoadRequest(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.NavigationDelegate.LoadRequest);
-    method public void onLocationChange(org.mozilla.geckoview.GeckoSession, java.lang.String);
-    method public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.GeckoSession> onNewSession(org.mozilla.geckoview.GeckoSession, java.lang.String);
+    method @android.support.annotation.UiThread public void onCanGoBack(org.mozilla.geckoview.GeckoSession, boolean);
+    method @android.support.annotation.UiThread public void onCanGoForward(org.mozilla.geckoview.GeckoSession, boolean);
+    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<java.lang.String> onLoadError(org.mozilla.geckoview.GeckoSession, java.lang.String, org.mozilla.geckoview.WebRequestError);
+    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onLoadRequest(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.NavigationDelegate.LoadRequest);
+    method @android.support.annotation.UiThread public void onLocationChange(org.mozilla.geckoview.GeckoSession, java.lang.String);
+    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.GeckoSession> onNewSession(org.mozilla.geckoview.GeckoSession, 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;
     field public static final int TARGET_WINDOW_NONE = 0;
   }
 
   public static class GeckoSession.NavigationDelegate.LoadRequest {
     ctor protected LoadRequest();
@@ -395,33 +395,33 @@ package org.mozilla.geckoview {
     field public final java.lang.String triggerUri;
     field public final java.lang.String uri;
   }
 
   public static interface GeckoSession.NavigationDelegate.TargetWindow implements java.lang.annotation.Annotation {
   }
 
   public static interface GeckoSession.PermissionDelegate {
-    method public void onAndroidPermissionsRequest(org.mozilla.geckoview.GeckoSession, java.lang.String[], org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
-    method public void onContentPermissionRequest(org.mozilla.geckoview.GeckoSession, java.lang.String, int, org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
-    method public void onMediaPermissionRequest(org.mozilla.geckoview.GeckoSession, java.lang.String, org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaCallback);
+    method @android.support.annotation.UiThread public void onAndroidPermissionsRequest(org.mozilla.geckoview.GeckoSession, java.lang.String[], org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
+    method @android.support.annotation.UiThread public void onContentPermissionRequest(org.mozilla.geckoview.GeckoSession, java.lang.String, int, org.mozilla.geckoview.GeckoSession.PermissionDelegate.Callback);
+    method @android.support.annotation.UiThread public void onMediaPermissionRequest(org.mozilla.geckoview.GeckoSession, java.lang.String, org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource[], org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaCallback);
     field public static final int PERMISSION_AUTOPLAY_MEDIA = 2;
     field public static final int PERMISSION_DESKTOP_NOTIFICATION = 1;
     field public static final int PERMISSION_GEOLOCATION = 0;
   }
 
   public static interface GeckoSession.PermissionDelegate.Callback {
-    method public void grant();
-    method public void reject();
+    method @android.support.annotation.UiThread public void grant();
+    method @android.support.annotation.UiThread public void reject();
   }
 
   public static interface GeckoSession.PermissionDelegate.MediaCallback {
-    method public void grant(java.lang.String, java.lang.String);
-    method public void grant(org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource, org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource);
-    method public void reject();
+    method @android.support.annotation.UiThread public void grant(java.lang.String, java.lang.String);
+    method @android.support.annotation.UiThread public void grant(org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource, org.mozilla.geckoview.GeckoSession.PermissionDelegate.MediaSource);
+    method @android.support.annotation.UiThread public void reject();
   }
 
   public static class GeckoSession.PermissionDelegate.MediaSource {
     ctor protected MediaSource();
     field public static final int SOURCE_APPLICATION = 2;
     field public static final int SOURCE_AUDIOCAPTURE = 6;
     field public static final int SOURCE_BROWSER = 4;
     field public static final int SOURCE_CAMERA = 0;
@@ -437,20 +437,20 @@ package org.mozilla.geckoview {
     field public final int source;
     field public final int type;
   }
 
   public static interface GeckoSession.PermissionDelegate.Permission implements java.lang.annotation.Annotation {
   }
 
   public static interface GeckoSession.ProgressDelegate {
-    method public void onPageStart(org.mozilla.geckoview.GeckoSession, java.lang.String);
-    method public void onPageStop(org.mozilla.geckoview.GeckoSession, boolean);
-    method public void onProgressChange(org.mozilla.geckoview.GeckoSession, int);
-    method public void onSecurityChange(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.ProgressDelegate.SecurityInformation);
+    method @android.support.annotation.UiThread public void onPageStart(org.mozilla.geckoview.GeckoSession, java.lang.String);
+    method @android.support.annotation.UiThread public void onPageStop(org.mozilla.geckoview.GeckoSession, boolean);
+    method @android.support.annotation.UiThread public void onProgressChange(org.mozilla.geckoview.GeckoSession, int);
+    method @android.support.annotation.UiThread public void onSecurityChange(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.ProgressDelegate.SecurityInformation);
   }
 
   public static class GeckoSession.ProgressDelegate.SecurityInformation {
     ctor protected SecurityInformation();
     field public static final int CONTENT_BLOCKED = 1;
     field public static final int CONTENT_LOADED = 2;
     field public static final int CONTENT_UNKNOWN = 0;
     field public static final int SECURITY_MODE_IDENTIFIED = 1;
@@ -466,48 +466,48 @@ package org.mozilla.geckoview {
     field public final java.lang.String organization;
     field public final java.lang.String origin;
     field public final int securityMode;
     field public final java.lang.String subjectName;
     field public final int trackingMode;
   }
 
   public static interface GeckoSession.PromptDelegate {
-    method public void onAlert(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback);
-    method public void onAuthPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthOptions, org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthCallback);
-    method public void onButtonPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, java.lang.String[], org.mozilla.geckoview.GeckoSession.PromptDelegate.ButtonCallback);
-    method public void onChoicePrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, int, org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[], org.mozilla.geckoview.GeckoSession.PromptDelegate.ChoiceCallback);
-    method public void onColorPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
-    method public void onDateTimePrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
-    method public void onFilePrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, int, java.lang.String[], org.mozilla.geckoview.GeckoSession.PromptDelegate.FileCallback);
-    method public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onPopupRequest(org.mozilla.geckoview.GeckoSession, java.lang.String);
-    method public void onTextPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
+    method @android.support.annotation.UiThread public void onAlert(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback);
+    method @android.support.annotation.UiThread public void onAuthPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthOptions, org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthCallback);
+    method @android.support.annotation.UiThread public void onButtonPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, java.lang.String[], org.mozilla.geckoview.GeckoSession.PromptDelegate.ButtonCallback);
+    method @android.support.annotation.UiThread public void onChoicePrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, int, org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[], org.mozilla.geckoview.GeckoSession.PromptDelegate.ChoiceCallback);
+    method @android.support.annotation.UiThread public void onColorPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
+    method @android.support.annotation.UiThread public void onDateTimePrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, org.mozilla.geckoview.GeckoSession.PromptDelegate.TextCallback);
+    method @android.support.annotation.UiThread public void onFilePrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, int, java.lang.String[], org.mozilla.geckoview.GeckoSession.PromptDelegate.FileCallback);
+    method @android.support.annotation.UiThread public org.mozilla.geckoview.GeckoResult<org.mozilla.geckoview.AllowOrDeny> onPopupRequest(org.mozilla.geckoview.GeckoSession, java.lang.String);
+    method @android.support.annotation.UiThread public void onTextPrompt(org.mozilla.geckoview.GeckoSession, java.lang.String, java.lang.String, java.lang.String, 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;
     field public static final int DATETIME_TYPE_WEEK = 3;
     field public static final int FILE_TYPE_MULTIPLE = 2;
     field public static final int FILE_TYPE_SINGLE = 1;
   }
 
   public static interface GeckoSession.PromptDelegate.AlertCallback {
-    method public void dismiss();
-    method public java.lang.String getCheckboxMessage();
-    method public boolean getCheckboxValue();
-    method public boolean hasCheckbox();
-    method public void setCheckboxValue(boolean);
+    method @android.support.annotation.UiThread public void dismiss();
+    method @android.support.annotation.UiThread 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);
   }
 
   public static interface GeckoSession.PromptDelegate.AuthCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
-    method public void confirm(java.lang.String);
-    method public void confirm(java.lang.String, java.lang.String);
+    method @android.support.annotation.UiThread public void confirm(java.lang.String);
+    method @android.support.annotation.UiThread public void confirm(java.lang.String, java.lang.String);
   }
 
   public static class GeckoSession.PromptDelegate.AuthOptions {
     ctor protected AuthOptions();
     field public static final int AUTH_FLAG_CROSS_ORIGIN_SUB_RESOURCE = 32;
     field public static final int AUTH_FLAG_HOST = 1;
     field public static final int AUTH_FLAG_ONLY_PASSWORD = 8;
     field public static final int AUTH_FLAG_PREVIOUS_FAILED = 16;
@@ -518,17 +518,17 @@ package org.mozilla.geckoview {
     field public int flags;
     field public int level;
     field public java.lang.String password;
     field public java.lang.String uri;
     field public java.lang.String username;
   }
 
   public static interface GeckoSession.PromptDelegate.ButtonCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
-    method public void confirm(int);
+    method @android.support.annotation.UiThread public void confirm(int);
   }
 
   public static class GeckoSession.PromptDelegate.Choice {
     ctor protected Choice();
     field public static final int CHOICE_TYPE_MENU = 1;
     field public static final int CHOICE_TYPE_MULTIPLE = 3;
     field public static final int CHOICE_TYPE_SINGLE = 2;
     field public final boolean disabled;
@@ -536,44 +536,44 @@ package org.mozilla.geckoview {
     field public final java.lang.String id;
     field public final org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[] items;
     field public final java.lang.String label;
     field public final boolean selected;
     field public final boolean separator;
   }
 
   public static interface GeckoSession.PromptDelegate.ChoiceCallback implements org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertCallback {
-    method public void confirm(java.lang.String);
-    method public void confirm(java.lang.String[]);
-    method public void confirm(org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice);
-    method public void confirm(org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice[]);
+    method @android.support.annotation.UiThread public void confirm(java.lang.String);
+    method @android.support.annotation.UiThread public void confirm(java.lang.String[]);
+    method @android.support.annotation.UiThread public void confirm(org.mozilla.geckoview.GeckoSession.PromptDelegate.Choice);
+    method @android.support.annotation.UiThread public void confirm(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 public void confirm(android.content.Context, android.net.Uri);
-    method public void confirm(android.content.Context, android.net.Uri[]);
+    method @android.support.annotation.UiThread public void confirm(android.content.Context, android.net.Uri);
+    method @android.support.annotation.UiThread public void confirm(android.content.Context, 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 public void confirm(java.lang.String);
+    method @android.support.annotation.UiThread public void confirm(java.lang.String);
   }
 
   public static interface GeckoSession.ScrollDelegate {
-    method public void onScrollChanged(org.mozilla.geckoview.GeckoSession, int, int);
+    method @android.support.annotation.UiThread public void onScrollChanged(org.mozilla.geckoview.GeckoSession, int, int);
   }
 
   public static interface GeckoSession.SelectionActionDelegate {
-    method public void onHideAction(org.mozilla.geckoview.GeckoSession, int);
-    method public void onShowActionRequest(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.SelectionActionDelegate.Selection, java.lang.String[], org.mozilla.geckoview.GeckoResponse<java.lang.String>);
+    method @android.support.annotation.UiThread public void onHideAction(org.mozilla.geckoview.GeckoSession, int);
+    method @android.support.annotation.UiThread public void onShowActionRequest(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.SelectionActionDelegate.Selection, java.lang.String[], 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";
     field public static final java.lang.String ACTION_CUT = "org.mozilla.geckoview.CUT";
     field public static final java.lang.String ACTION_DELETE = "org.mozilla.geckoview.DELETE";
     field public static final java.lang.String ACTION_HIDE = "org.mozilla.geckoview.HIDE";
     field public static final java.lang.String ACTION_PASTE = "org.mozilla.geckoview.PASTE";
     field public static final java.lang.String ACTION_SELECT_ALL = "org.mozilla.geckoview.SELECT_ALL";
@@ -635,17 +635,17 @@ package org.mozilla.geckoview {
 
   public static interface GeckoSession.TextInputDelegate.AutoFillNotification implements java.lang.annotation.Annotation {
   }
 
   public static interface GeckoSession.TextInputDelegate.RestartReason implements java.lang.annotation.Annotation {
   }
 
   public static interface GeckoSession.TrackingProtectionDelegate {
-    method public void onTrackerBlocked(org.mozilla.geckoview.GeckoSession, java.lang.String, int);
+    method @android.support.annotation.UiThread public void onTrackerBlocked(org.mozilla.geckoview.GeckoSession, java.lang.String, int);
     field public static final int CATEGORY_AD = 1;
     field public static final int CATEGORY_ALL = 31;
     field public static final int CATEGORY_ANALYTIC = 2;
     field public static final int CATEGORY_CONTENT = 8;
     field public static final int CATEGORY_NONE = 0;
     field public static final int CATEGORY_SOCIAL = 4;
     field public static final int CATEGORY_TEST = 16;
   }
@@ -783,25 +783,25 @@ package org.mozilla.geckoview {
     field public static final int MEDIA_STATE_SUSPEND = 7;
     field public static final int MEDIA_STATE_WAITING = 8;
     field protected org.mozilla.geckoview.MediaElement.Delegate mDelegate;
     field protected final org.mozilla.geckoview.GeckoSession mSession;
     field protected final long mVideoId;
   }
 
   public static interface MediaElement.Delegate {
-    method public void onError(org.mozilla.geckoview.MediaElement, int);
-    method public void onFullscreenChange(org.mozilla.geckoview.MediaElement, boolean);
-    method public void onLoadProgress(org.mozilla.geckoview.MediaElement, org.mozilla.geckoview.MediaElement.LoadProgressInfo);
-    method public void onMetadataChange(org.mozilla.geckoview.MediaElement, org.mozilla.geckoview.MediaElement.Metadata);
-    method public void onPlaybackRateChange(org.mozilla.geckoview.MediaElement, double);
-    method public void onPlaybackStateChange(org.mozilla.geckoview.MediaElement, int);
-    method public void onReadyStateChange(org.mozilla.geckoview.MediaElement, int);
-    method public void onTimeChange(org.mozilla.geckoview.MediaElement, double);
-    method public void onVolumeChange(org.mozilla.geckoview.MediaElement, double, boolean);
+    method @android.support.annotation.UiThread public void onError(org.mozilla.geckoview.MediaElement, int);
+    method @android.support.annotation.UiThread public void onFullscreenChange(org.mozilla.geckoview.MediaElement, boolean);
+    method @android.support.annotation.UiThread public void onLoadProgress(org.mozilla.geckoview.MediaElement, org.mozilla.geckoview.MediaElement.LoadProgressInfo);
+    method @android.support.annotation.UiThread public void onMetadataChange(org.mozilla.geckoview.MediaElement, org.mozilla.geckoview.MediaElement.Metadata);
+    method @android.support.annotation.UiThread public void onPlaybackRateChange(org.mozilla.geckoview.MediaElement, double);
+    method @android.support.annotation.UiThread public void onPlaybackStateChange(org.mozilla.geckoview.MediaElement, int);
+    method @android.support.annotation.UiThread public void onReadyStateChange(org.mozilla.geckoview.MediaElement, int);
+    method @android.support.annotation.UiThread public void onTimeChange(org.mozilla.geckoview.MediaElement, double);
+    method @android.support.annotation.UiThread public void onVolumeChange(org.mozilla.geckoview.MediaElement, double, boolean);
   }
 
   public static class MediaElement.LoadProgressInfo {
     ctor protected LoadProgressInfo();
     field public final org.mozilla.geckoview.MediaElement.LoadProgressInfo.TimeRange[] buffered;
     field public final long loadedBytes;
     field public final long totalBytes;
   }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
@@ -297,16 +297,17 @@ public final class GeckoRuntime implemen
         GeckoThread.forceQuit();
     }
 
     public interface Delegate {
         /**
          * This is called when the runtime shuts down. Any GeckoSession instances that were
          * opened with this instance are now considered closed.
          **/
+        @UiThread
         void onShutdown();
     }
 
     /**
      * Set a delegate for receiving callbacks relevant to to this GeckoRuntime.
      *
      * @param delegate an implementation of {@link GeckoRuntime.Delegate}.
      */
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -2476,37 +2476,41 @@ 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(GeckoSession session, 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(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(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(GeckoSession session, SecurityInformation securityInfo);
     }
 
     /**
      * WebResponseInfo contains information about a single web response.
      */
     static public class WebResponseInfo {
         /**
@@ -2554,39 +2558,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(GeckoSession session, 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(GeckoSession session);
 
         /**
         * A page has requested to close
         * @param session The GeckoSession that initiated the callback.
         */
+        @UiThread
         void onCloseRequest(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(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})
@@ -2653,46 +2661,50 @@ public class GeckoSession implements Par
          * This event is fired on links, (nested) images and (nested) media
          * 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);
 
         /**
          * 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(GeckoSession session, 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(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(GeckoSession session);
     }
 
     public interface SelectionActionDelegate {
         @Retention(RetentionPolicy.SOURCE)
         @IntDef(flag = true, value = {FLAG_IS_COLLAPSED,
                                       FLAG_IS_EDITABLE})
         /* package */ @interface Flag {}
@@ -2835,16 +2847,17 @@ public class GeckoSession implements Par
          * @param session The GeckoSession that initiated the callback.
          * @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(GeckoSession session, Selection selection,
                                  @Action String[] actions, GeckoResponse<String> response);
 
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({HIDE_REASON_NO_SELECTION,
                  HIDE_REASON_INVISIBLE_SELECTION,
                  HIDE_REASON_ACTIVE_SELECTION,
                  HIDE_REASON_ACTIVE_SCROLL})
@@ -2876,39 +2889,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(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(GeckoSession session, 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(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(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;
@@ -2987,39 +3004,42 @@ public class GeckoSession implements Par
          * @param session The GeckoSession that initiated the callback.
          * @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);
 
         /**
         * 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);
 
         /**
          * @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
         GeckoResult<String> onLoadError(GeckoSession session, String uri, WebRequestError error);
     }
 
     /**
      * GeckoSession applications implement this interface to handle prompts triggered by
      * content in the GeckoSession, such as alerts, authentication dialogs, and select list
      * pickers.
      **/
@@ -3029,71 +3049,78 @@ public class GeckoSession implements Par
          * optional features for prompts (e.g. optional checkbox).
          */
         interface AlertCallback {
             /**
              * Called by the prompt implementation when the prompt is dismissed without a
              * result, for example if the user presses the "Back" button. All prompts
              * must call dismiss() or confirm(), if available, when the prompt is dismissed.
              */
+            @UiThread
             void dismiss();
 
             /**
              * Return whether the prompt shown should include a checkbox. For example, if
              * a page shows multiple prompts within a short period of time, the next
              * prompt will include a checkbox to let the user disable future prompts.
              * Although the API allows checkboxes for all prompts, in practice, only
              * alert/button/text/auth prompts will possibly have a checkbox.
              *
              * @return True if prompt includes a checkbox.
              */
+            @UiThread
             boolean hasCheckbox();
 
             /**
              * Return the message label for the optional checkbox.
              *
              * @return Checkbox message or null if none.
              */
+            @UiThread
             String getCheckboxMessage();
 
             /**
              * Return the initial value for the optional checkbox.
              *
              * @return Initial checkbox value.
              */
+            @UiThread
             boolean getCheckboxValue();
 
             /**
              * Set the current value for the optional checkbox.
              *
              * @param value New checkbox value.
              */
+            @UiThread
             void setCheckboxValue(boolean value);
         }
 
         /**
          * 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(GeckoSession session, String title, String msg, AlertCallback callback);
 
         /**
          * 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.
              *
              * @param button Button result; one of BUTTON_TYPE_* constants.
              */
+            @UiThread
             void confirm(int button);
         }
 
         static final int BUTTON_TYPE_POSITIVE = 0;
         static final int BUTTON_TYPE_NEUTRAL = 1;
         static final int BUTTON_TYPE_NEGATIVE = 2;
 
         /**
@@ -3104,64 +3131,69 @@ public class GeckoSession implements Par
          * @param msg Message for the prompt dialog.
          * @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(GeckoSession session, String title, String msg,
                              String[] btnMsg, ButtonCallback callback);
 
         /**
          * 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
              * the user, for example by pressing the "OK" button.
              *
              * @param text Text result.
              */
+            @UiThread
             void confirm(String text);
         }
 
         /**
          * Display a prompt for inputting text.
          *
          * @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(GeckoSession session, String title, String msg,
                            String value, TextCallback callback);
 
         /**
          * 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.
              *
              * @param password Entered password.
              */
+            @UiThread
             void confirm(String password);
 
             /**
              * Called by the prompt implementation when a username/password prompt is
              * confirmed by the user.
              *
              * @param username Entered username.
              * @param password Entered password.
              */
+            @UiThread
             void confirm(String username, String password);
         }
 
         class AuthOptions {
             @Retention(RetentionPolicy.SOURCE)
             @IntDef(flag = true,
                     value = {AUTH_FLAG_HOST, AUTH_FLAG_PROXY,
                              AUTH_FLAG_ONLY_PASSWORD, AUTH_FLAG_PREVIOUS_FAILED,
@@ -3255,16 +3287,17 @@ public class GeckoSession implements Par
          * Display a prompt for authentication credentials.
          *
          * @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(GeckoSession session, String title, String msg,
                            AuthOptions options, AuthCallback callback);
 
         class Choice {
             @Retention(RetentionPolicy.SOURCE)
             @IntDef({CHOICE_TYPE_MENU, CHOICE_TYPE_SINGLE, CHOICE_TYPE_MULTIPLE})
             /* package */ @interface ChoiceType {}
 
@@ -3360,69 +3393,75 @@ public class GeckoSession implements Par
          */
         interface ChoiceCallback extends AlertCallback {
             /**
              * Called by the prompt implementation when the menu or single-choice list is
              * dismissed by the user.
              *
              * @param id ID of the selected item.
              */
+            @UiThread
             void confirm(String id);
 
             /**
              * Called by the prompt implementation when the multiple-choice list is
              * dismissed by the user.
              *
              * @param ids IDs of the selected items.
              */
+            @UiThread
             void confirm(String[] ids);
 
             /**
              * Called by the prompt implementation when the menu or single-choice list is
              * dismissed by the user.
              *
              * @param item Choice representing the selected item; must be an original
              *             Choice object that was passed to the implementation.
              */
+            @UiThread
             void confirm(Choice item);
 
             /**
              * Called by the prompt implementation when the multiple-choice list is
              * dismissed by the user.
              *
              * @param items Choice array representing the selected items; must be original
              *              Choice objects that were passed to the implementation.
              */
+            @UiThread
             void confirm(Choice[] items);
         }
 
 
         /**
          * Display a menu prompt or list prompt.
          *
          * @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(GeckoSession session, String title, String msg,
                             @Choice.ChoiceType int type, Choice[] choices,
                             ChoiceCallback callback);
 
         /**
          * 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(GeckoSession session, String title, String value,
                             TextCallback callback);
 
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({DATETIME_TYPE_DATE, DATETIME_TYPE_MONTH, DATETIME_TYPE_WEEK,
                  DATETIME_TYPE_TIME, DATETIME_TYPE_DATETIME_LOCAL})
         /* package */ @interface DatetimeType {}
 
@@ -3458,40 +3497,43 @@ public class GeckoSession implements Par
          * @param title Title for the prompt dialog; currently always null.
          * @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(GeckoSession session, String title,
                               @DatetimeType int type, String value, String min,
                               String max, TextCallback callback);
 
         /**
          * 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.
              *
              * @param context An application Context for parsing URIs.
              * @param uri The URI of the selected file.
              */
+            @UiThread
             void confirm(Context context, Uri uri);
 
             /**
              * Called by the prompt implementation when the user makes file selections in
              * multiple-selection mode.
              *
              * @param context An application Context for parsing URIs.
              * @param uris Array of URI objects for the selected files.
              */
+            @UiThread
             void confirm(Context context, Uri[] uris);
         }
 
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({FILE_TYPE_SINGLE, FILE_TYPE_MULTIPLE})
         /* package */ @interface FileType {}
         static final int FILE_TYPE_SINGLE = 1;
         static final int FILE_TYPE_MULTIPLE = 2;
@@ -3502,44 +3544,47 @@ public class GeckoSession implements Par
          * @param session GeckoSession that triggered the prompt
          * @param title Title for the prompt dialog.
          * @param type One of FILE_TYPE_* indicating the prompt type.
          * @param mimeTypes Array of permissible MIME types for the selected files, in
          *                  the form "type/subtype", where "type" and/or "subtype" can be
          *                  "*" to indicate any value.
          * @param callback Callback interface.
          */
+        @UiThread
         void onFilePrompt(GeckoSession session, String title, @FileType int type,
                           String[] mimeTypes, FileCallback callback);
 
         /**
          * 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(GeckoSession session, String targetUri);
     }
 
     /**
      * 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(GeckoSession session, int scrollX, int scrollY);
     }
 
     /**
      * Get the PanZoomController instance for this session.
      *
      * @return PanZoomController instance.
      */
@@ -3745,16 +3790,17 @@ public class GeckoSession implements Par
          * Set blocked tracker categories via GeckoRuntimeSettings and enable
          * tracking protection via GeckoSessionSettings.
          *
         * @param session The GeckoSession that initiated the callback.
         * @param uri The URI of the blocked element.
         * @param categories The tracker categories of the blocked element.
         *                   One or more of the {@link #CATEGORY_AD CATEGORY_*} flags.
         */
+        @UiThread
         void onTrackerBlocked(GeckoSession session, String uri,
                               @Category int categories);
     }
 
     /**
      * GeckoSession applications implement this interface to handle requests for permissions
      * from content, such as geolocation and notifications. For each permission, usually
      * two requests are generated: one request for the Android app permission through
@@ -3788,50 +3834,54 @@ public class GeckoSession implements Par
         /**
          * Callback interface for notifying the result of a permission request.
          */
         interface Callback {
             /**
              * Called by the implementation after permissions are granted; the
              * implementation must call either grant() or reject() for every request.
              */
+            @UiThread
             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();
         }
 
         /**
          * Request Android app permissions.
          *
          * @param session GeckoSession instance requesting the permissions.
          * @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(GeckoSession session, String[] permissions,
                                          Callback callback);
 
         /**
          * 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
          *             PERMISSION_AUTOPLAY_MEDIA
          * @param callback Callback interface.
          */
+        @UiThread
         void onContentPermissionRequest(GeckoSession session, String uri,
                                         @Permission int type, Callback callback);
 
         class MediaSource {
             @Retention(RetentionPolicy.SOURCE)
             @IntDef({SOURCE_CAMERA, SOURCE_SCREEN, SOURCE_APPLICATION,
                      SOURCE_WINDOW, SOURCE_BROWSER, SOURCE_MICROPHONE,
                      SOURCE_AUDIOCAPTURE, SOURCE_OTHER})
@@ -3985,48 +4035,52 @@ public class GeckoSession implements Par
              * Called by the implementation after permissions are granted; the
              * implementation must call one of grant() or reject() for every request.
              *
              * @param video "id" value from the bundle for the video source to use,
              *              or null when video is not requested.
              * @param audio "id" value from the bundle for the audio source to use,
              *              or null when audio is not requested.
              */
+            @UiThread
             void grant(final String video, final String audio);
 
             /**
              * Called by the implementation after permissions are granted; the
              * implementation must call one of grant() or reject() for every request.
              *
              * @param video MediaSource for the video source to use (must be an original
              *              MediaSource object that was passed to the implementation);
              *              or null when video is not requested.
              * @param audio MediaSource for the audio source to use (must be an original
              *              MediaSource object that was passed to the implementation);
              *              or null when audio is not requested.
              */
+            @UiThread
             void grant(final MediaSource video, final 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();
         }
 
         /**
          * Request content media permissions, including request for which video and/or
          * audio source to use.
          *
          * @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(GeckoSession session, String uri, MediaSource[] video,
                                       MediaSource[] audio, MediaCallback callback);
     }
 
     /**
      * 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.
@@ -4405,22 +4459,24 @@ public class GeckoSession implements Par
      * GeckoSession applications implement this interface to handle media events.
      */
     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);
         /**
          * 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);
     }
 
     /**
      * An interface for recording new history visits and fetching the visited
      * status for links.
      */
     public interface HistoryDelegate {
@@ -4458,16 +4514,17 @@ public class GeckoSession implements Par
          *                       redirects and reloads.
          * @param flags Additional flags for this visit, including redirect and
          *              error statuses. This is a bitmask of one or more
          *              {@link VisitFlags}, OR-ed together.
          * @return A {@link GeckoResult} completed with a boolean indicating
          *         whether to highlight links for the new URL as visited
          *         ({@code true}) or unvisited ({@code false}).
          */
+        @UiThread
         default @Nullable GeckoResult<Boolean> onVisited(@NonNull GeckoSession session,
                                                          @NonNull String url,
                                                          @Nullable String lastVisitedURL,
                                                          @VisitFlags int flags) {
             return null;
         }
 
         /**
@@ -4476,14 +4533,15 @@ public class GeckoSession implements Par
          *
          * @param session The session requesting the visited statuses.
          * @param urls A list of URLs to check.
          * @return A {@link GeckoResult} completed with a list of booleans
          *         corresponding to the URLs in {@code urls}, and indicating
          *         whether to highlight links for each URL as visited
          *         ({@code true}) or unvisited ({@code false}).
          */
+        @UiThread
         default @Nullable GeckoResult<boolean[]> getVisited(@NonNull GeckoSession session,
                                                             @NonNull String[] urls) {
             return null;
         }
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/MediaElement.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/MediaElement.java
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.geckoview;
 
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
 import android.util.Log;
 
 import org.mozilla.gecko.util.GeckoBundle;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 /**
@@ -282,83 +283,92 @@ public class MediaElement {
     public interface Delegate {
         /**
          * The media playback state has changed.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param mediaState The playback state of the media.
          *                   One of the {@link #MEDIA_STATE_PLAY MEDIA_STATE_*} flags.
          */
+        @UiThread
         void onPlaybackStateChange(MediaElement mediaElement, @MediaStateFlags int mediaState);
 
         /**
          * The readiness state of the media has changed.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param readyState The readiness state of the media.
          *                   One of the {@link #MEDIA_READY_STATE_HAVE_NOTHING MEDIA_READY_STATE_*} flags.
          */
+        @UiThread
         void onReadyStateChange(MediaElement mediaElement, @ReadyStateFlags int readyState);
 
         /**
          * The media metadata has loaded or changed.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param metaData The MetaData values of the media.
          */
+        @UiThread
         void onMetadataChange(MediaElement mediaElement, Metadata metaData);
 
         /**
          * Indicates that a loading operation is in progress for the media.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param progressInfo Information about the load progress and buffered ranges.
          */
+        @UiThread
         void onLoadProgress(MediaElement mediaElement, LoadProgressInfo progressInfo);
 
         /**
          * The media audio volume has changed.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param volume The volume of the media.
          * @param muted True if the media is muted.
          */
+        @UiThread
         void onVolumeChange(MediaElement mediaElement, double volume, boolean muted);
 
         /**
          * The current playback time has changed. This event is usually dispatched every 250ms.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param time The current playback time in seconds.
          */
+        @UiThread
         void onTimeChange(MediaElement mediaElement, double time);
 
         /**
          * The media playback speed has changed.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param rate The current playback rate. A value of 1.0 indicates normal speed.
          */
+        @UiThread
         void onPlaybackRateChange(MediaElement mediaElement, double rate);
 
         /**
          * A media element has entered or exited fullscreen mode.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param fullscreen True if the media has entered full screen mode.
          */
+        @UiThread
         void onFullscreenChange(MediaElement mediaElement, boolean fullscreen);
 
         /**
          * An error has occurred.
          *
          * @param mediaElement A reference to the MediaElement that dispatched the event.
          * @param errorCode The error code.
          *                  One of the {@link #MEDIA_ERROR_NETWORK_NO_SOURCE MEDIA_ERROR_*} flags.
          */
+        @UiThread
         void onError(MediaElement mediaElement, @MediaErrorFlags int errorCode);
     }
 
     /* package */ long getVideoId() {
         return mVideoId;
     }
 
     /**