Backed out 7 changesets (bug 1500155) for multiple Android fails CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Wed, 12 Dec 2018 16:24:36 +0200
changeset 450271 f7c35130959cdc3d2711c2588d88d471f1d3beb8
parent 450270 34b839130e5fa3ceb596d2afbc9b59b147755078
child 450272 077802d9610e0d98fe606fa0e44d9408310572b5
push id35194
push usercsabou@mozilla.com
push dateWed, 12 Dec 2018 21:53:36 +0000
treeherdermozilla-central@c9fa642e9e3a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1500155
milestone66.0a1
backs out0f66513c5f234d93889f4fd2c6e5e0bcee0b75ef
85900c298b050ff0191954eacb92e4a4f11c741c
c4bc2e839a9e28b83802caf99d2ecf5eddd14e65
4dd0b1c3524cafe7cfe7ba5d10105324b4906895
0d03623732b6f0ee20cb02c7446ae1086c48b13f
fcfa609101f8e4efb877d10e4ff6a65ddc286eb6
a9410d9b3f16d13be22b81701f890ba7af676697
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
Backed out 7 changesets (bug 1500155) for multiple Android fails CLOSED TREE Backed out changeset 0f66513c5f23 (bug 1500155) Backed out changeset 85900c298b05 (bug 1500155) Backed out changeset c4bc2e839a9e (bug 1500155) Backed out changeset 4dd0b1c3524c (bug 1500155) Backed out changeset 0d03623732b6 (bug 1500155) Backed out changeset fcfa609101f8 (bug 1500155) Backed out changeset a9410d9b3f16 (bug 1500155)
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/VirtualPresentation.java
mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
mobile/android/geckoview/CHANGELOG.md
mobile/android/geckoview/api.txt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SessionLifecycleTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/crash/RemoteGeckoService.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -1082,20 +1082,19 @@ public abstract class GeckoApp extends G
         setContentView(getLayout());
 
         // Set up Gecko layout.
         mRootLayout = (RelativeLayout) findViewById(R.id.root_layout);
         mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
         mMainLayout = (RelativeLayout) findViewById(R.id.main_layout);
         mLayerView = (GeckoView) findViewById(R.id.layer_view);
 
-        final GeckoSession session = new GeckoSession(
-                new GeckoSessionSettings.Builder()
-                        .chromeUri("chrome://browser/content/browser.xul")
-                        .build());
+        final GeckoSession session = new GeckoSession();
+        session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
+                                        "chrome://browser/content/browser.xul");
         session.setContentDelegate(this);
 
         // If the view already has a session, we need to ensure it is closed.
         if (mLayerView.getSession() != null) {
             mLayerView.getSession().close();
         }
         mLayerView.setSession(session, GeckoApplication.getRuntime());
         mLayerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
--- a/mobile/android/base/java/org/mozilla/gecko/VirtualPresentation.java
+++ b/mobile/android/base/java/org/mozilla/gecko/VirtualPresentation.java
@@ -40,20 +40,20 @@ class VirtualPresentation extends CastPr
         super.onCreate(savedInstanceState);
 
         /*
          * NOTICE: The context get from getContext() is different to the context
          * of the application. Presentaion has its own context to get correct
          * resources.
          */
 
-        final GeckoSession session = new GeckoSession(new GeckoSessionSettings.Builder()
-                .chromeUri(PRESENTATION_VIEW_URI + "#" + deviceId)
-                .screenId(screenId)
-                .build());
+        final GeckoSession session = new GeckoSession();
+        session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
+                PRESENTATION_VIEW_URI + "#" + deviceId);
+        session.getSettings().setInt(GeckoSessionSettings.SCREEN_ID, screenId);
 
         // Create new GeckoView
         view = new GeckoView(getContext());
         view.setSession(session, GeckoApplication.ensureRuntime(getContext()));
         view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                 LayoutParams.MATCH_PARENT));
 
         // Create new layout to put the GeckoView
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -118,19 +118,18 @@ public class CustomTabsActivity extends 
 
         actionBarPresenter = new ActionBarPresenter(actionBar, getActionBarTextColor());
         actionBarPresenter.displayUrlOnly(intent.getDataString());
         actionBarPresenter.setBackgroundColor(IntentUtil.getToolbarColor(intent), getWindow());
         actionBarPresenter.setTextLongClickListener(new UrlCopyListener());
 
         mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
 
-        final GeckoSessionSettings settings = new GeckoSessionSettings.Builder()
-                .useMultiprocess(false)
-                .build();
+        final GeckoSessionSettings settings = new GeckoSessionSettings();
+        settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
         mGeckoSession = new GeckoSession(settings);
         mGeckoSession.setNavigationDelegate(this);
         mGeckoSession.setProgressDelegate(this);
         mGeckoSession.setContentDelegate(this);
 
         mGeckoView.setSession(mGeckoSession, GeckoApplication.ensureRuntime(this));
 
         mPromptService = new PromptService(this, mGeckoView.getEventDispatcher());
--- a/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
@@ -93,19 +93,18 @@ public class WebAppActivity extends AppC
         } else {
             Telemetry.sendUIEvent(TelemetryContract.Event.PWA, TelemetryContract.Method.HOMESCREEN);
         }
 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.webapp_activity);
         mGeckoView = (GeckoView) findViewById(R.id.pwa_gecko_view);
 
