Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Sessions are recreated correctly when clearing data #2362

Merged
merged 2 commits into from Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -345,6 +345,24 @@ public void suspend() {
mState.mSession = null;
}

private boolean shouldLoadDefaultPage(@NonNull SessionState aState) {
if (aState.mUri != null && aState.mUri.length() != 0 && !aState.mUri.equals(mContext.getString(R.string.about_blank))) {
return false;
}
if (aState.mSessionState != null && aState.mSessionState.size() != 0) {
return false;
}
return true;
}

private void loadDefaultPage() {
if (mState.mSettings.isPrivateBrowsingEnabled()) {
loadPrivateBrowsingPage();
} else {
loadHomePage();
}
}

private void restore() {
SessionSettings settings = mState.mSettings;
if (settings == null) {
Expand All @@ -364,18 +382,17 @@ private void restore() {
mState.mUri = null;
}

if (mState.mSessionState != null) {
if (shouldLoadDefaultPage(mState)) {
loadDefaultPage();
} else if (mState.mSessionState != null) {
mState.mSession.restoreState(mState.mSessionState);
} else if (mState.mUri != null) {
mState.mSession.loadUri(mState.mUri);
} else {
loadDefaultPage();
}

if ((mState.mSessionState == null) && (mState.mUri != null)) {
mState.mSession.loadUri(mState.mUri);
} else if (mState.mSettings.isPrivateBrowsingEnabled() && mState.mUri == null) {
loadPrivateBrowsingPage();
} else if(mState.mSessionState == null || ((mState.mUri == null) || mState.mUri.equals(mContext.getResources().getString(R.string.about_blank))) ||
(mState.mSessionState != null && mState.mSessionState.size() == 0)) {
loadHomePage();
} else if (mState.mUri != null && mState.mUri.contains(".youtube.com")) {
if (mState.mUri != null && mState.mUri.contains(".youtube.com")) {
mState.mSession.loadUri(mState.mUri, GeckoSession.LOAD_FLAGS_REPLACE_HISTORY);
}

Expand Down Expand Up @@ -419,20 +436,19 @@ private GeckoSession createGeckoSession(@NonNull SessionSettings aSettings) {
return session;
}

private void recreateSession() {
public void recreateSession() {
SessionState previous = mState;
mState = mState.recreate();
restore();

mState = createSession(previous.mSettings, SESSION_OPEN);
mState.setActive(true);
if (previous.mSessionState != null) {
mState.mSession.restoreState(previous.mSessionState);
}
GeckoSession previousGeckoSession = null;
if (previous.mSession != null) {
previousGeckoSession = previous.mSession;
closeSession(previous);
}

for (SessionChangeListener listener : mSessionChangeListeners) {
listener.onCurrentSessionChange(previous.mSession, mState.mSession);
listener.onCurrentSessionChange(previousGeckoSession, mState.mSession);
}
}

Expand All @@ -444,12 +460,13 @@ private void closeSession(@NonNull SessionState aState) {
aState.mSession.setActive(false);
aState.mSession.stop();
if (aState.mDisplay != null) {
surfaceDestroyed();
aState.mDisplay.surfaceDestroyed();
aState.mSession.releaseDisplay(aState.mDisplay);
aState.mDisplay = null;
}
aState.mSession.close();
aState.setActive(false);
mFirstContentfulPaint = false;
}

public void captureBitmap() {
Expand Down Expand Up @@ -788,24 +805,6 @@ protected void setTrackingProtection(final boolean aEnabled) {
}
}

public void clearCache(final long clearFlags) {
if (mRuntime != null) {
// Per GeckoView Docs:
// Note: Any open session may re-accumulate previously cleared data.
// To ensure that no persistent data is left behind, you need to close all sessions prior to clearing data.
// https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/StorageController.html#clearData-long-
if (mState.mSession != null) {
mState.mSession.stop();
mState.mSession.close();
}

mRuntime.getStorageController().clearData(clearFlags).then(aVoid -> {
recreateSession();
return null;
});
}
}

public void updateLastUse() {
mState.mLastUse = System.currentTimeMillis();
}
Expand Down Expand Up @@ -1055,6 +1054,14 @@ public void onFirstComposite(@NonNull GeckoSession aSession) {
for (GeckoSession.ContentDelegate listener : mContentListeners) {
listener.onFirstComposite(aSession);
}
if (mFirstContentfulPaint) {
// onFirstContentfulPaint is only called once after a session is opened.
// Notify onFirstContentfulPaint after a session is reattached before
// being closed ((e.g. tab selected)
for (GeckoSession.ContentDelegate listener : mContentListeners) {
listener.onFirstContentfulPaint(aSession);
}
}
}
}

Expand Down
Expand Up @@ -41,6 +41,21 @@ public class SessionState {
public String mId = UUID.randomUUID().toString();
public String mParentId; // Parent session stack Id.

public SessionState recreate() {
SessionState result = new SessionState();
result.mUri = mUri;
result.mPreviousUri = mPreviousUri;
result.mTitle = mTitle;
result.mSettings = mSettings;
result.mSessionState = mSessionState;
result.mLastUse = mLastUse;
result.mRegion = mRegion;
result.mId = mId;
result.mParentId = mParentId;

return result;
}

public static class GeckoSessionStateAdapter extends TypeAdapter<GeckoSession.SessionState> {
@Override
public void write(JsonWriter out, GeckoSession.SessionState session) throws IOException {
Expand Down
Expand Up @@ -27,6 +27,7 @@

import java.security.KeyStore;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class SessionStore implements GeckoSession.PermissionDelegate {
Expand Down Expand Up @@ -351,9 +352,19 @@ public void setLocales(List<String> locales) {
}

public void clearCache(long clearFlags) {
LinkedList<Session> activeSession = new LinkedList<>();
for (Session session: mSessions) {
session.clearCache(clearFlags);
if (session.getGeckoSession() != null) {
session.suspend();
activeSession.add(session);
}
}
mRuntime.getStorageController().clearData(clearFlags).then(aVoid -> {
for (Session session: activeSession) {
session.recreateSession();
}
return null;
});
}

// Permission Delegate
Expand Down
Expand Up @@ -1109,13 +1109,13 @@ public void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSessi
} else {
setPrivateBrowsingEnabled(false);
}
waitForFirstPaint();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't seem to be executing the first draw callback in some situations like:

  • Open a new tab
  • Select the previous tab

}

@Override
public void onStackSession(Session aSession) {
// e.g. tab opened via window.open()
aSession.updateLastUse();
waitForFirstPaint();
Session current = mSession;
setSession(aSession);
SessionStore.get().setActiveSession(aSession);
Expand Down