From b0378f8bb4874bf5f184605b18b1ee87a5977cc8 Mon Sep 17 00:00:00 2001 From: Matthew Finkel Date: Wed, 29 May 2019 14:05:07 +0000 Subject: [PATCH] Bug 30573 - Sanitize old tabs and wait for tor before opening new tabs --- .../java/org/mozilla/gecko/BrowserApp.java | 4 +- .../base/java/org/mozilla/gecko/GeckoApp.java | 55 ++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java index d99baf371b9fd..01111c4ca94f8 100644 --- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -1107,7 +1107,7 @@ public class BrowserApp extends GeckoApp * * mTorStatus provides synchronization across threads. */ - private boolean checkTorIsStarted() { + public boolean checkTorIsStarted() { // When tor is started, true. Otherwise, false mTorStatus = false; BroadcastReceiver br = setupReceiveTorIsStartedAsync(); @@ -2099,6 +2099,7 @@ public class BrowserApp extends GeckoApp finishAndShutdown(/* restart */ false); } } + super.handleMessage(event, message, callback); break; case "Sanitize:OpenTabs": @@ -2972,6 +2973,7 @@ public class BrowserApp extends GeckoApp // If we finished, then Tor bootstrapped 100% mTorNeedsStart = false; + EventDispatcher.getInstance().dispatch("Tor:Ready", null); // When bootstrapping completes, check if the Firstrun (onboarding) screens // should be shown. diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java index fcea7e79fb213..a8c0df25b1e57 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -195,6 +195,10 @@ public abstract class GeckoApp extends GeckoActivity protected Menu mMenu; protected boolean mIsRestoringActivity; + protected boolean mIsSanitizeTabsEnabled = false; + protected boolean mIsSanitizeCompleted = false; + protected Object mIsSanitizeCompletedLock = new Object(); + /** Tells if we're aborting app launch, e.g. if this is an unsupported device configuration. */ protected boolean mIsAbortingAppLaunch; @@ -606,6 +610,12 @@ public abstract class GeckoApp extends GeckoActivity for (final String clear : clearSet) { clearObj.putBoolean(clear, true); } + + synchronized (mIsSanitizeCompletedLock) { + mIsSanitizeTabsEnabled = clearSet.contains("private.data.openTabs"); + mIsSanitizeCompleted = false; + } + return clearObj; } @@ -790,6 +800,11 @@ public abstract class GeckoApp extends GeckoActivity notifyAll(); } + } else if ("Sanitize:Finished".equals(event)) { + synchronized (mIsSanitizeCompletedLock) { + mIsSanitizeCompleted = true; + } + } else if ("SystemUI:Visibility".equals(event)) { if (message.getBoolean("visible", true)) { mMainLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); @@ -1618,7 +1633,45 @@ public abstract class GeckoApp extends GeckoActivity loadStartupTab(Tabs.LOADURL_NEW_TAB, action); } else { final int flags = getNewTabFlags(); - loadStartupTab(passedUri, intent, flags); + final BrowserApp browserApp = (BrowserApp) GeckoApp.this; + + synchronized (mIsSanitizeCompletedLock) { + // If OpenTabs will be sanitized, then load the tab after Sanitize:Finished + // is received. If Tor isn't started, then load tabs after Tor:Ready, too. And + // if Gecko isn't loaded, then wait until the profile is loaded (avoiding the race + // between loading the page and checking if |browser.privatebrowsing.autoStart| is true. + EventDispatcher.getInstance().registerUiThreadListener(new BundleEventListener() { + // isSanitized is true if Sanitizing is enable and it is completed or if Sanitizing is disabled. + private boolean isSanitized = (mIsSanitizeTabsEnabled && mIsSanitizeCompleted) || !mIsSanitizeTabsEnabled; + private boolean isTorReady = browserApp.checkTorIsStarted(); + private boolean isGeckoReady = GeckoThread.isRunning(); + + @Override + public void handleMessage(String event, GeckoBundle message, EventCallback callback) { + if ("Sanitize:Finished".equals(event)) { + EventDispatcher.getInstance().unregisterUiThreadListener(this, "Sanitize:Finished"); + isSanitized = true; + + } else if ("Tor:Ready".equals(event)) { + EventDispatcher.getInstance().unregisterUiThreadListener(this, "Tor:Ready"); + isTorReady = true; + } else if ("Gecko:Ready".equals(event)) { + EventDispatcher.getInstance().unregisterUiThreadListener(this, "Gecko:Ready"); + isGeckoReady = true; + } else if ("Tor:CheckIfReady".equals(event)) { + EventDispatcher.getInstance().unregisterUiThreadListener(this, "Tor:CheckIfReady"); + } + + if (isSanitized && isTorReady && isGeckoReady) { + loadStartupTab(passedUri, intent, flags); + } + } + }, "Sanitize:Finished", "Tor:Ready", "Tor:CheckIfReady", "Gecko:Ready"); + + // Run the event callback now, just in case Tor:Ready and Sanitize:Finished were + // dispatched before the listener was created. + EventDispatcher.getInstance().dispatch("Tor:CheckIfReady", null); + } } } }); -- GitLab