-        final GeckoSessionSettings settings = new GeckoSessionSettings.Builder()
-                .useMultiprocess(false)
-                .build();
+        final GeckoSessionSettings settings = new GeckoSessionSettings();
+        settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
         mGeckoSession = new GeckoSession(settings);
         mGeckoView.setSession(mGeckoSession, GeckoApplication.ensureRuntime(this));
 
         mGeckoSession.setNavigationDelegate(this);
         mGeckoSession.setContentDelegate(this);
         mGeckoSession.setProgressDelegate(new GeckoSession.ProgressDelegate() {
             @Override
             public void onPageStart(GeckoSession session, String url) {
@@ -315,17 +314,17 @@ public class WebAppActivity extends AppC
                 mode = GeckoSessionSettings.DISPLAY_MODE_MINIMAL_UI;
                 break;
             case "browser":
             default:
                 mode = GeckoSessionSettings.DISPLAY_MODE_BROWSER;
                 break;
         }
 
-        mGeckoSession.getSettings().setDisplayMode(mode);
+        mGeckoSession.getSettings().setInt(GeckoSessionSettings.DISPLAY_MODE, mode);
     }
 
     @Override // GeckoSession.NavigationDelegate
     public void onLocationChange(GeckoSession session, String url) {
     }
 
     @Override // GeckoSession.NavigationDelegate
     public void onCanGoBack(GeckoSession session, boolean canGoBack) {
--- a/mobile/android/geckoview/CHANGELOG.md
+++ b/mobile/android/geckoview/CHANGELOG.md
@@ -23,11 +23,10 @@
   can mock these classes in tests.
 - 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>.
-  - Added methods for each setting in `GeckoSessionSettings`
 
-[api-version]: 0c3293d38c5723b34aeb348a44c8eb47dcc0253a
+[api-version]: d6c40ef4886c7818a446fb7b7a1cdbde706025ab
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -661,63 +661,45 @@ package org.mozilla.geckoview {
     field public final java.lang.String uri;
   }
 
   public final class GeckoSessionSettings implements android.os.Parcelable {
     ctor public GeckoSessionSettings();
     ctor public GeckoSessionSettings(org.mozilla.geckoview.GeckoSessionSettings);
     method public int describeContents();
     method public boolean equals(java.lang.Object);
-    method public boolean getAllowJavascript();
-    method public java.lang.String getChromeUri();
-    method public int getDisplayMode();
-    method public boolean getFullAccessibilityTree();
-    method public int getScreenId();
-    method public boolean getSuspendMediaWhenInactive();
-    method public boolean getUseMultiprocess();
-    method public boolean getUsePrivateMode();
-    method public boolean getUseTrackingProtection();
-    method public int getUserAgentMode();
-    method public java.lang.String getUserAgentOverride();
+    method public boolean getBoolean(org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean>);
+    method public int getInt(org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Integer>);
+    method public java.lang.String getString(org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.String>);
     method public int hashCode();
     method public void readFromParcel(android.os.Parcel);
-    method public void setAllowJavascript(boolean);
-    method public void setDisplayMode(int);
-    method public void setFullAccessibilityTree(boolean);
-    method public void setSuspendMediaWhenInactive(boolean);
-    method public void setUseTrackingProtection(boolean);
-    method public void setUserAgentMode(int);
-    method public void setUserAgentOverride(java.lang.String);
+    method public void setBoolean(org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean>, boolean);
+    method public void setInt(org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Integer>, int);
+    method public void setString(org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.String>, java.lang.String);
     method public java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean> ALLOW_JAVASCRIPT;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.String> CHROME_URI;
     field public static final android.os.Parcelable.Creator<org.mozilla.geckoview.GeckoSessionSettings> CREATOR;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Integer> DISPLAY_MODE;
     field public static final int DISPLAY_MODE_BROWSER = 0;
     field public static final int DISPLAY_MODE_FULLSCREEN = 3;
     field public static final int DISPLAY_MODE_MINIMAL_UI = 1;
     field public static final int DISPLAY_MODE_STANDALONE = 2;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean> FULL_ACCESSIBILITY_TREE;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Integer> SCREEN_ID;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean> SUSPEND_MEDIA_WHEN_INACTIVE;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Integer> USER_AGENT_MODE;
     field public static final int USER_AGENT_MODE_DESKTOP = 1;
     field public static final int USER_AGENT_MODE_MOBILE = 0;
     field public static final int USER_AGENT_MODE_VR = 2;
-  }
-
-  public static final class GeckoSessionSettings.Builder {
-    ctor public Builder();
-    ctor public Builder(org.mozilla.geckoview.GeckoSessionSettings);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder allowJavascript(boolean);
-    method public org.mozilla.geckoview.GeckoSessionSettings build();
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder chromeUri(java.lang.String);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder displayMode(int);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder fullAccessibilityTree(boolean);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder screenId(int);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder suspendMediaWhenInactive(boolean);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder useMultiprocess(boolean);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder usePrivateMode(boolean);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder useTrackingProtection(boolean);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder userAgentMode(int);
-    method public org.mozilla.geckoview.GeckoSessionSettings.Builder userAgentOverride(java.lang.String);
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.String> USER_AGENT_OVERRIDE;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean> USE_MULTIPROCESS;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean> USE_PRIVATE_MODE;
+    field public static final org.mozilla.geckoview.GeckoSessionSettings.Key<java.lang.Boolean> USE_TRACKING_PROTECTION;
   }
 
   public static class GeckoSessionSettings.Key<T> {
   }
 
   public class GeckoView extends android.widget.FrameLayout {
     ctor public GeckoView(android.content.Context);
     ctor public GeckoView(android.content.Context, android.util.AttributeSet);
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -3,16 +3,17 @@
  * 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.test
 
 import android.os.Parcel
 import android.support.test.InstrumentationRegistry
 import org.mozilla.geckoview.GeckoSession
+import org.mozilla.geckoview.GeckoSessionSettings
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
 
 import org.hamcrest.Matcher
 import org.hamcrest.Matchers
 import org.junit.Assume.assumeThat
 import org.junit.Rule
 import org.junit.rules.ErrorCollector
 
@@ -67,17 +68,17 @@ open class BaseSessionTest(noErrorCollec
 
     fun <T> forEachCall(vararg values: T): T = sessionRule.forEachCall(*values)
 
     fun getTestBytes(path: String) =
             InstrumentationRegistry.getTargetContext().resources.assets
                     .open(path.removePrefix("/assets/")).readBytes()
 
     val GeckoSession.isRemote
-        get() = this.settings.getUseMultiprocess()
+        get() = this.settings.getBoolean(GeckoSessionSettings.USE_MULTIPROCESS)
 
     fun createTestUrl(path: String) =
             GeckoSessionTestRule.APK_URI_PREFIX + path.removePrefix("/")
 
     fun GeckoSession.loadTestPath(path: String) =
             this.loadUri(createTestUrl(path))
 
     inline fun GeckoSession.toParcel(lambda: (Parcel) -> Unit) {
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
@@ -43,26 +43,29 @@ class GeckoSessionTestRuleTest : BaseSes
     }
 
     @Setting.List(Setting(key = Setting.Key.USE_PRIVATE_MODE, value = "true"),
                   Setting(key = Setting.Key.DISPLAY_MODE, value = "DISPLAY_MODE_MINIMAL_UI"),
                   Setting(key = Setting.Key.ALLOW_JAVASCRIPT, value = "false"))
     @Setting(key = Setting.Key.USE_TRACKING_PROTECTION, value = "true")
     @Test fun settingsApplied() {
         assertThat("USE_PRIVATE_MODE should be set",
-                   sessionRule.session.settings.usePrivateMode,
+                   sessionRule.session.settings.getBoolean(
+                           GeckoSessionSettings.USE_PRIVATE_MODE),
                    equalTo(true))
         assertThat("DISPLAY_MODE should be set",
-                   sessionRule.session.settings.displayMode,
+                   sessionRule.session.settings.getInt(GeckoSessionSettings.DISPLAY_MODE),
                    equalTo(GeckoSessionSettings.DISPLAY_MODE_MINIMAL_UI))
         assertThat("USE_TRACKING_PROTECTION should be set",
-                   sessionRule.session.settings.useTrackingProtection,
+                   sessionRule.session.settings.getBoolean(
+                           GeckoSessionSettings.USE_TRACKING_PROTECTION),
                    equalTo(true))
         assertThat("ALLOW_JAVASCRIPT should be set",
-                sessionRule.session.settings.allowJavascript,
+                sessionRule.session.settings.getBoolean(
+                        GeckoSessionSettings.ALLOW_JAVASCRIPT),
                 equalTo(false))
     }
 
     @Test(expected = UiThreadUtils.TimeoutException::class)
     @TimeoutMillis(1000)
     fun noPendingCallbacks() {
         // Make sure we don't have unexpected pending callbacks at the start of a test.
         sessionRule.waitUntilCalled(object : Callbacks.All {})
@@ -888,19 +891,18 @@ class GeckoSessionTestRuleTest : BaseSes
         val newSession = sessionRule.createOpenSession()
         assertThat("Can create session", newSession, notNullValue())
         assertThat("New session is open", newSession.isOpen, equalTo(true))
         assertThat("New session has same settings",
                    newSession.settings, equalTo(sessionRule.session.settings))
     }
 
     @Test fun createOpenSession_withSettings() {
-        val settings = GeckoSessionSettings.Builder(sessionRule.session.settings)
-                .usePrivateMode(true)
-                .build()
+        val settings = GeckoSessionSettings(sessionRule.session.settings)
+        settings.setBoolean(GeckoSessionSettings.USE_PRIVATE_MODE, true)
 
         val newSession = sessionRule.createOpenSession(settings)
         assertThat("New session has same settings", newSession.settings, equalTo(settings))
     }
 
     @Test fun createOpenSession_canInterleaveOtherCalls() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
 
@@ -925,17 +927,18 @@ class GeckoSessionTestRuleTest : BaseSes
         val newSession = sessionRule.createClosedSession()
         assertThat("Can create session", newSession, notNullValue())
         assertThat("New session is open", newSession.isOpen, equalTo(false))
         assertThat("New session has same settings",
                    newSession.settings, equalTo(sessionRule.session.settings))
     }
 
     @Test fun createClosedSession_withSettings() {
-        val settings = GeckoSessionSettings.Builder(sessionRule.session.settings).usePrivateMode(true).build()
+        val settings = GeckoSessionSettings(sessionRule.session.settings)
+        settings.setBoolean(GeckoSessionSettings.USE_PRIVATE_MODE, true)
 
         val newSession = sessionRule.createClosedSession(settings)
         assertThat("New session has same settings", newSession.settings, equalTo(settings))
     }
 
     @Test(expected = UiThreadUtils.TimeoutException::class)
     @TimeoutMillis(1000)
     @ClosedSessionAtStart
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
@@ -2,31 +2,32 @@
  * Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.geckoview.test
 
 import org.mozilla.geckoview.AllowOrDeny
 import org.mozilla.geckoview.GeckoResult
 import org.mozilla.geckoview.GeckoSession
-import org.mozilla.geckoview.GeckoSession.NavigationDelegate.LoadRequest
-import org.mozilla.geckoview.GeckoSession.TrackingProtectionDelegate
+import org.mozilla.geckoview.GeckoSession.NavigationDelegate.LoadRequest;
+import org.mozilla.geckoview.GeckoSession.TrackingProtectionDelegate;
 import org.mozilla.geckoview.GeckoSessionSettings
 import org.mozilla.geckoview.WebRequestError
 
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.NullDelegate
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.Setting
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
 import org.mozilla.geckoview.test.util.Callbacks
 
 import android.support.test.filters.MediumTest
 import android.support.test.runner.AndroidJUnit4
 import org.hamcrest.Matchers.*
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 @MediumTest
 @ReuseSession(false)
 class NavigationDelegateTest : BaseSessionTest() {
 
@@ -59,17 +60,17 @@ class NavigationDelegateTest : BaseSessi
                     }
 
                     @AssertCalled(count = 1, order = [4])
                     override fun onPageStop(session: GeckoSession, success: Boolean) {
                         assertThat("Load should fail", success, equalTo(false))
                     }
                 })
 
-        sessionRule.session.loadUri(testUri)
+        sessionRule.session.loadUri(testUri);
         sessionRule.waitForPageStop()
 
         if (errorPageUrl != null) {
             sessionRule.waitUntilCalled(object : Callbacks.ContentDelegate, Callbacks.NavigationDelegate {
                 @AssertCalled(count = 1, order = [1])
                 override fun onLocationChange(session: GeckoSession, url: String) {
                     assertThat("URL should match", url, equalTo(testUri))
                 }
@@ -118,17 +119,17 @@ class NavigationDelegateTest : BaseSessi
 
         sessionRule.session.loadUri(testUri)
         sessionRule.waitUntilCalled(Callbacks.NavigationDelegate::class, "onLoadError")
 
         if (errorPageUrl != null) {
             sessionRule.waitUntilCalled(object: Callbacks.ContentDelegate {
                 @AssertCalled(count = 1)
                 override fun onTitleChange(session: GeckoSession, title: String) {
-                    assertThat("Title should not be empty", title, not(isEmptyOrNullString()))
+                    assertThat("Title should not be empty", title, not(isEmptyOrNullString()));
                 }
             })
         }
     }
 
     fun testLoadEarlyError(testUri: String, expectedCategory: Int,
                            expectedError: Int) {
         testLoadEarlyErrorWithErrorPage(testUri, expectedCategory, expectedError, createTestUrl(HELLO_HTML_PATH))
@@ -162,39 +163,40 @@ class NavigationDelegateTest : BaseSessi
     @Test fun loadUntrusted() {
         val uri = if (sessionRule.env.isAutomation) {
             "https://expired.example.com/"
         } else {
             "https://expired.badssl.com/"
         }
         testLoadExpectError(uri,
                 WebRequestError.ERROR_CATEGORY_SECURITY,
-                WebRequestError.ERROR_SECURITY_BAD_CERT)
+                WebRequestError.ERROR_SECURITY_BAD_CERT);
     }
 
     @Setting(key = Setting.Key.USE_TRACKING_PROTECTION, value = "true")
     @Test fun trackingProtection() {
-        val category = TrackingProtectionDelegate.CATEGORY_TEST
+        val category = TrackingProtectionDelegate.CATEGORY_TEST;
         sessionRule.runtime.settings.trackingProtectionCategories = category
         sessionRule.session.loadTestPath(TRACKERS_PATH)
 
         sessionRule.waitUntilCalled(
                 object : Callbacks.TrackingProtectionDelegate {
             @AssertCalled(count = 1)
             override fun onTrackerBlocked(session: GeckoSession, uri: String,
                                           categories: Int) {
                 assertThat("Category should be set",
                            categories,
                            equalTo(category))
                 assertThat("URI should not be null", uri, notNullValue())
                 assertThat("URI should match", uri, endsWith("trackertest.org/tracker.js"))
             }
         })
 
-        sessionRule.session.settings.useTrackingProtection = false
+        sessionRule.session.settings.setBoolean(
+            GeckoSessionSettings.USE_TRACKING_PROTECTION, false)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         sessionRule.forCallbacksDuringWait(
                 object : Callbacks.TrackingProtectionDelegate {
             @AssertCalled(false)
             override fun onTrackerBlocked(session: GeckoSession, uri: String,
@@ -363,57 +365,60 @@ class NavigationDelegateTest : BaseSessi
         val userAgentJs = "window.navigator.userAgent"
         val mobileSubStr = "Mobile"
         val desktopSubStr = "X11"
 
         assertThat("User agent should be set to mobile",
                    sessionRule.session.evaluateJS(userAgentJs) as String,
                    containsString(mobileSubStr))
 
-        var userAgent = sessionRule.waitForResult(sessionRule.session.userAgent)
+        var userAgent = sessionRule.waitForResult(sessionRule.session.getUserAgent());
         assertThat("User agent should be reported as mobile",
-                    userAgent, containsString(mobileSubStr))
+                    userAgent, containsString(mobileSubStr));
 
-        sessionRule.session.settings.userAgentMode = GeckoSessionSettings.USER_AGENT_MODE_DESKTOP
+        sessionRule.session.settings.setInt(
+            GeckoSessionSettings.USER_AGENT_MODE, GeckoSessionSettings.USER_AGENT_MODE_DESKTOP)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         assertThat("User agent should be set to desktop",
                    sessionRule.session.evaluateJS(userAgentJs) as String,
                    containsString(desktopSubStr))
 
-        userAgent = sessionRule.waitForResult(sessionRule.session.userAgent)
+        userAgent = sessionRule.waitForResult(sessionRule.session.getUserAgent());
         assertThat("User agent should be reported as desktop",
-                    userAgent, containsString(desktopSubStr))
+                    userAgent, containsString(desktopSubStr));
 
-        sessionRule.session.settings.userAgentMode = GeckoSessionSettings.USER_AGENT_MODE_MOBILE
+        sessionRule.session.settings.setInt(
+            GeckoSessionSettings.USER_AGENT_MODE, GeckoSessionSettings.USER_AGENT_MODE_MOBILE)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         assertThat("User agent should be set to mobile",
                    sessionRule.session.evaluateJS(userAgentJs) as String,
                    containsString(mobileSubStr))
 
-        userAgent = sessionRule.waitForResult(sessionRule.session.userAgent)
+        userAgent = sessionRule.waitForResult(sessionRule.session.getUserAgent());
         assertThat("User agent should be reported as mobile",
-                    userAgent, containsString(mobileSubStr))
+                    userAgent, containsString(mobileSubStr));
 
         val vrSubStr = "Mobile VR"
-        sessionRule.session.settings.userAgentMode = GeckoSessionSettings.USER_AGENT_MODE_VR
+        sessionRule.session.settings.setInt(
+                GeckoSessionSettings.USER_AGENT_MODE, GeckoSessionSettings.USER_AGENT_MODE_VR)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         assertThat("User agent should be set to VR",
                 sessionRule.session.evaluateJS(userAgentJs) as String,
                 containsString(vrSubStr))
 
-        userAgent = sessionRule.waitForResult(sessionRule.session.userAgent)
+        userAgent = sessionRule.waitForResult(sessionRule.session.getUserAgent())
         assertThat("User agent should be reported as VR",
                 userAgent, containsString(vrSubStr))
 
     }
 
     @WithDevToolsAPI
     @Test fun uaOverride() {
         sessionRule.session.loadUri("https://example.com")
@@ -423,61 +428,62 @@ class NavigationDelegateTest : BaseSessi
         val mobileSubStr = "Mobile"
         val vrSubStr = "Mobile VR"
         val overrideUserAgent = "This is the override user agent"
 
         var userAgent = sessionRule.session.evaluateJS(userAgentJs) as String
         assertThat("User agent should be reported as mobile",
                 userAgent, containsString(mobileSubStr))
 
-        sessionRule.session.settings.userAgentOverride = overrideUserAgent
+        sessionRule.session.settings.setString(GeckoSessionSettings.USER_AGENT_OVERRIDE, overrideUserAgent)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         userAgent = sessionRule.session.evaluateJS(userAgentJs) as String
 
         assertThat("User agent should be reported as override",
                 userAgent, equalTo(overrideUserAgent))
 
-        sessionRule.session.settings.userAgentMode = GeckoSessionSettings.USER_AGENT_MODE_VR
+        sessionRule.session.settings.setInt(
+                GeckoSessionSettings.USER_AGENT_MODE, GeckoSessionSettings.USER_AGENT_MODE_VR)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         assertThat("User agent should still be reported as override even when USER_AGENT_MODE is set",
                 userAgent, equalTo(overrideUserAgent))
 
-        sessionRule.session.settings.userAgentOverride = null
+        sessionRule.session.settings.setString(GeckoSessionSettings.USER_AGENT_OVERRIDE, null)
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         userAgent = sessionRule.session.evaluateJS(userAgentJs) as String
         assertThat("User agent should now be reported as VR",
                 userAgent, containsString(vrSubStr))
 
         sessionRule.delegateDuringNextWait(object : Callbacks.NavigationDelegate {
             override fun onLoadRequest(session: GeckoSession, request: LoadRequest): GeckoResult<AllowOrDeny>? {
-                sessionRule.session.settings.userAgentOverride = overrideUserAgent
+                sessionRule.session.settings.setString(GeckoSessionSettings.USER_AGENT_OVERRIDE, overrideUserAgent)
                 return null
             }
         })
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         userAgent = sessionRule.session.evaluateJS(userAgentJs) as String
 
         assertThat("User agent should be reported as override after being set in onLoadRequest",
                 userAgent, equalTo(overrideUserAgent))
 
         sessionRule.delegateDuringNextWait(object : Callbacks.NavigationDelegate {
             override fun onLoadRequest(session: GeckoSession, request: LoadRequest): GeckoResult<AllowOrDeny>? {
-                sessionRule.session.settings.userAgentOverride = null
+                sessionRule.session.settings.setString(GeckoSessionSettings.USER_AGENT_OVERRIDE, null)
                 return null
             }
         })
 
         sessionRule.session.reload()
         sessionRule.session.waitForPageStop()
 
         userAgent = sessionRule.session.evaluateJS(userAgentJs) as String
@@ -545,18 +551,18 @@ class NavigationDelegateTest : BaseSessi
             override fun onNewSession(session: GeckoSession, uri: String): GeckoResult<GeckoSession>? {
                 return null
             }
         })
     }
 
     @Test fun load_dataUri() {
         val dataUrl = "data:,Hello%2C%20World!"
-        sessionRule.session.loadUri(dataUrl)
-        sessionRule.waitForPageStop()
+        sessionRule.session.loadUri(dataUrl);
+        sessionRule.waitForPageStop();
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate, Callbacks.ProgressDelegate {
             @AssertCalled(count = 1)
             override fun onLocationChange(session: GeckoSession, url: String) {
                 assertThat("URL should match the provided data URL", url, equalTo(dataUrl))
             }
 
             @AssertCalled(count = 1)
@@ -598,22 +604,22 @@ class NavigationDelegateTest : BaseSessi
         assertThat("Should not get callback for second load",
                    onLocationCount, equalTo(1))
     }
 
     @Test fun loadString() {
         val dataString = "<html><head><title>TheTitle</title></head><body>TheBody</body></html>"
         val mimeType = "text/html"
         sessionRule.session.loadString(dataString, mimeType)
-        sessionRule.waitForPageStop()
+        sessionRule.waitForPageStop();
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate, Callbacks.ProgressDelegate, Callbacks.ContentDelegate {
             @AssertCalled
             override fun onTitleChange(session: GeckoSession, title: String) {
-                assertThat("Title should match", title, equalTo("TheTitle"))
+                assertThat("Title should match", title, equalTo("TheTitle"));
             }
 
             @AssertCalled(count = 1)
             override fun onLocationChange(session: GeckoSession, url: String) {
                 assertThat("URL should be a data URL", url,
                            equalTo(GeckoSession.createDataUri(dataString, mimeType)))
             }
 
@@ -621,17 +627,17 @@ class NavigationDelegateTest : BaseSessi
             override fun onPageStop(session: GeckoSession, success: Boolean) {
                 assertThat("Page should load successfully", success, equalTo(true))
             }
         })
     }
 
     @Test fun loadString_noMimeType() {
         sessionRule.session.loadString("Hello, World!", null)
-        sessionRule.waitForPageStop()
+        sessionRule.waitForPageStop();
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate, Callbacks.ProgressDelegate {
             @AssertCalled(count = 1)
             override fun onLocationChange(session: GeckoSession, url: String) {
                 assertThat("URL should be a data URL", url, startsWith("data:"))
             }
 
             @AssertCalled(count = 1)
@@ -640,18 +646,18 @@ class NavigationDelegateTest : BaseSessi
             }
         })
     }
 
     @Test fun loadData_html() {
         val bytes = getTestBytes(HELLO_HTML_PATH)
         assertThat("test html should have data", bytes.size, greaterThan(0))
 
-        sessionRule.session.loadData(bytes, "text/html")
-        sessionRule.waitForPageStop()
+        sessionRule.session.loadData(bytes, "text/html");
+        sessionRule.waitForPageStop();
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate, Callbacks.ProgressDelegate, Callbacks.ContentDelegate {
             @AssertCalled(count = 1)
             override fun onTitleChange(session: GeckoSession, title: String) {
                 assertThat("Title should match", title, equalTo("Hello, world!"))
             }
 
             @AssertCalled(count = 1)
@@ -665,18 +671,18 @@ class NavigationDelegateTest : BaseSessi
             }
         })
     }
 
     fun loadDataHelper(assetPath: String, mimeType: String? = null) {
         val bytes = getTestBytes(assetPath)
         assertThat("test data should have bytes", bytes.size, greaterThan(0))
 
-        sessionRule.session.loadData(bytes, mimeType)
-        sessionRule.waitForPageStop()
+        sessionRule.session.loadData(bytes, mimeType);
+        sessionRule.waitForPageStop();
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate, Callbacks.ProgressDelegate {
             @AssertCalled(count = 1)
             override fun onLocationChange(session: GeckoSession, url: String) {
                 assertThat("URL should match", url, equalTo(GeckoSession.createDataUri(bytes, mimeType)))
             }
 
             @AssertCalled(count = 1)
@@ -981,23 +987,23 @@ class NavigationDelegateTest : BaseSessi
     @Setting(key = Setting.Key.USE_MULTIPROCESS, value = "false")
     @WithDevToolsAPI
     @Test fun onNewSession_openRemoteFromNonRemote() {
         // Disable popup blocker.
         sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false))
 
         // Ensure a non-remote page can open a remote page, as needed by some tests.
         assertThat("Opening session should be non-remote",
-                   mainSession.settings.useMultiprocess,
+                   mainSession.settings.getBoolean(GeckoSessionSettings.USE_MULTIPROCESS),
                    equalTo(false))
 
         val newSession = delegateNewSession(
-                GeckoSessionSettings.Builder(mainSession.settings)
-                .useMultiprocess(true)
-                .build())
+                GeckoSessionSettings(mainSession.settings).apply {
+                    setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, true)
+                })
         mainSession.evaluateJS("window.open('http://example.com')")
         newSession.waitForPageStop()
 
         assertThat("window.opener should be set",
                    newSession.evaluateJS("window.opener"), notNullValue())
     }
 
     @WithDevToolsAPI
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SessionLifecycleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SessionLifecycleTest.kt
@@ -72,16 +72,38 @@ class SessionLifecycleTest : BaseSession
     }
 
     @Test(expected = IllegalStateException::class)
     fun open_throwOnAlreadyOpen() {
         // Throw exception if retrying to open again; otherwise we would leak the old open window.
         sessionRule.session.open()
     }
 
