Skip to content

Commit

Permalink
Bug 1734394 - Make Geckoview use the session store collector r=geckov…
Browse files Browse the repository at this point in the history
…iew-reviewers,agi,farre,peterv

When the session storage prefs are enabled, GeckoSession updateSessionState will provide the bundle of information, including zoom, scroll, and form data, to the delegate. Currently works for Fission and on Fenix.

Differential Revision: https://phabricator.services.mozilla.com/D148215
  • Loading branch information
calumozilla committed Jul 15, 2022
1 parent 5601c9d commit df9bafb
Show file tree
Hide file tree
Showing 26 changed files with 594 additions and 299 deletions.
4 changes: 4 additions & 0 deletions browser/app/profile/firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,10 @@ pref("browser.sessionstore.upgradeBackup.maxUpgradeBackups", 3);
pref("browser.sessionstore.debug", false);
// Forget closed windows/tabs after two weeks
pref("browser.sessionstore.cleanup.forget_closed_after", 1209600000);
// Platform collects data for session store
pref("browser.sessionstore.platform_collection", true);
// Platform collects session storage data for session store
pref("browser.sessionstore.collect_session_storage", true);

// Don't quit the browser when Ctrl + Q is pressed.
pref("browser.quitShortcut.disabled", false);
Expand Down
4 changes: 2 additions & 2 deletions docshell/base/CanonicalBrowsingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2445,7 +2445,7 @@ nsresult CanonicalBrowsingContext::WriteSessionStorageToSessionStore(

void CanonicalBrowsingContext::UpdateSessionStoreSessionStorage(
const std::function<void()>& aDone) {
if constexpr (!SessionStoreUtils::NATIVE_LISTENER) {
if (!StaticPrefs::browser_sessionstore_collect_session_storage_AtStartup()) {
aDone();
return;
}
Expand Down Expand Up @@ -2478,7 +2478,7 @@ void CanonicalBrowsingContext::UpdateSessionStoreForStorage(
}

void CanonicalBrowsingContext::MaybeScheduleSessionStoreUpdate() {
if constexpr (!SessionStoreUtils::NATIVE_LISTENER) {
if (!StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
return;
}

Expand Down
4 changes: 2 additions & 2 deletions docshell/base/nsDocShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5781,7 +5781,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
}
}

if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
if (IsForceReloadType(mLoadType)) {
if (WindowContext* windowContext =
mBrowsingContext->GetCurrentWindowContext()) {
Expand Down Expand Up @@ -6525,7 +6525,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// incorrectly overrides session store data from the following load.
return NS_OK;
}
if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
if (WindowContext* windowContext =
mBrowsingContext->GetCurrentWindowContext()) {
using Change = SessionStoreChangeListener::Change;
Expand Down
2 changes: 1 addition & 1 deletion dom/base/nsFrameLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3089,7 +3089,7 @@ nsresult nsFrameLoader::EnsureMessageManager() {
NS_ENSURE_TRUE(mChildMessageManager, NS_ERROR_UNEXPECTED);

// Set up session store
if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
if (XRE_IsParentProcess() && mIsTopLevelContent) {
mSessionStoreChild = SessionStoreChild::GetOrCreate(
GetExtantBrowsingContext(), mOwnerContent);
Expand Down
12 changes: 12 additions & 0 deletions dom/chrome-webidl/BrowserSessionStore.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ interface SessionStoreFormData {
object toJSON();
};

[GenerateConversionToJS]
dictionary SessionStoreDisplaySize {
unsigned long width;
unsigned long height;
};

[GenerateConversionToJS]
dictionary SessionStoreZoomData {
double resolution;
SessionStoreDisplaySize displaySize;
};

[ChromeOnly, Exposed=Window]
interface SessionStoreScrollData {
[Cached, Pure]
Expand Down
2 changes: 1 addition & 1 deletion dom/ipc/BrowserChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ nsresult BrowserChild::Init(mozIDOMWindowProxy* aParent,

mIPCOpen = true;

if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
mSessionStoreChild = SessionStoreChild::GetOrCreate(mBrowsingContext);
}

Expand Down
2 changes: 1 addition & 1 deletion dom/storage/SessionStorageManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ void BackgroundSessionStorageManager::SetCurrentBrowsingContextId(
}

void BackgroundSessionStorageManager::MaybeScheduleSessionStoreUpdate() {
if constexpr (!SessionStoreUtils::NATIVE_LISTENER) {
if (!StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
return;
}

Expand Down
10 changes: 8 additions & 2 deletions mobile/android/chrome/geckoview/SessionStateAggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const DEFAULT_INTERVAL_MS = 1500;
const TIMEOUT_DISABLED_PREF = "browser.sessionstore.debug.no_auto_updates";

const PREF_INTERVAL = "browser.sessionstore.interval";
const PREF_SESSION_COLLECTION = "browser.sessionstore.platform_collection";

class Handler {
constructor(store) {
Expand Down Expand Up @@ -598,13 +599,18 @@ class SessionStateAggregator extends GeckoViewChildModule {
this.stateChangeNotifier = new StateChangeNotifier(this);

this.handlers = [
new FormDataListener(this),
new SessionHistoryListener(this),
new ScrollPositionListener(this),
this.stateChangeNotifier,
this.messageQueue,
];

if (!Services.prefs.getBoolPref(PREF_SESSION_COLLECTION, false)) {
this.handlers.push(
new FormDataListener(this),
new ScrollPositionListener(this)
);
}

this.messageManager.addMessageListener("GeckoView:FlushSessionState", this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,36 @@ private void onShowDynamicToolbar() {
}
});
}

@WrapForJNI(calledFrom = "gecko")
private void onUpdateSessionStore(final GeckoBundle aBundle) {
ThreadUtils.runOnUiThread(
() -> {
final GeckoSession session = mOwner.get();
if (session == null) {
return;
}
GeckoBundle scroll = aBundle.getBundle("scroll");
if (scroll == null) {
scroll = new GeckoBundle();
aBundle.putBundle("scroll", scroll);
}

// Here we unfortunately need to do some re-mapping since `zoom` is passed in a separate
// bunds and we wish to keep the bundle format.
scroll.putBundle("zoom", aBundle.getBundle("zoom"));
final SessionState stateCache = session.mStateCache;
stateCache.updateSessionState(aBundle);
final SessionState state = new SessionState(stateCache);
if (!state.isEmpty()) {
final ProgressDelegate progressDelegate = session.getProgressDelegate();
if (progressDelegate != null) {
progressDelegate.onSessionStateChange(session, state);
} else {
}
}
});
}
}

private class Listener implements BundleEventListener {
Expand Down
18 changes: 18 additions & 0 deletions modules/libpref/init/StaticPrefList.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,24 @@
value: 15000
mirror: always

# Platform collection of data for session store
- name: browser.sessionstore.platform_collection
type: bool
value: @IS_NOT_ANDROID@
mirror: once

# Platform collection of session storage data for session store
- name: browser.sessionstore.collect_session_storage
type: bool
value: @IS_NOT_ANDROID@
mirror: once

# Platform collection of zoom data for session store
- name: browser.sessionstore.collect_zoom
type: bool
value: @IS_NOT_ANDROID@
mirror: once

# Causes SessionStore to ignore non-final update messages from
# browser tabs that were not caused by a flush from the parent.
# This is a testing flag and should not be used by end-users.
Expand Down
5 changes: 3 additions & 2 deletions toolkit/components/sessionstore/PSessionStore.ipdl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include protocol PInProcess;
include SessionStoreTypes;

using mozilla::dom::MaybeDiscardedBrowsingContext from "mozilla/dom/BrowsingContext.h";
using mozilla::dom::MaybeSessionStoreZoom from "mozilla/dom/SessionStoreScrollData.h";

namespace mozilla {
namespace dom {
Expand All @@ -31,8 +32,8 @@ parent:
* collected incrementally.
*/
async SessionStoreUpdate(
nsCString? aDocShellCaps, bool? aPrivateMode, bool aNeedCollectSHistory,
uint32_t aEpoch);
nsCString? aDocShellCaps, bool? aPrivateMode, MaybeSessionStoreZoom aZoom,
bool aNeedCollectSHistory, uint32_t aEpoch);

/**
* Sends data to be stored to the session store. The collected data
Expand Down
50 changes: 47 additions & 3 deletions toolkit/components/sessionstore/SessionStoreChangeListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
#include "nsPIDOMWindow.h"
#include "nsTHashMap.h"
#include "nsTHashtable.h"
#include "nsLayoutUtils.h"

using namespace mozilla;
using namespace mozilla::dom;

namespace {
constexpr auto kInput = u"input"_ns;
constexpr auto kScroll = u"mozvisualscroll"_ns;
constexpr auto kResize = u"mozvisualresize"_ns;

static constexpr char kNoAutoUpdates[] =
"browser.sessionstore.debug.no_auto_updates";
Expand Down Expand Up @@ -120,14 +122,16 @@ SessionStoreChangeListener::HandleEvent(dom::Event* aEvent) {
RecordChange(windowContext, Change::Input);
} else if (eventType == kScroll) {
RecordChange(windowContext, Change::Scroll);
} else if (eventType == kResize && browsingContext->IsTop()) {
RecordChange(windowContext, Change::Resize);
}

return NS_OK;
}

/* static */ already_AddRefed<SessionStoreChangeListener>
SessionStoreChangeListener::Create(BrowsingContext* aBrowsingContext) {
MOZ_RELEASE_ASSERT(SessionStoreUtils::NATIVE_LISTENER);
MOZ_RELEASE_ASSERT(
StaticPrefs::browser_sessionstore_platform_collection_AtStartup());
if (!aBrowsingContext) {
return nullptr;
}
Expand Down Expand Up @@ -181,6 +185,29 @@ static void CollectFormData(Document* aDocument,
}
}

static void GetZoom(BrowsingContext* aBrowsingContext,
Maybe<SessionStoreZoom>& aZoom) {
nsIDocShell* docShell = aBrowsingContext->GetDocShell();
if (!docShell) {
return;
}

PresShell* presShell = docShell->GetPresShell();
if (!presShell) {
return;
}

LayoutDeviceIntSize displaySize;

if (!nsLayoutUtils::GetContentViewerSize(presShell->GetPresContext(),
displaySize)) {
return;
}

aZoom.emplace(presShell->GetResolution(), displaySize.width,
displaySize.height);
}

void SessionStoreChangeListener::FlushSessionStore() {
if (mTimer) {
mTimer->Cancel();
Expand All @@ -189,6 +216,7 @@ void SessionStoreChangeListener::FlushSessionStore() {

bool collectSessionHistory = false;
bool collectWireFrame = false;
bool didResize = false;

for (auto& iter : mSessionStoreChanges) {
WindowContext* windowContext = iter.GetKey();
Expand Down Expand Up @@ -230,6 +258,10 @@ void SessionStoreChangeListener::FlushSessionStore() {
collectSessionHistory =
collectSessionHistory || changes.contains(Change::SessionHistory);

if (presShell && changes.contains(Change::Resize)) {
didResize = true;
}

mSessionStoreChild->IncrementalSessionStoreUpdate(
browsingContext, maybeFormData, maybeScroll, mEpoch);
}
Expand All @@ -239,7 +271,13 @@ void SessionStoreChangeListener::FlushSessionStore() {
}

mSessionStoreChanges.Clear();
mSessionStoreChild->UpdateSessionStore(collectSessionHistory);

Maybe<SessionStoreZoom> zoom;
if (didResize) {
GetZoom(mBrowsingContext->Top(), zoom);
}

mSessionStoreChild->UpdateSessionStore(collectSessionHistory, zoom);
}

/* static */
Expand Down Expand Up @@ -314,6 +352,9 @@ void SessionStoreChangeListener::AddEventListeners() {
if (EventTarget* target = GetEventTarget()) {
target->AddSystemEventListener(kInput, this, false);
target->AddSystemEventListener(kScroll, this, false);
if (StaticPrefs::browser_sessionstore_collect_zoom_AtStartup()) {
target->AddSystemEventListener(kResize, this, false);
}
mCurrentEventTarget = target;
}
}
Expand All @@ -322,6 +363,9 @@ void SessionStoreChangeListener::RemoveEventListeners() {
if (mCurrentEventTarget) {
mCurrentEventTarget->RemoveSystemEventListener(kInput, this, false);
mCurrentEventTarget->RemoveSystemEventListener(kScroll, this, false);
if (StaticPrefs::browser_sessionstore_collect_zoom_AtStartup()) {
mCurrentEventTarget->RemoveSystemEventListener(kResize, this, false);
}
}

mCurrentEventTarget = nullptr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class SessionStoreChangeListener final : public nsINamed,

void FlushSessionStore();

enum class Change { Input, Scroll, SessionHistory, WireFrame };
enum class Change { Input, Scroll, SessionHistory, WireFrame, Resize };

static SessionStoreChangeListener* CollectSessionStoreData(
WindowContext* aWindowContext, const EnumSet<Change>& aChanges);
Expand Down
15 changes: 9 additions & 6 deletions toolkit/components/sessionstore/SessionStoreChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,12 @@ void SessionStoreChild::UpdateEventTargets() {
}
}

void SessionStoreChild::UpdateSessionStore(bool aSessionHistoryUpdate) {
void SessionStoreChild::UpdateSessionStore(bool aSessionHistoryUpdate,
const MaybeSessionStoreZoom& aZoom) {
if (!mSessionStoreListener) {
// This is the case when we're shutting down, and expect a final update.
SessionStoreUpdate(Nothing(), Nothing(), aSessionHistoryUpdate, 0);
SessionStoreUpdate(Nothing(), Nothing(), Nothing(), aSessionHistoryUpdate,
0);
return;
}

Expand All @@ -187,7 +189,7 @@ void SessionStoreChild::UpdateSessionStore(bool aSessionHistoryUpdate) {
}

SessionStoreUpdate(
docShellCaps, privatedMode,
docShellCaps, privatedMode, aZoom,
store->GetAndClearSHistoryChanged() || aSessionHistoryUpdate,
mSessionStoreListener->GetEpoch());
}
Expand Down Expand Up @@ -216,14 +218,15 @@ mozilla::ipc::IPCResult SessionStoreChild::RecvFlushTabState(

void SessionStoreChild::SessionStoreUpdate(
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
const bool aNeedCollectSHistory, const uint32_t& aEpoch) {
const MaybeSessionStoreZoom& aZoom, const bool aNeedCollectSHistory,
const uint32_t& aEpoch) {
if (XRE_IsContentProcess()) {
Unused << SendSessionStoreUpdate(aDocShellCaps, aPrivatedMode,
Unused << SendSessionStoreUpdate(aDocShellCaps, aPrivatedMode, aZoom,
aNeedCollectSHistory, aEpoch);
} else if (SessionStoreParent* sessionStoreParent =
static_cast<SessionStoreParent*>(
InProcessChild::ParentActorFor(this))) {
sessionStoreParent->SessionStoreUpdate(aDocShellCaps, aPrivatedMode,
sessionStoreParent->SessionStoreUpdate(aDocShellCaps, aPrivatedMode, aZoom,
aNeedCollectSHistory, aEpoch);
}
}
Expand Down
5 changes: 4 additions & 1 deletion toolkit/components/sessionstore/SessionStoreChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/dom/PSessionStoreChild.h"
#include "mozilla/dom/SessionStoreScrollData.h"
#include "mozilla/dom/SessionStoreChangeListener.h"
#include "mozilla/dom/SessionStoreListener.h"
#include "mozilla/RefPtr.h"
Expand All @@ -31,12 +32,14 @@ class SessionStoreChild final : public PSessionStoreChild {
void SetOwnerContent(Element* aElement);
void Stop();
void UpdateEventTargets();
void UpdateSessionStore(bool aSessionHistoryUpdate = false);
void UpdateSessionStore(bool aSessionHistoryUpdate = false,
const MaybeSessionStoreZoom& aZoom = Nothing());
void FlushSessionStore();
void UpdateSHistoryChanges();

void SessionStoreUpdate(const Maybe<nsCString>& aDocShellCaps,
const Maybe<bool>& aPrivatedMode,
const MaybeSessionStoreZoom& aZoom,
const bool aNeedCollectSHistory,
const uint32_t& aEpoch);

Expand Down
Loading

0 comments on commit df9bafb

Please sign in to comment.