Bug 1650108 - Remove deprecated Parcelable support r=geckoview-reviewers,agi
authorowlishDeveloper <bugzeeeeee@gmail.com>
Thu, 17 Sep 2020 02:13:22 +0000
changeset 549206 20cc1d596578e36344a9e226e3968206c7b852d5
parent 549205 787605ddd0b146e2918d8148f6fecefa11088c54
child 549207 aa09cdc39dadb4c2f9834e8e0c3a2181b6998172
push id126617
push useristorozhko@mozilla.com
push dateThu, 17 Sep 2020 18:43:27 +0000
treeherderautoland@20cc1d596578 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgeckoview-reviewers, agi
bugs1650108
milestone82.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 1650108 - Remove deprecated Parcelable support r=geckoview-reviewers,agi Try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=6658ee401fd39bb137546937e29a8fa630bcd54a I also removed `dumpHprof()` function as it was seemingly unused Differential Revision: https://phabricator.services.mozilla.com/D90471
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/SessionLifecycleTest.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/GeckoView.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/TabSession.java
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -633,17 +633,17 @@ package org.mozilla.geckoview {
     method @NonNull public GeckoRuntimeSettings.Builder telemetryDelegate(@NonNull RuntimeTelemetry.Delegate);
     method @NonNull public GeckoRuntimeSettings.Builder useMaxScreenDepth(boolean);
     method @Deprecated @NonNull public GeckoRuntimeSettings.Builder useMultiprocess(boolean);
     method @NonNull public GeckoRuntimeSettings.Builder webFontsEnabled(boolean);
     method @NonNull public GeckoRuntimeSettings.Builder webManifest(boolean);
     method @NonNull protected GeckoRuntimeSettings newSettings(@Nullable GeckoRuntimeSettings);
   }
 