+    @Test(expected = IllegalStateException::class)
+    fun setChromeURI_throwOnOpenSession() {
+        sessionRule.session.settings.setString(GeckoSessionSettings.CHROME_URI, "chrome://invalid/path/to.xul")
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun setScreenID_throwOnOpenSession() {
+        sessionRule.session.settings.setInt(GeckoSessionSettings.SCREEN_ID, 42)
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun setUsePrivateMode_throwOnOpenSession() {
+        sessionRule.session.settings.setBoolean(GeckoSessionSettings.USE_PRIVATE_MODE, true)
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun setUseMultiprocess_throwOnOpenSession() {
+        sessionRule.session.settings.setBoolean(
+                GeckoSessionSettings.USE_MULTIPROCESS,
+                !sessionRule.session.settings.getBoolean(GeckoSessionSettings.USE_MULTIPROCESS))
+    }
+
     @Test fun readFromParcel() {
         val session = sessionRule.createOpenSession()
 
         session.toParcel { parcel ->
             val newSession = sessionRule.createClosedSession()
             newSession.readFromParcel(parcel)
 
             assertThat("New session has same settings",
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/crash/RemoteGeckoService.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/crash/RemoteGeckoService.kt
@@ -26,19 +26,18 @@ class RemoteGeckoService : Service() {
             when (msg.what) {
                 CMD_CRASH_PARENT_NATIVE -> {
                     val settings = GeckoSessionSettings()
                     val session = GeckoSession(settings)
                     session.open(runtime!!)
                     session.loadUri("about:crashparent")
                 }
                 CMD_CRASH_CONTENT_NATIVE -> {
-                    val settings = GeckoSessionSettings.Builder()
-                            .useMultiprocess(true)
-                            .build()
+                    val settings = GeckoSessionSettings()
+                    settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, true)
                     val session = GeckoSession(settings)
                     session.open(runtime!!)
                     session.loadUri("about:crashcontent")
                 }
                 else -> {
                     throw RuntimeException("Unhandled command")
                 }
             }
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -195,68 +195,46 @@ public class GeckoSessionTestRule implem
             FULL_ACCESSIBILITY_TREE;
 
             private final GeckoSessionSettings.Key<?> mKey;
             private final Class<?> mType;
 
             Key() {
                 final Field field;
                 try {
-                    field = GeckoSessionSettings.class.getDeclaredField(name());
-                    field.setAccessible(true);
+                    field = GeckoSessionSettings.class.getField(name());
                     mKey = (GeckoSessionSettings.Key<?>) field.get(null);
                 } catch (final NoSuchFieldException | IllegalAccessException e) {
                     throw new RuntimeException(e);
                 }
 
                 final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
                 mType = (Class<?>) genericType.getActualTypeArguments()[0];
             }
 
             @SuppressWarnings("unchecked")
             public void set(final GeckoSessionSettings settings, final String value) {
-                try {
-                    if (boolean.class.equals(mType) || Boolean.class.equals(mType)) {
-                        Method method = GeckoSessionSettings.class
-                                .getDeclaredMethod("setBoolean",
-                                        GeckoSessionSettings.Key.class,
-                                        boolean.class);
-                        method.setAccessible(true);
-                        method.invoke(settings, mKey, Boolean.valueOf(value));
-                    } else if (int.class.equals(mType) || Integer.class.equals(mType)) {
-                        Method method = GeckoSessionSettings.class
-                                .getDeclaredMethod("setInt",
-                                        GeckoSessionSettings.Key.class,
-                                        int.class);
-                        method.setAccessible(true);
-                        try {
-                            method.invoke(settings, mKey,
-                                    (Integer)GeckoSessionSettings.class.getField(value)
-                                            .get(null));
-                        }
-                        catch (final NoSuchFieldException | IllegalAccessException |
-                                ClassCastException e) {
-                            method.invoke(settings, mKey,
-                                    Integer.valueOf(value));
-                        }
-                    } else if (String.class.equals(mType)) {
-                        Method method = GeckoSessionSettings.class
-                                .getDeclaredMethod("setString",
-                                        GeckoSessionSettings.Key.class,
-                                        String.class);
-                        method.setAccessible(true);
-                        method.invoke(settings, mKey, value);
-                    } else {
-                        throw new IllegalArgumentException("Unsupported type: " +
-                                mType.getSimpleName());
+                if (boolean.class.equals(mType) || Boolean.class.equals(mType)) {
+                    settings.setBoolean((GeckoSessionSettings.Key<Boolean>) mKey,
+                            Boolean.valueOf(value));
+                } else if (int.class.equals(mType) || Integer.class.equals(mType)) {
+                    try {
+                        settings.setInt((GeckoSessionSettings.Key<Integer>) mKey,
+                                (Integer) GeckoSessionSettings.class.getField(value)
+                                        .get(null));
+                    } catch (final NoSuchFieldException | IllegalAccessException |
+                            ClassCastException e) {
+                        settings.setInt((GeckoSessionSettings.Key<Integer>) mKey,
+                                        Integer.valueOf(value));
                     }
-                } catch (NoSuchMethodException
-                        | IllegalAccessException
-                        | InvocationTargetException e) {
-                    throw new RuntimeException(e);
+                } else if (String.class.equals(mType)) {
+                    settings.setString((GeckoSessionSettings.Key<String>) mKey, value);
+                } else {
+                    throw new IllegalArgumentException("Unsupported type: " +
+                            mType.getSimpleName());
                 }
             }
         }
 
         @Target({ElementType.METHOD, ElementType.TYPE})
         @Retention(RetentionPolicy.RUNTIME)
         @interface List {
             Setting[] value();
@@ -854,19 +832,18 @@ public class GeckoSessionTestRule implem
     protected boolean mClosedSession;
     protected boolean mWithDevTools;
     protected Map<GeckoSession, Tab> mRDPTabs;
     protected Tab mRDPChromeProcess;
     protected boolean mReuseSession;
     protected boolean mIgnoreCrash;
 
     public GeckoSessionTestRule() {
-        mDefaultSettings = new GeckoSessionSettings.Builder()
-                .useMultiprocess(env.isMultiprocess())
-                .build();
+        mDefaultSettings = new GeckoSessionSettings();
+        mDefaultSettings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, env.isMultiprocess());
     }
 
     /**
      * Set an ErrorCollector for assertion errors, or null to not use one.
      *
      * @param ec ErrorCollector or null.
      */
     public void setErrorCollector(final @Nullable ErrorCollector ec) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -7,21 +7,23 @@
 package org.mozilla.geckoview;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.UUID;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.GeckoEditableChild;
 import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.IGeckoEditableParent;
 import org.mozilla.gecko.mozglue.JNIObject;
 import org.mozilla.gecko.NativeQueue;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.IntentUtils;
@@ -1239,19 +1241,19 @@ public class GeckoSession implements Par
     public void open(final @NonNull GeckoRuntime runtime) {
         ThreadUtils.assertOnUiThread();
 
         if (isOpen()) {
             // We will leak the existing Window if we open another one.
             throw new IllegalStateException("Session is open");
         }
 
-        final String chromeUri = mSettings.getChromeUri();
-        final int screenId = mSettings.getScreenId();
-        final boolean isPrivate = mSettings.getUsePrivateMode();
+        final String chromeUri = mSettings.getString(GeckoSessionSettings.CHROME_URI);
+        final int screenId = mSettings.getInt(GeckoSessionSettings.SCREEN_ID);
+        final boolean isPrivate = mSettings.getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE);
 
         mWindow = new Window(runtime, this, mNativeQueue);
 
         onWindowChanged(WINDOW_OPEN, /* inProgress */ true);
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             Window.open(mWindow, mNativeQueue, mCompositor, mEventDispatcher,
                         mAccessibility != null ? mAccessibility.nativeProvider : null,
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
@@ -3,189 +3,26 @@
  * 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 org.mozilla.gecko.util.GeckoBundle;
 
-import android.app.Service;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.util.Log;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.Collection;
 
 public final class GeckoSessionSettings implements Parcelable {
-
-    /**
-     * Settings builder used to construct the settings object.
-     */
-    public static final class Builder {
-        private final GeckoSessionSettings mSettings;
-
-        public Builder() {
-            mSettings = new GeckoSessionSettings();
-        }
-
-        public Builder(final GeckoSessionSettings settings) {
-            mSettings = new GeckoSessionSettings(settings);
-        }
-
-        /**
-         * Finalize and return the settings.
-         *
-         * @return The constructed settings.
-         */
-        public @NonNull GeckoSessionSettings build() {
-            return new GeckoSessionSettings(mSettings);
-        }
-
-        /**
-         * Set the chrome URI.
-         *
-         * @param uri The URI to set the Chrome URI to.
-         * @return This Builder instance.
-
-         */
-        public @NonNull  Builder chromeUri(final String uri) {
-            mSettings.setChromeUri(uri);
-            return this;
-        }
-
-        /**
-         * Set the screen id.
-         *
-         * @param id The screen id.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder screenId(final int id) {
-            mSettings.setScreenId(id);
-            return this;
-        }
-
-        /**
-         * Set the privacy mode for this instance.
-         *
-         * @param flag A flag determining whether Private Mode should be enabled.
-         *             Default is false.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder usePrivateMode(final boolean flag) {
-            mSettings.setUsePrivateMode(flag);
-            return this;
-        }
-
-        /**
-         * Set whether multi-process support should be enabled.
-         *
-         * @param flag A flag determining whether multi-process should be enabled.
-         *             Default is false.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder useMultiprocess(final boolean flag) {
-            mSettings.setUseMultiprocess(flag);
-            return this;
-        }
-
-        /**
-         * Set whether tracking protection should be enabled.
-         *
-         * @param flag A flag determining whether tracking protection should be enabled.
-         *             Default is false.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder useTrackingProtection(final boolean flag) {
-            mSettings.setUseTrackingProtection(flag);
-            return this;
-        }
-
-        /**
-         * Set the user agent mode.
-         *
-         * @param mode The mode to set the user agent to.
-         *             Use one or more of the
-         *             {@link GeckoSessionSettings#USER_AGENT_MODE_MOBILE GeckoSessionSettings.USER_AGENT_MODE_*} flags.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder userAgentMode(final int mode) {
-            mSettings.setUserAgentMode(mode);
-            return this;
-        }
-
-        /**
-         * Override the user agent.
-         *
-         * @param agent The user agent to use.
-         * @return This Builder instance.
-
-         */
-        public @NonNull Builder userAgentOverride(final String agent) {
-            mSettings.setUserAgentOverride(agent);
-            return this;
-        }
-
-        /**
-         * Specify which display-mode to use.
-         *
-         * @param mode The mode to set the display to.
-         *             Use one or more of the
-         *             {@link GeckoSessionSettings#DISPLAY_MODE_BROWSER GeckoSessionSettings.DISPLAY_MODE_*} flags.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder displayMode(final int mode) {
-            mSettings.setDisplayMode(mode);
-            return this;
-        }
-
-        /**
-         * Set whether to suspend the playing of media when the session is inactive.
-         *
-         * @param flag A flag determining whether media should be suspended.
-         *             Default is false.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder suspendMediaWhenInactive(final boolean flag) {
-            mSettings.setSuspendMediaWhenInactive(flag);
-            return this;
-        }
-
-        /**
-         * Set whether JavaScript support should be enabled.
-         *
-         * @param flag A flag determining whether JavaScript should be enabled.
-         *             Default is true.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder allowJavascript(final boolean flag) {
-            mSettings.setAllowJavascript(flag);
-            return this;
-        }
-
-        /**
-         * Set whether the entire accessible tree should be exposed with no caching.
-         *
-         * @param flag A flag determining if the entire accessible tree should be exposed.
-         *             Default is false.
-         * @return This Builder instance.
-         */
-        public @NonNull Builder fullAccessibilityTree(final boolean flag) {
-            mSettings.setFullAccessibilityTree(flag);
-            return this;
-        }
-    }
-
     private static final String LOGTAG = "GeckoSessionSettings";
     private static final boolean DEBUG = false;
 
     // This needs to match nsIDocShell.idl
     public static final int DISPLAY_MODE_BROWSER = 0;
     public static final int DISPLAY_MODE_MINIMAL_UI = 1;
     public static final int DISPLAY_MODE_STANDALONE = 2;
     public static final int DISPLAY_MODE_FULLSCREEN = 3;
@@ -211,81 +48,81 @@ public final class GeckoSessionSettings 
             this.values = values;
         }
     }
 
     /**
      * Key to set the chrome window URI, or null to use default URI.
      * Read-only once session is open.
      */
-    private static final Key<String> CHROME_URI =
+    public static final Key<String> CHROME_URI =
         new Key<String>("chromeUri", /* initOnly */ true, /* values */ null);
     /**
      * Key to set the window screen ID, or 0 to use default ID.
      * Read-only once session is open.
      */
-    private static final Key<Integer> SCREEN_ID =
+    public static final Key<Integer> SCREEN_ID =
         new Key<Integer>("screenId", /* initOnly */ true, /* values */ null);
 
     /**
      * Key to enable and disable tracking protection.
      */
-    private static final Key<Boolean> USE_TRACKING_PROTECTION =
+    public static final Key<Boolean> USE_TRACKING_PROTECTION =
         new Key<Boolean>("useTrackingProtection");
     /**
      * Key to enable and disable private mode browsing.
      * Read-only once session is open.
      */
-    private static final Key<Boolean> USE_PRIVATE_MODE =
+    public static final Key<Boolean> USE_PRIVATE_MODE =
         new Key<Boolean>("usePrivateMode", /* initOnly */ true, /* values */ null);
 
     /**
      * Key to enable and disable multiprocess browsing (e10s).
      * Read-only once session is open.
      */
-    private static final Key<Boolean> USE_MULTIPROCESS =
+    public static final Key<Boolean> USE_MULTIPROCESS =
         new Key<Boolean>("useMultiprocess", /* initOnly */ true, /* values */ null);
 
     /**
      * Key to specify which user agent mode we should use.
      */
-    private static final Key<Integer> USER_AGENT_MODE =
+    public static final Key<Integer> USER_AGENT_MODE =
         new Key<Integer>("userAgentMode", /* initOnly */ false,
                          Arrays.asList(USER_AGENT_MODE_MOBILE, USER_AGENT_MODE_DESKTOP, USER_AGENT_MODE_VR));
 
     /**
      * Key to specify the user agent override string.
      * Set value to null to use the user agent specified by USER_AGENT_MODE.
      */
-    private static final Key<String> USER_AGENT_OVERRIDE =
+    public static final Key<String> USER_AGENT_OVERRIDE =
         new Key<String>("userAgentOverride", /* initOnly */ false, /* values */ null);
 
     /**
      * Key to specify which display-mode we should use.
      */
-    private static final Key<Integer> DISPLAY_MODE =
+    public static final Key<Integer> DISPLAY_MODE =
         new Key<Integer>("displayMode", /* initOnly */ false,
                          Arrays.asList(DISPLAY_MODE_BROWSER, DISPLAY_MODE_MINIMAL_UI,
                                        DISPLAY_MODE_STANDALONE, DISPLAY_MODE_FULLSCREEN));
 
     /**
      * Key to specify if media should be suspended when the session is inactive.
      */
-    private static final Key<Boolean> SUSPEND_MEDIA_WHEN_INACTIVE =
+    public static final Key<Boolean> SUSPEND_MEDIA_WHEN_INACTIVE =
         new Key<Boolean>("suspendMediaWhenInactive", /* initOnly */ false, /* values */ null);
 
     /**
      * Key to specify if JavaScript should be allowed on this session.
      */
-    private static final Key<Boolean> ALLOW_JAVASCRIPT =
+    public static final Key<Boolean> ALLOW_JAVASCRIPT =
             new Key<Boolean>("allowJavascript", /* initOnly */ false, /* values */ null);
     /**
      * Key to specify if entire accessible tree should be exposed with no caching.
      */
-    private static final Key<Boolean> FULL_ACCESSIBILITY_TREE =
+    public static final Key<Boolean> FULL_ACCESSIBILITY_TREE =
             new Key<Boolean>("fullAccessibilityTree", /* initOnly */ false, /* values */ null);
 
     private final GeckoSession mSession;
     private final GeckoBundle mBundle;
 
     public GeckoSessionSettings() {
         this(null, null);
     }
@@ -312,282 +149,62 @@ public final class GeckoSessionSettings 
         mBundle.putBoolean(SUSPEND_MEDIA_WHEN_INACTIVE.name, false);
         mBundle.putBoolean(ALLOW_JAVASCRIPT.name, true);
         mBundle.putBoolean(FULL_ACCESSIBILITY_TREE.name, false);
         mBundle.putInt(USER_AGENT_MODE.name, USER_AGENT_MODE_MOBILE);
         mBundle.putString(USER_AGENT_OVERRIDE.name, null);
         mBundle.putInt(DISPLAY_MODE.name, DISPLAY_MODE_BROWSER);
     }
 
-
-    /**
-     * Set whether tracking protection should be enabled.
-     *
-     * @param value A flag determining whether tracking protection should be enabled.
-     *             Default is false.
-     */
-    public void setUseTrackingProtection(final boolean value) {
-        setBoolean(USE_TRACKING_PROTECTION, value);
-    }
-
-    /**
-     * Set the privacy mode for this instance.
-     *
-     * @param value A flag determining whether Private Mode should be enabled.
-     *             Default is false.
-     */
-    private void setUsePrivateMode(final boolean value) {
-        setBoolean(USE_PRIVATE_MODE, value);
-    }
-
-
-    /**
-     * Set whether multi-process support should be enabled.
-     *
-     * @param value A flag determining whether multi-process should be enabled.
-     *             Default is false.
-     */
-    private void setUseMultiprocess(final boolean value) {
-        setBoolean(USE_MULTIPROCESS, value);
-    }
-
-    /**
-     * Set whether to suspend the playing of media when the session is inactive.
-     *
-     * @param value A flag determining whether media should be suspended.
-     *             Default is false.
-     */
-    public void setSuspendMediaWhenInactive(final boolean value) {
-        setBoolean(SUSPEND_MEDIA_WHEN_INACTIVE, value);
-    }
-
-
-    /**
-     * Set whether JavaScript support should be enabled.
-     *
-     * @param value A flag determining whether JavaScript should be enabled.
-     *             Default is true.
-     */
-    public void setAllowJavascript(final boolean value) {
-        setBoolean(ALLOW_JAVASCRIPT, value);
-    }
-
-
-    /**
-     * Set whether the entire accessible tree should be exposed with no caching.
-     *
-     * @param value A flag determining full accessibility tree should be exposed.
-     *             Default is false.
-     */
-    public void setFullAccessibilityTree(final boolean value) {
-        setBoolean(FULL_ACCESSIBILITY_TREE, value);
-    }
-
-    private void setBoolean(final Key<Boolean> key, final boolean value) {
+    public void setBoolean(final Key<Boolean> key, final boolean value) {
         synchronized (mBundle) {
             if (valueChangedLocked(key, value)) {
                 mBundle.putBoolean(key.name, value);
                 dispatchUpdate();
             }
         }
     }
 
-    /**
-     * Whether tracking protection is enabled.
-     *
-     * @return true if tracking protection is enabled, false if not.
-     */
-    public boolean getUseTrackingProtection() {
-        return getBoolean(USE_TRACKING_PROTECTION);
-    }
-
-    /**
-     * Whether private mode is enabled.
-     *
-     * @return true if private mode is enabled, false if not.
-     */
-    public boolean getUsePrivateMode() {
-        return getBoolean(USE_PRIVATE_MODE);
-    }
-
-    /**
-     * Whether multiprocess is enabled.
-     *
-     * @return true if multiprocess is enabled, false if not.
-     */
-    public boolean getUseMultiprocess() {
-        return getBoolean(USE_MULTIPROCESS);
-    }
-
-    /**
-     * Whether media will be suspended when the session is inactice.
-     *
-     * @return true if media will be suspended, false if not.
-     */
-    public boolean getSuspendMediaWhenInactive() {
-        return getBoolean(SUSPEND_MEDIA_WHEN_INACTIVE);
-    }
-
-    /**
-     * Whether javascript execution is allowed.
-     *
-     * @return true if javascript execution is allowed, false if not.
-     */
-    public boolean getAllowJavascript() {
-        return getBoolean(ALLOW_JAVASCRIPT);
-    }
-
-    /**
-     * Whether entire accessible tree is exposed with no caching.
-     *
-     * @return true if accessibility tree is exposed, false if not.
-     */
-    public boolean getFullAccessibilityTree() {
-        return getBoolean(FULL_ACCESSIBILITY_TREE);
-    }
-
-    private boolean getBoolean(final Key<Boolean> key) {
+    public boolean getBoolean(final Key<Boolean> key) {
         synchronized (mBundle) {
             return mBundle.getBoolean(key.name);
         }
     }
 
-
-    /**
-     * Set the screen id.
-     *
-     * @param value The screen id.
-     */
-    private void setScreenId(final int value) {
-        setInt(SCREEN_ID, value);
-    }
-
-
-    /**
-     * Specify which user agent mode we should use
-     *
-     * @param value One or more of the
-     *             {@link GeckoSessionSettings#USER_AGENT_MODE_MOBILE GeckoSessionSettings.USER_AGENT_MODE_*} flags.
-     */
-    public void setUserAgentMode(final int value) {
-        setInt(USER_AGENT_MODE, value);
-    }
-
-
-    /**
-     * Set the display mode.
-     *
-     * @param value The mode to set the display to.
-     *             Use one or more of the
-     *             {@link GeckoSessionSettings#DISPLAY_MODE_BROWSER GeckoSessionSettings.DISPLAY_MODE_*} flags.
-     */
-    public void setDisplayMode(final int value) {
-        setInt(DISPLAY_MODE, value);
-    }
-
-    private void setInt(final Key<Integer> key, final int value) {
+    public void setInt(final Key<Integer> key, final int value) {
         synchronized (mBundle) {
             if (valueChangedLocked(key, value)) {
                 mBundle.putInt(key.name, value);
                 dispatchUpdate();
             }
         }
     }
 
-    /**
-     * Set the window screen ID.
-     * Read-only once session is open.
-     * Use the {@link Builder} to set on session open.
-     *
-     * @return Key to set the window screen ID. 0 is the default ID.
-     */
-    public int getScreenId() {
-        return getInt(SCREEN_ID);
-    }
-
-    /**
-     * The current user agent Mode
-     * @return One or more of the
-     *      {@link GeckoSessionSettings#USER_AGENT_MODE_MOBILE GeckoSessionSettings.USER_AGENT_MODE_*} flags.
-     */
-    public int getUserAgentMode() {
-        return getInt(USER_AGENT_MODE);
-    }
-
-    /**
-     * The current display mode.
-     * @return )One or more of the
-     *      {@link GeckoSessionSettings#DISPLAY_MODE_BROWSER GeckoSessionSettings.DISPLAY_MODE_*} flags.
-     */
-    public int getDisplayMode() {
-        return getInt(DISPLAY_MODE);
-    }
-
-    private int getInt(final Key<Integer> key) {
+    public int getInt(final Key<Integer> key) {
         synchronized (mBundle) {
             return mBundle.getInt(key.name);
         }
     }
 
-    /**
-     * Set the chrome URI.
-     *
-     * @param value The URI to set the Chrome URI to.
-
-     */
-    private void setChromeUri(final String value) {
-        setString(CHROME_URI, value);
-    }
-
-
-    /**
-     * Specify the user agent override string.
-     * Set value to null to use the user agent specified by USER_AGENT_MODE.
-     * @param value
-     */
-    public void setUserAgentOverride(final String value) {
-        setString(USER_AGENT_OVERRIDE, value);
-    }
-
-    private void setString(final Key<String> key, final String value) {
+    public void setString(final Key<String> key, final String value) {
         synchronized (mBundle) {
             if (valueChangedLocked(key, value)) {
                 mBundle.putString(key.name, value);
                 dispatchUpdate();
             }
         }
     }
 
-    /**
-     * Set the chrome window URI.
-     * Read-only once session is open.
-     * Use the {@link Builder} to set on session open.
-     *
-     * @return Key to set the chrome window URI, or null to use default URI.
-     */
-    public String getChromeUri() {
-        return getString(USER_AGENT_OVERRIDE);
-    }
-
-    /**
-     * The user agent override string.
-     * @return The current user agent string or null if the agent is specified by
-     *          {@link GeckoSessionSettings#USER_AGENT_MODE}
-     */
-    public String getUserAgentOverride() {
-        return getString(USER_AGENT_OVERRIDE);
-    }
-
-    private String getString(final Key<String> key) {
+    public String getString(final Key<String> key) {
         synchronized (mBundle) {
             return mBundle.getString(key.name);
         }
     }
 
-    /* package */ @NonNull GeckoBundle toBundle() {
+    /* package */ GeckoBundle toBundle() {
         return new GeckoBundle(mBundle);
     }
 
     @Override
     public String toString() {
         return mBundle.toString();
     }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
@@ -108,17 +108,17 @@ public class SessionAccessibility {
         return "android.view.View"; // Fallback class is View
     }
 
     /* package */ final class NodeProvider extends AccessibilityNodeProvider {
         @Override
         public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualDescendantId) {
             AccessibilityNodeInfo node = null;
             if (mAttached) {
-                node = mSession.getSettings().getFullAccessibilityTree() ?
+                node = mSession.getSettings().getBoolean(GeckoSessionSettings.FULL_ACCESSIBILITY_TREE) ?
                         getNodeFromGecko(virtualDescendantId) : getNodeFromCache(virtualDescendantId);
                 if (node != null) {
                     node.setAccessibilityFocused(mAccessibilityFocusedNode == virtualDescendantId);
                     node.setFocused(mFocusedNode == virtualDescendantId);
                 }
             }
 
             if (node == null) {
@@ -649,17 +649,17 @@ public class SessionAccessibility {
         if (!Settings.isPlatformEnabled() && (Build.VERSION.SDK_INT < 17 || mView.getDisplay() != null)) {
             // Accessibility could be activated in Gecko via xpcom, for example when using a11y
             // devtools. Here we assure that either Android a11y is *really* enabled, or no
             // display is attached and we must be in a junit test.
             return;
         }
 
         GeckoBundle cachedBundle = null;
-        if (!mSession.getSettings().getFullAccessibilityTree()) {
+        if (!mSession.getSettings().getBoolean(GeckoSessionSettings.FULL_ACCESSIBILITY_TREE)) {
             cachedBundle = getMostRecentBundle(sourceId);
             // Suppress events from non cached nodes if cache is enabled.
             if (cachedBundle == null && sourceId != View.NO_ID) {
                 return;
             }
         }
 
         final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -140,38 +140,39 @@ public class GeckoViewActivity extends A
             mGeckoSession = (GeckoSession)getIntent().getParcelableExtra("session");
             if (mGeckoSession != null) {
                 connectSession(mGeckoSession);
 
                 if (!mGeckoSession.isOpen()) {
                     mGeckoSession.open(sGeckoRuntime);
                 }
 
-                mUseMultiprocess = mGeckoSession.getSettings().getUseMultiprocess();
-                mFullAccessibilityTree = mGeckoSession.getSettings().getFullAccessibilityTree();
+                mUseMultiprocess = mGeckoSession.getSettings().getBoolean(GeckoSessionSettings.USE_MULTIPROCESS);
+                mFullAccessibilityTree = mGeckoSession.getSettings().getBoolean(GeckoSessionSettings.FULL_ACCESSIBILITY_TREE);
 
                 mGeckoView.setSession(mGeckoSession);
             } else {
                 mGeckoSession = createSession();
                 mGeckoView.setSession(mGeckoSession, sGeckoRuntime);
 
                 loadFromIntent(getIntent());
             }
         }
 
         mLocationView.setCommitListener(mCommitListener);
     }
 
     private GeckoSession createSession() {
-        GeckoSession session = new GeckoSession(new GeckoSessionSettings.Builder()
-                .useMultiprocess(mUseMultiprocess)
-                .usePrivateMode(mUsePrivateBrowsing)
-                .useTrackingProtection(mUseTrackingProtection)
-                .fullAccessibilityTree(mFullAccessibilityTree)
-                .build());
+        GeckoSession session = new GeckoSession();
+        session.getSettings().setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, mUseMultiprocess);
+        session.getSettings().setBoolean(GeckoSessionSettings.USE_PRIVATE_MODE, mUsePrivateBrowsing);
+        session.getSettings().setBoolean(
+            GeckoSessionSettings.USE_TRACKING_PROTECTION, mUseTrackingProtection);
+        session.getSettings().setBoolean(
+                GeckoSessionSettings.FULL_ACCESSIBILITY_TREE, mFullAccessibilityTree);
 
         connectSession(session);
 
         return session;
     }
 
     private void connectSession(GeckoSession session) {
         session.setContentDelegate(new ExampleContentDelegate());
@@ -211,17 +212,18 @@ public class GeckoViewActivity extends A
         if(savedInstanceState != null) {
             mGeckoSession = mGeckoView.getSession();
         } else {
             recreateSession();
         }
     }
 
     private void updateTrackingProtection(GeckoSession session) {
-        session.getSettings().setUseTrackingProtection(mUseTrackingProtection);
+        session.getSettings().setBoolean(
+            GeckoSessionSettings.USE_TRACKING_PROTECTION, mUseTrackingProtection);
     }
 
     @Override
     public void onBackPressed() {
         if (mFullScreen) {
             mGeckoSession.exitFullScreen();
             return;
         }