-  public class GeckoSession implements Parcelable {
+  public class GeckoSession {
     ctor public GeckoSession();
     ctor public GeckoSession(@Nullable GeckoSessionSettings);
     method @UiThread @NonNull public GeckoDisplay acquireDisplay();
     method @UiThread public void autofill(@NonNull SparseArray<CharSequence>);
     method @UiThread public void close();
     method @AnyThread @NonNull public static String createDataUri(@NonNull byte[], @Nullable String);
     method @AnyThread @NonNull public static String createDataUri(@NonNull String, @Nullable String);
     method @AnyThread public void exitFullScreen();
@@ -691,17 +691,16 @@ package org.mozilla.geckoview {
     method @AnyThread public void loadUri(@NonNull String, @Nullable GeckoSession, int, @Nullable Map<String,String>);
     method @AnyThread public void loadUri(@NonNull Uri);
     method @AnyThread public void loadUri(@NonNull Uri, @Nullable Map<String,String>);
     method @AnyThread public void loadUri(@NonNull Uri, int);
     method @AnyThread public void loadUri(@NonNull Uri, @Nullable Uri, int);
     method @AnyThread public void loadUri(@NonNull Uri, @Nullable Uri, int, @Nullable Map<String,String>);
     method @UiThread public void open(@NonNull GeckoRuntime);
     method @AnyThread public void purgeHistory();
-    method @Deprecated @AnyThread public void readFromParcel(@NonNull Parcel);
     method @UiThread public void releaseDisplay(@NonNull GeckoDisplay);
     method @AnyThread public void reload();
     method @AnyThread public void reload(int);
     method @AnyThread public void restoreState(@NonNull GeckoSession.SessionState);
     method @AnyThread public void setActive(boolean);
     method @UiThread public void setAutofillDelegate(@Nullable Autofill.Delegate);
     method @AnyThread public void setContentBlockingDelegate(@Nullable ContentBlocking.Delegate);
     method @UiThread public void setContentDelegate(@Nullable GeckoSession.ContentDelegate);
@@ -712,17 +711,16 @@ package org.mozilla.geckoview {
     method @UiThread public void setNavigationDelegate(@Nullable GeckoSession.NavigationDelegate);
     method @UiThread public void setPermissionDelegate(@Nullable GeckoSession.PermissionDelegate);
     method @UiThread public void setProgressDelegate(@Nullable GeckoSession.ProgressDelegate);
     method @AnyThread public void setPromptDelegate(@Nullable GeckoSession.PromptDelegate);
     method @UiThread public void setScrollDelegate(@Nullable GeckoSession.ScrollDelegate);
     method @UiThread public void setSelectionActionDelegate(@Nullable GeckoSession.SelectionActionDelegate);
     method @AnyThread public void stop();
     method @UiThread protected void setShouldPinOnScreen(boolean);
-    field @Deprecated public static final Parcelable.Creator<GeckoSession> CREATOR;
     field public static final int FINDER_DISPLAY_DIM_PAGE = 2;
     field public static final int FINDER_DISPLAY_DRAW_LINK_OUTLINE = 4;
     field public static final int FINDER_DISPLAY_HIGHLIGHT_ALL = 1;
     field public static final int FINDER_FIND_BACKWARDS = 1;
     field public static final int FINDER_FIND_LINKS_ONLY = 8;
     field public static final int FINDER_FIND_MATCH_CASE = 2;
     field public static final int FINDER_FIND_WHOLE_WORD = 4;
     field public static final int LOAD_FLAGS_ALLOW_POPUPS = 8;
--- 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
@@ -106,20 +106,16 @@ open class BaseSessionTest(noErrorCollec
     fun createTestUrl(path: String) = GeckoSessionTestRule.TEST_ENDPOINT + path
 
     fun GeckoSession.loadTestPath(path: String) =
             this.loadUri(createTestUrl(path))
 
     inline fun GeckoSession.toParcel(lambda: (Parcel) -> Unit) {
         val parcel = Parcel.obtain()
         try {
-            // Bug 1650108: Remove this
-            @Suppress("DEPRECATION")
-            this.writeToParcel(parcel, 0)
-
             val pos = parcel.dataPosition()
             parcel.setDataPosition(0)
 
             lambda(parcel)
 
             assertThat("Read parcel matches written parcel",
                        parcel.dataPosition(), Matchers.equalTo(pos))
         } finally {
--- 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
@@ -1,42 +1,27 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.geckoview.test
 
 import org.mozilla.geckoview.GeckoRuntimeSettings
 import org.mozilla.geckoview.GeckoSession
-import org.mozilla.geckoview.GeckoSessionSettings
-import org.mozilla.geckoview.GeckoView
-import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ClosedSessionAtStart
-import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.NullDelegate
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
-import org.mozilla.geckoview.test.util.Callbacks
 import org.mozilla.geckoview.test.util.UiThreadUtils
-import org.junit.Ignore
 
 import android.os.Bundle
-import android.os.Debug
-import android.os.Parcelable
-import android.os.SystemClock
-import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.filters.MediumTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import android.util.Log
-import android.util.SparseArray
 
 import org.hamcrest.Matchers.*
-import org.junit.Assume.assumeThat
 import org.junit.Test
 import org.junit.runner.RunWith
-import java.io.File
-import java.io.IOException
 import java.lang.ref.ReferenceQueue
 import java.lang.ref.WeakReference
 
 @RunWith(AndroidJUnit4::class)
 @MediumTest
 class SessionLifecycleTest : BaseSessionTest() {
     companion object {
         val LOGTAG = "SessionLifecycleTest"
@@ -74,257 +59,16 @@ 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()
     }
 
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel() {
-        val session = sessionRule.createOpenSession()
-
-        session.toParcel { parcel ->
-            val newSession = sessionRule.createFromParcel(parcel)
-
-            assertThat("New session has same settings",
-                       newSession.settings, equalTo(session.settings))
-            assertThat("New session is open", newSession.isOpen, equalTo(true))
-
-            newSession.close()
-            assertThat("New session can be closed", newSession.isOpen, equalTo(false))
-        }
-
-        sessionRule.session.reload()
-        sessionRule.session.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Ignore //Disable test for frequent failures Bug 1532186
-    @Test(expected = IllegalStateException::class)
-    fun readFromParcel_throwOnAlreadyOpen() {
-        //disable readFromParcel_throwOnAlreadyOpen for frequent failures Bug 1532186
-        assumeThat(sessionRule.env.isDebugBuild, equalTo(true))
-        // Throw exception if retrying to open again; otherwise we would leak the old open window.
-        sessionRule.session.toParcel { parcel ->
-            sessionRule.createOpenSession().readFromParcel(parcel)
-        }
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_canLoadPageAfterRead() {
-        var newSession: GeckoSession? = null
-
-        sessionRule.session.toParcel { parcel ->
-            newSession = sessionRule.createFromParcel(parcel)
-        }
-
-        newSession!!.reload()
-        newSession!!.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_closedSession() {
-        val session = sessionRule.createClosedSession()
-
-        session.toParcel { parcel ->
-            val newSession = sessionRule.createFromParcel(parcel)
-            assertThat("New session should not be open",
-                       newSession.isOpen, equalTo(false))
-        }
-
-        sessionRule.session.reload()
-        sessionRule.session.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_closedSessionAfterParceling() {
-        val session = sessionRule.createOpenSession()
-
-        session.toParcel { parcel ->
-            assertThat("Session is still open", session.isOpen, equalTo(true))
-            session.close()
-
-            val newSession = sessionRule.createFromParcel(parcel)
-            assertThat("New session should not be open",
-                       newSession.isOpen, equalTo(false))
-        }
-
-        sessionRule.session.reload()
-        sessionRule.session.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_closedSessionAfterReadParcel() {
-        // disable test on opt for frequently failing Bug 1519591
-        assumeThat(sessionRule.env.isDebugBuild, equalTo(true))
-        val session = sessionRule.createOpenSession()
-
-        session.toParcel { parcel ->
-            assertThat("Session is still open", session.isOpen, equalTo(true))
-            val newSession = sessionRule.createFromParcel(parcel)
-            assertThat("New session should be open",
-                    newSession.isOpen, equalTo(true))
-            assertThat("Old session should be closed",
-                    session.isOpen, equalTo(false))
-        }
-
-        sessionRule.session.reload()
-        sessionRule.session.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_closeOpenAndLoad() {
-        var newSession: GeckoSession? = null
-
-        sessionRule.session.toParcel { parcel ->
-            newSession = sessionRule.createFromParcel(parcel)
-        }
-
-        newSession!!.close()
-        newSession!!.open()
-
-        newSession!!.reload()
-        newSession!!.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_allowCallsBeforeUnparceling() {
-        val newSession = sessionRule.createClosedSession()
-
-        newSession.loadTestPath(HELLO_HTML_PATH)
-        newSession.reload()
-
-        sessionRule.session.toParcel { parcel ->
-            newSession.readFromParcel(parcel)
-        }
-        newSession.waitForPageStops(2)
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_chained() {
-        var session1: GeckoSession? = null
-        var session2: GeckoSession? = null
-        var session3: GeckoSession? = null
-
-        sessionRule.session.toParcel { parcel ->
-            session1 = sessionRule.createFromParcel(parcel)
-        }
-        session1!!.toParcel { parcel ->
-            session2 = sessionRule.createFromParcel(parcel)
-        }
-        session2!!.toParcel { parcel ->
-            session3 = sessionRule.createFromParcel(parcel)
-        }
-
-        session3!!.reload()
-        session3!!.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @NullDelegate(GeckoSession.NavigationDelegate::class)
-    @ClosedSessionAtStart
-    @Test fun readFromParcel_moduleUpdated() {
-        val session = sessionRule.createOpenSession()
-
-        session.loadTestPath(HELLO_HTML_PATH)
-        session.waitForPageStop()
-
-        // Disable navigation notifications on the old, open session.
-        assertThat("Old session navigation delegate should be null",
-                   session.navigationDelegate, nullValue())
-
-        // Enable navigation notifications on the new, closed session.
-        var onLocationCount = 0
-        sessionRule.session.navigationDelegate = object : Callbacks.NavigationDelegate {
-            override fun onLocationChange(session: GeckoSession, url: String?) {
-                onLocationCount++
-            }
-        }
-
-        // Transferring the old session to the new session should
-        // automatically re-enable navigation notifications.
-        session.toParcel { parcel ->
-            sessionRule.session.readFromParcel(parcel)
-        }
-
-        sessionRule.session.reload()
-        sessionRule.session.waitForPageStop()
-
-        assertThat("New session should receive navigation notifications",
-                   onLocationCount, equalTo(1))
-    }
-
-    @Suppress("DEPRECATION")
-    @Test fun readFromParcel_focusedInput() {
-        // When an input is focused, make sure SessionTextInput is still active after transferring.
-        mainSession.loadTestPath(INPUTS_PATH)
-        mainSession.waitForPageStop()
-
-        mainSession.evaluateJS("document.querySelector('#input').focus()")
-        mainSession.waitUntilCalled(object : Callbacks.TextInputDelegate {
-            @AssertCalled(count = 1)
-            override fun restartInput(session: GeckoSession, reason: Int) {
-                assertThat("Reason should be correct",
-                           reason, equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_FOCUS))
-            }
-        })
-
-        var newSession: GeckoSession? = null
-        mainSession.toParcel { parcel ->
-            newSession = sessionRule.createFromParcel(parcel)
-            // Since we will be calling evaluateJS on newSession, we need to
-            // tell sessionRule to transfer mainSession's WebExtension.Port
-            // over to newSession.
-            sessionRule.transferPort(mainSession, newSession!!)
-        }
-
-        // We generate an extra focus event during transfer.
-        newSession!!.waitUntilCalled(object : Callbacks.TextInputDelegate {
-            @AssertCalled(count = 1)
-            override fun restartInput(session: GeckoSession, reason: Int) {
-                assertThat("Reason should be correct",
-                           reason, equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_FOCUS))
-            }
-        })
-
-        newSession!!.evaluateJS("document.querySelector('#input').blur()")
-        newSession!!.waitUntilCalled(object : Callbacks.TextInputDelegate {
-            @AssertCalled(count = 1)
-            override fun restartInput(session: GeckoSession, reason: Int) {
-                // We generate an extra focus event during transfer.
-                assertThat("Reason should be correct",
-                           reason, equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_BLUR))
-            }
-        })
-    }
-
-    private fun testRestoreInstanceState(fromSession: GeckoSession?,
-                                         ontoSession: GeckoSession?) =
-            GeckoView(InstrumentationRegistry.getInstrumentation().targetContext).apply {
-                id = 0
-                autofillEnabled = false
-
-                if (fromSession != null) {
-                    setSession(fromSession)
-                }
-
-                val state = SparseArray<Parcelable>()
-                saveHierarchyState(state)
-
-                if (ontoSession !== fromSession) {
-                    releaseSession()
-                    if (ontoSession != null) {
-                        setSession(ontoSession)
-                    }
-                }
-                restoreHierarchyState(state)
-            }
-
     @ClosedSessionAtStart
     @Test fun restoreRuntimeSettings_noSession() {
         val extrasSetting = Bundle(2)
         extrasSetting.putInt("test1", 10)
         extrasSetting.putBoolean("test2", true)
 
         val settings = GeckoRuntimeSettings.Builder()
                        .javaScriptEnabled(false)
@@ -342,116 +86,16 @@ class SessionLifecycleTest : BaseSession
                        newSettings.extras.getInt("test1"),
                        equalTo(settings.extras.getInt("test1")))
             assertThat("Parceled settings must match",
                        newSettings.extras.getBoolean("test2"),
                        equalTo(settings.extras.getBoolean("test2")))
         }
     }
 
-    @ClosedSessionAtStart
-    @Test fun restoreInstanceState_noSessionOntoNoSession() {
-        val view = testRestoreInstanceState(null, null)
-        assertThat("View session is restored", view.session, nullValue())
-    }
-
-    @ClosedSessionAtStart
-    @Test fun restoreInstanceState_closedSessionOntoNoSession() {
-        val view = testRestoreInstanceState(mainSession, null)
-        assertThat("View session is restored", view.session, equalTo(mainSession))
-        assertThat("View session is closed", view.session?.isOpen, equalTo(false))
-    }
-
-    @Test fun restoreInstanceState_openSessionOntoNoSession() {
-        val view = testRestoreInstanceState(mainSession, null)
-        assertThat("View session is restored", view.session, equalTo(mainSession))
-        assertThat("View session is open", view.session?.isOpen, equalTo(true))
-        view.session?.reload()
-        sessionRule.waitForPageStop()
-    }
-
-    @ClosedSessionAtStart
-    @Test fun restoreInstanceState_noSessionOntoClosedSession() {
-        val view = testRestoreInstanceState(null, sessionRule.createClosedSession())
-        assertThat("View session is not restored", view.session, notNullValue())
-        assertThat("View session is closed", view.session?.isOpen, equalTo(false))
-    }
-
-    @ClosedSessionAtStart
-    @Test fun restoreInstanceState_closedSessionOntoClosedSession() {
-        val view = testRestoreInstanceState(mainSession, sessionRule.createClosedSession())
-        assertThat("View session is restored", view.session, equalTo(mainSession))
-        assertThat("View session is closed", view.session?.isOpen, equalTo(false))
-    }
-
-    @Test fun restoreInstanceState_openSessionOntoClosedSession() {
-        val view = testRestoreInstanceState(mainSession, sessionRule.createClosedSession())
-        assertThat("View session is restored", view.session, equalTo(mainSession))
-        assertThat("View session is open", view.session?.isOpen, equalTo(true))
-        view.session?.reload()
-        sessionRule.waitForPageStop()
-    }
-
-    @ClosedSessionAtStart
-    @Test fun restoreInstanceState_noSessionOntoOpenSession() {
-        val view = testRestoreInstanceState(null, sessionRule.createOpenSession())
-        assertThat("View session is not restored", view.session, notNullValue())
-        assertThat("View session is open", view.session?.isOpen, equalTo(true))
-        view.session?.reload()
-        sessionRule.waitForPageStop()
-    }
-
-    @ClosedSessionAtStart
-    @Test(expected = IllegalStateException::class)
-    fun restoreInstanceState_closedSessionOntoOpenSession() {
-        testRestoreInstanceState(mainSession, sessionRule.createOpenSession())
-    }
-
-    @Test(expected = IllegalStateException::class)
-    fun restoreInstanceState_openSessionOntoOpenSession() {
-        testRestoreInstanceState(mainSession, sessionRule.createOpenSession())
-    }
-
-    @ClosedSessionAtStart
-    @Test fun restoreInstanceState_sameClosedSession() {
-        val view = testRestoreInstanceState(mainSession, mainSession)
-        assertThat("View session is unchanged", view.session, equalTo(mainSession))
-        assertThat("View session is closed", view.session!!.isOpen, equalTo(false))
-    }
-
-    @Test fun restoreInstanceState_sameOpenSession() {
-        // We should keep the session open when restoring the same open session.
-        val view = testRestoreInstanceState(mainSession, mainSession)
-        assertThat("View session is unchanged", view.session, equalTo(mainSession))
-        assertThat("View session is open", view.session!!.isOpen, equalTo(true))
-        view.session!!.reload()
-        sessionRule.waitForPageStop()
-    }
-
-    @Suppress("DEPRECATION")
-    @Ignore // Bug 1533934 - disabled createFromParcel on pgo for frequent failures
-    @Test fun createFromParcel() {
-        val session = sessionRule.createOpenSession()
-
-        session.toParcel { parcel ->
-            val newSession = sessionRule.wrapSession(
-                    GeckoSession.CREATOR.createFromParcel(parcel))
-
-            assertThat("New session has same settings",
-                       newSession.settings, equalTo(session.settings))
-            assertThat("New session is open", newSession.isOpen, equalTo(true))
-
-            newSession.close()
-            assertThat("New session can be closed", newSession.isOpen, equalTo(false))
-        }
-
-        sessionRule.session.reload()
-        sessionRule.session.waitForPageStop()
-    }
-
     @Test fun collectClosed() {
         // We can't use a normal scoped function like `run` because
         // those are inlined, which leaves a local reference.
         fun createSession(): QueuedWeakReference<GeckoSession> {
             return QueuedWeakReference<GeckoSession>(GeckoSession())
         }
 
         waitUntilCollected(createSession())
@@ -498,28 +142,16 @@ class SessionLifecycleTest : BaseSession
 
         // Reactivate the GeckoSession and confirm that rAF/setTimeout/etc callbacks now run
         mainSession.setActive(true)
         mainSession.waitForJS("new Promise(resolve => requestAnimationFrame(() => { resolve(); }))");
         var isGreen = mainSession.evaluateJS("document.documentElement.style.backgroundColor === 'green'") as Boolean
         assertThat("requestAnimationFrame has run", isGreen, equalTo(true))
     }
 
-    private fun dumpHprof() {
-        try {
-            val dest = File(InstrumentationRegistry.getInstrumentation().targetContext
-                    .filesDir.parent, "dump.hprof").absolutePath
-            Debug.dumpHprofData(dest)
-            Log.d(LOGTAG, "Dumped hprof to $dest")
-        } catch (e: IOException) {
-            Log.e(LOGTAG, "Failed to dump hprof", e)
-        }
-
-    }
-
     private fun waitUntilCollected(ref: QueuedWeakReference<*>) {
         UiThreadUtils.waitForCondition({
             Runtime.getRuntime().gc()
             ref.queue.poll() != null
         }, sessionRule.timeoutMillis)
     }
 
     class QueuedWeakReference<T> @JvmOverloads constructor(obj: T, var queue: ReferenceQueue<T> =
--- 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
@@ -3,17 +3,16 @@
  * 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.rule;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONTokener;
-import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.geckoview.Autofill;
 import org.mozilla.geckoview.ContentBlocking;
 import org.mozilla.geckoview.GeckoDisplay;
 import org.mozilla.geckoview.GeckoResult;
 import org.mozilla.geckoview.GeckoRuntime;
 import org.mozilla.geckoview.GeckoSession;
 import org.mozilla.geckoview.GeckoSessionSettings;
@@ -24,33 +23,31 @@ import org.mozilla.geckoview.WebExtensio
 import org.mozilla.geckoview.WebExtensionController;
 import org.mozilla.geckoview.test.util.TestServer;
 import org.mozilla.geckoview.test.util.RuntimeCreator;
 import org.mozilla.geckoview.test.util.Environment;
 import org.mozilla.geckoview.test.util.UiThreadUtils;
 import org.mozilla.geckoview.test.util.Callbacks;
 
 import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
 import org.hamcrest.Matcher;
 
 import org.json.JSONObject;
 
 import org.junit.rules.ErrorCollector;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
 import android.app.Instrumentation;
 import android.graphics.Point;
 import android.graphics.SurfaceTexture;
-import android.os.Parcel;
 import android.os.SystemClock;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import androidx.test.platform.app.InstrumentationRegistry;
 import android.util.Log;
 import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.Surface;
@@ -71,17 +68,16 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
 
 import kotlin.jvm.JvmClassMappingKt;
 import kotlin.reflect.KClass;
 
 /**
  * TestRule that, for each test, sets up a GeckoSession, runs the test on the UI thread,
@@ -1964,22 +1960,16 @@ public class GeckoSessionTestRule implem
                                        final boolean open) {
         final GeckoSession session = wrapSession(new GeckoSession(settings));
         if (open) {
             openSession(session);
         }
         return session;
     }
 
-    public GeckoSession createFromParcel(Parcel source) {
-        final GeckoSession session = new GeckoSession(mMainSession.getSettings());
-        session.readFromParcel(source);
-        return wrapSession(session);
-    }
-
     /**
      * This method is a temporary hack to ensure that sessions reconstituted from parcels
      * have their WebExtension.Port transferred over to the reconstituted session.
      *
      * This will be removed when we remove the ability of GeckoSession to be Parcelable.
      */
     public void transferPort(@NonNull final GeckoSession fromSession, @NonNull final GeckoSession toSession) {
         final WebExtension.Port port = mPorts.remove(fromSession);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -44,17 +44,16 @@ import android.content.ContentResolver;
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.IBinder;
 import android.os.IInterface;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.support.annotation.AnyThread;
 import android.support.annotation.IntDef;
 import android.support.annotation.LongDef;
 import android.support.annotation.Nullable;
@@ -68,17 +67,17 @@ import android.util.LongSparseArray;
 import android.util.SparseArray;
 import android.view.Surface;
 import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.View;
 import android.view.ViewStructure;
 
-public class GeckoSession implements Parcelable {
+public class GeckoSession {
     private static final String LOGTAG = "GeckoSession";
     private static final boolean DEBUG = false;
 
     // Type of changes given to onWindowChanged.
     // Window has been cleared due to the session being closed.
     private static final int WINDOW_CLOSE = 0;
     // Window has been set due to the session being opened.
     private static final int WINDOW_OPEN = 1; // Window has been opened.
@@ -1312,80 +1311,16 @@ public class GeckoSession implements Par
         }
     }
 
     /* package */ void transferFrom(final GeckoSession session) {
         transferFrom(session.mWindow, session.mSettings, session.mId);
         session.mWindow = null;
     }
 
-    /**
-     * @deprecated Use {@link ProgressDelegate#onSessionStateChange(GeckoSession, GeckoSession.SessionState)} and
-     * {@link #restoreState} instead. This method will be removed in GeckoView 82.
-     */
-    @Deprecated // Bug 1650108
-    @Override // Parcelable
-    @AnyThread
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @deprecated Use {@link ProgressDelegate#onSessionStateChange(GeckoSession, GeckoSession.SessionState)} and
-     * {@link #restoreState} instead. This method will be removed in GeckoView 82.
-     */
-    @Deprecated // Bug 1650108
-    @Override // Parcelable
-    @AnyThread
-    public void writeToParcel(final Parcel out, final int flags) {
-        out.writeStrongInterface(mWindow);
-        out.writeParcelable(mSettings, flags);
-        out.writeString(mId);
-    }
-
-    // AIDL code may call readFromParcel even though it's not part of Parcelable.
-    /**
-     * @deprecated Use {@link ProgressDelegate#onSessionStateChange(GeckoSession, GeckoSession.SessionState)} and
-     * {@link #restoreState} instead. This method will be removed in GeckoView 82.
-     */
-    @Deprecated // Bug 1650108
-    @AnyThread
-    @SuppressWarnings("checkstyle:javadocmethod")
-    public void readFromParcel(final @NonNull Parcel source) {
-        final IBinder binder = source.readStrongBinder();
-        final IInterface ifce = (binder != null) ?
-                binder.queryLocalInterface(Window.class.getName()) : null;
-        final Window window = (ifce instanceof Window) ? (Window) ifce : null;
-        final GeckoSessionSettings settings =
-                source.readParcelable(getClass().getClassLoader());
-        final String id = source.readString();
-        transferFrom(window, settings, id);
-    }
-
-    /**
-     * @deprecated Use {@link ProgressDelegate#onSessionStateChange(GeckoSession, GeckoSession.SessionState)} and
-     * {@link #restoreState} instead. This field will be removed in GeckoView 82.
-     */
-    @Deprecated // Bug 1650108
-    public static final Creator<GeckoSession> CREATOR = new Creator<GeckoSession>() {
-        @Override
-        @AnyThread
-        public GeckoSession createFromParcel(final Parcel in) {
-            final GeckoSession session = new GeckoSession();
-            session.readFromParcel(in);
-            return session;
-        }
-
-        @Override
-        @AnyThread
-        public GeckoSession[] newArray(final int size) {
-            return new GeckoSession[size];
-        }
-    };
-
     /* package */ boolean equalsId(final GeckoSession other) {
         if (other == null) {
             return false;
         }
 
         return mId.equals(other.mId);
     }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -22,18 +22,16 @@ import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.os.Build;
 import android.os.Handler;
-import android.os.Parcel;
-import android.os.Parcelable;
 import android.support.annotation.AnyThread;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -71,48 +69,16 @@ public class GeckoView extends FrameLayo
 
     private boolean mIsResettingFocus;
 
     private boolean mAutofillEnabled = true;
 
     private GeckoSession.SelectionActionDelegate mSelectionActionDelegate;
     private Autofill.Delegate mAutofillDelegate;
 
-    private static class SavedState extends BaseSavedState {
-        public final GeckoSession session;
-
-        public SavedState(final Parcelable superState, final GeckoSession session) {
-            super(superState);
-            this.session = session;
-        }
-
-        /* package */ SavedState(final Parcel in) {
-            super(in);
-            session = in.readParcelable(getClass().getClassLoader());
-        }
-
-        @Override // BaseSavedState
-        public void writeToParcel(final Parcel dest, final int flags) {
-            super.writeToParcel(dest, flags);
-            dest.writeParcelable(session, flags);
-        }
-
-        public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
-            @Override
-            public SavedState createFromParcel(final Parcel in) {
-                return new SavedState(in);
-            }
-
-            @Override
-            public SavedState[] newArray(final int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
     private class Display implements SurfaceViewWrapper.Listener {
         private final int[] mOrigin = new int[2];
 
         private GeckoDisplay mDisplay;
         private boolean mValid;
 
         private int mClippingHeight;
         private int mDynamicToolbarMaxHeight;
@@ -559,46 +525,16 @@ public class GeckoView extends FrameLayo
         // which is more expensive.
         if (mSurfaceWrapper != null) {
             mDisplay.onGlobalLayout();
         }
         return super.gatherTransparentRegion(region);
     }
 
     @Override
-    protected Parcelable onSaveInstanceState() {
-        mStateSaved = true;
-        return new SavedState(super.onSaveInstanceState(), mSession);
-    }
-
-    @Override
-    protected void onRestoreInstanceState(final Parcelable state) {
-        mStateSaved = false;
-
-        if (!(state instanceof SavedState)) {
-            super.onRestoreInstanceState(state);
-            return;
-        }
-
-        final SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-
-        restoreSession(ss.session);
-    }
-
-    private void restoreSession(final @Nullable GeckoSession savedSession) {
-        if (savedSession == null || savedSession.equalsId(mSession)) {
-            return;
-        }
-
-        // This can throw if there's already an open session set, but that's the right thing to do.
-        setSession(savedSession);
-    }
-
-    @Override
     public void onWindowFocusChanged(final boolean hasWindowFocus) {
         super.onWindowFocusChanged(hasWindowFocus);
 
         // Only call setFocus(true) when the window gains focus. Any focus loss could be temporary
         // (e.g. due to auto-fill popups) and we don't want to call setFocus(false) in those cases.
         // Instead, we call setFocus(false) in onWindowVisibilityChanged.
         if (mSession != null && hasWindowFocus && isFocused()) {
             mSession.setFocused(true);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -25,21 +25,24 @@ exclude: true
   ([bug 1530022]({{bugzilla}}1530022))
 - Added [`Image`][82.3] support for size-dependent bitmap retrieval from image resources.
   ([bug 1658456]({{bugzilla}}1658456))
 - ⚠️ Use [`Image`][82.3] for [`MediaSession`][81.6] artwork and [`WebExtension`][69.5] icon support.
   ([bug 1662508]({{bugzilla}}1662508))
 - Added [`RepostConfirmPrompt`][82.4] to prompt the user for cofirmation before
   resending POST requests.
   ([bug 1659073]({{bugzilla}}1659073))
+- Removed `Parcelable` support in `GeckoSession`. Use [`ProgressDelegate#onSessionStateChange`][68.29] and [`ProgressDelegate#restoreState`][82.5] instead.
+  ([bug 1650108]({{bugzilla}}1650108))
   
 [82.1]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onExternalResponse-org.mozilla.geckoview.GeckoSession-org.mozilla.geckoview.GeckoSession.WebResponseInfo-
 [82.2]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onExternalResponse-org.mozilla.geckoview.GeckoSession-org.mozilla.geckoview.GeckoResult-
 [82.3]: {{javadoc_uri}}/Image.html
 [82.4]: {{javadoc_uri}}/GeckoSession.PromptDelegate.RepostConfirmPrompt.html
+[82.5]: {{javadoc_uri}}/GeckoSession.html#restoreState-org.mozilla.geckoview.GeckoSession.SessionState-
 
 ## v81
 - Added `cookiePurging` to [`ContentBlocking.Settings.Builder`][81.1] and `getCookiePurging` and `setCookiePurging`
   to [`ContentBlocking.Settings`][81.2].
 - Added [`GeckoSession.ContentDelegate.onPaintStatusReset()`][81.3] callback which notifies when valid content is no longer being rendered.
 - Made [`GeckoSession.ContentDelegate.onFirstContentfulPaint()`][81.4] additionally be called for the first contentful paint following a `onPaintStatusReset()` event, rather than just the first contentful paint of the session.
 - Removed deprecated `GeckoRuntime.registerWebExtension`. Use [`WebExtensionController.install`][73.1] instead.
 ⚠️ - Changed [`GeckoView.onTouchEventForResult`][81.5] to return a `GeckoResult`, as it now
@@ -788,9 +791,9 @@ to allow adding gecko profiler markers.
 [65.19]: {{javadoc_uri}}/GeckoSession.NavigationDelegate.LoadRequest.html#isRedirect
 [65.20]: {{javadoc_uri}}/GeckoSession.html#LOAD_FLAGS_BYPASS_CLASSIFIER
 [65.21]: {{javadoc_uri}}/GeckoSession.ContentDelegate.ContextElement.html
 [65.22]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onContextMenu-org.mozilla.geckoview.GeckoSession-int-int-org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement-
 [65.23]: {{javadoc_uri}}/GeckoSession.FinderResult.html
 [65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
 [65.25]: {{javadoc_uri}}/GeckoResult.html
 
-[api-version]: b2f304bfc18a9b3ce4bbe4cc12bc31be42f6fde8
+[api-version]: b75e10652f129f9fd9414e3c94cac91203a99927
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/TabSession.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/TabSession.java
@@ -36,41 +36,9 @@ public class TabSession extends GeckoSes
     public void loadUri(@NonNull String uri) {
         super.loadUri(uri);
         mUri = uri;
     }
 
     public void onLocationChange(@NonNull String uri) {
         mUri = uri;
     }
-
-    @Override // Parcelable
-    @UiThread
-    public void writeToParcel(final Parcel out, final int flags) {
-        super.writeToParcel(out, flags);
-        out.writeString(mTitle);
-        out.writeString(mUri);
-    }
-
-    // AIDL code may call readFromParcel even though it's not part of Parcelable.
-    @UiThread
-    public void readFromParcel(final @NonNull Parcel source) {
-        super.readFromParcel(source);
-        mTitle = source.readString();
-        mUri = source.readString();
-    }
-
-    public static final Creator<GeckoSession> CREATOR = new Creator<GeckoSession>() {
-        @Override
-        @UiThread
-        public TabSession createFromParcel(final Parcel in) {
-            final TabSession session = new TabSession();
-            session.readFromParcel(in);
-            return session;
-        }
-
-        @Override
-        @UiThread
-        public TabSession[] newArray(final int size) {
-            return new TabSession[size];
-        }
-    };
 }