Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Implement tab stacking #2084

Merged
merged 2 commits into from
Oct 28, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import org.mozilla.vrbrowser.browser.engine.Session;

public interface SessionChangeListener {
default void onNewSession(GeckoSession aSession) {};
default void onRemoveSession(GeckoSession aSession) {};
default void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSession) {};
default void onNewTab(Session aTab) {};
default void onRemoveSession(Session aSession) {}
default void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSession) {}
default void onStackSession(Session aSession) {}
default void onUnstackSession(Session aSession, Session aParent) {}
default void onActiveStateChange(Session aSession, boolean aActive) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
Expand Down Expand Up @@ -54,7 +55,7 @@
public class Session implements ContentBlocking.Delegate, GeckoSession.NavigationDelegate,
GeckoSession.ProgressDelegate, GeckoSession.ContentDelegate, GeckoSession.TextInputDelegate,
GeckoSession.PromptDelegate, GeckoSession.MediaDelegate, GeckoSession.HistoryDelegate, GeckoSession.PermissionDelegate,
GeckoSession.SelectionActionDelegate, SharedPreferences.OnSharedPreferenceChangeListener {
GeckoSession.SelectionActionDelegate, SharedPreferences.OnSharedPreferenceChangeListener, SessionChangeListener {

private static final String LOGTAG = SystemUtils.createLogtag(Session.class);

Expand All @@ -77,25 +78,31 @@ public class Session implements ContentBlocking.Delegate, GeckoSession.Navigatio
private transient GeckoRuntime mRuntime;
private boolean mUsePrivateMode;
private transient byte[] mPrivatePage;
private boolean mIsActive;

public interface BitmapChangedListener {
void onBitmapChanged(Session aSession, Bitmap aBitmap);
}

@IntDef(value = { SESSION_OPEN, SESSION_DO_NOT_OPEN})
public @interface SessionOpenModeFlags {}
public static final int SESSION_OPEN = 0;
public static final int SESSION_DO_NOT_OPEN = 1;

protected Session(Context aContext, GeckoRuntime aRuntime, boolean aUsePrivateMode) {
this(aContext, aRuntime, aUsePrivateMode, null, true);
this(aContext, aRuntime, aUsePrivateMode, null, SESSION_OPEN);
}

protected Session(Context aContext, GeckoRuntime aRuntime, boolean aUsePrivateMode,
@Nullable SessionSettings aSettings, boolean aOpen) {
@Nullable SessionSettings aSettings, @SessionOpenModeFlags int aOpenMode) {
mContext = aContext;
mRuntime = aRuntime;
mUsePrivateMode = aUsePrivateMode;
initialize();
if (aSettings != null) {
mState = createSession(aSettings, aOpen);
mState = createSession(aSettings, aOpenMode);
} else {
mState = createSession(aOpen);
mState = createSession(aOpenMode);
}

setupSessionListeners(mState.mSession);
Expand Down Expand Up @@ -144,6 +151,16 @@ protected void shutdown() {
mState.mSession = null;
}

for (SessionChangeListener listener : mSessionChangeListeners) {
listener.onRemoveSession(this);
}
if (mState.mParentId != null) {
Session parent = SessionStore.get().getSession(mState.mParentId);
if (parent != null) {
parent.mSessionChangeListeners.remove(this);
}
}

mNavigationListeners.clear();
mProgressListeners.clear();
mContentListeners.clear();
Expand Down Expand Up @@ -316,10 +333,6 @@ private void restore() {
mState.mSession.restoreState(mState.mSessionState);
}

for (SessionChangeListener listener: mSessionChangeListeners) {
listener.onNewSession(mState.mSession);
}

if (mUsePrivateMode) {
loadPrivateBrowsingPage();
} else if(mState.mSessionState == null || mState.mUri.equals(mContext.getResources().getString(R.string.about_blank)) ||
Expand All @@ -330,27 +343,23 @@ private void restore() {
dumpAllState();
}

private SessionState createSession(boolean aOpen) {
private SessionState createSession(@SessionOpenModeFlags int aOpenMode) {
SessionSettings settings = new SessionSettings.Builder()
.withDefaultSettings(mContext)
.build();

return createSession(settings, aOpen);
return createSession(settings, aOpenMode);
}

private SessionState createSession(@NonNull SessionSettings aSettings, boolean aOpen) {
private SessionState createSession(@NonNull SessionSettings aSettings, @SessionOpenModeFlags int aOpenMode) {
SessionState state = new SessionState();
state.mSettings = aSettings;
state.mSession = createGeckoSession(aSettings);

if (aOpen && !state.mSession.isOpen()) {
if (aOpenMode == SESSION_OPEN && !state.mSession.isOpen()) {
state.mSession.open(mRuntime);
}

for (SessionChangeListener listener: mSessionChangeListeners) {
listener.onNewSession(state.mSession);
}

return state;
}

Expand Down Expand Up @@ -378,7 +387,7 @@ private GeckoSession createGeckoSession(@NonNull SessionSettings aSettings) {
private void recreateSession() {
SessionState previous = mState;

mState = createSession(previous.mSettings, true);
mState = createSession(previous.mSettings, SESSION_OPEN);
if (previous.mSessionState != null)
mState.mSession.restoreState(previous.mSessionState);
if (previous.mSession != null) {
Expand All @@ -392,12 +401,10 @@ private void recreateSession() {

private void closeSession(@NonNull GeckoSession aSession) {
cleanSessionListeners(aSession);
for (SessionChangeListener listener : mSessionChangeListeners) {
listener.onRemoveSession(aSession);
}
aSession.setActive(false);
aSession.stop();
aSession.close();
mIsActive = false;
}

public void captureBitmap(@NonNull GeckoDisplay aDisplay) {
Expand Down Expand Up @@ -474,14 +481,28 @@ public boolean isInputActive() {
}

public boolean canGoBack() {
return mState.mCanGoBack || isInFullScreen();
if (mState.mCanGoBack || isInFullScreen()) {
return true;
}
if (mState.mParentId != null) {
Session parent = SessionStore.get().getSession(mState.mParentId);
return parent != null && !parent.isActive();
}
return false;
}

public void goBack() {
if (isInFullScreen()) {
exitFullScreen();
} else if (mState.mCanGoBack && mState.mSession != null) {
mState.mSession.goBack();
} else if (mState.mParentId != null) {
Session parent = SessionStore.get().getSession(mState.mParentId);
if (parent != null && !parent.isActive()) {
for (SessionChangeListener listener: mSessionChangeListeners) {
listener.onUnstackSession(this, parent);
}
}
}
}

Expand All @@ -495,6 +516,11 @@ public void setActive(boolean aActive) {
if (mState.mSession != null) {
mState.mSession.setActive(aActive);
}
mIsActive = aActive;

for (SessionChangeListener listener: mSessionChangeListeners) {
listener.onActiveStateChange(this, aActive);
}
}

public void reload() {
Expand Down Expand Up @@ -543,7 +569,7 @@ public void toggleServo() {
.withServo(!isInstanceOfServoSession(mState.mSession))
.build();

mState = createSession(settings, true);
mState = createSession(settings, SESSION_OPEN);
closeSession(previous.mSession);
loadUri(uri);
}
Expand Down Expand Up @@ -586,6 +612,10 @@ public int getUaMode() {
return mState.mSession.getSettings().getUserAgentMode();
}

public boolean isActive() {
return mIsActive;
}

private static final String M_PREFIX = "m.";
private static final String MOBILE_PREFIX = "mobile.";

Expand Down Expand Up @@ -789,12 +819,14 @@ public void onCanGoForward(@NonNull GeckoSession aSession, boolean aCanGoForward

@Override
public GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession aSession, @NonNull String aUri) {
Log.d(LOGTAG, "Session onNewSession: " + aUri);
Log.d(LOGTAG, "Session onStackSession: " + aUri);

Session session = SessionStore.get().createSession(mUsePrivateMode, mState.mSettings, false);
for (SessionChangeListener listener: mSessionChangeListeners) {
listener.onNewTab(session);
Session session = SessionStore.get().createSession(mUsePrivateMode, mState.mSettings, SESSION_DO_NOT_OPEN);
session.mState.mParentId = mState.mId;
for (SessionChangeListener listener: new LinkedList<>(mSessionChangeListeners)) {
listener.onStackSession(session);
}
mSessionChangeListeners.add(session);
return GeckoResult.fromValue(session.getGeckoSession());
}

Expand Down Expand Up @@ -1205,4 +1237,27 @@ public void onHideAction(@NonNull GeckoSession aSession, int aHideReason) {
}
}
}

// SessionChangeListener

@Override
public void onRemoveSession(Session aParent) {
if (mState.mParentId != null) {
mState.mParentId = null;
// Parent stack session closed. Notify canGoBack state changed
for (GeckoSession.NavigationDelegate listener : mNavigationListeners) {
listener.onCanGoBack(this.getGeckoSession(), canGoBack());
}
}
}

@Override
public void onActiveStateChange(Session aSession, boolean aActive) {
if (mState.mParentId != null) {
// Parent stack session has been attached/detached. Notify canGoBack state changed
for (GeckoSession.NavigationDelegate listener : mNavigationListeners) {
listener.onCanGoBack(this.getGeckoSession(), canGoBack());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class SessionState {
public long mLastUse;
public String mRegion;
public String mId = UUID.randomUUID().toString();
public String mParentId; // Parent session stack Id.

public static class GeckoSessionStateAdapter extends TypeAdapter<GeckoSession.SessionState> {
@Override
Expand Down Expand Up @@ -83,6 +84,7 @@ public void write(JsonWriter out, T value) throws IOException {
out.name("mLastUse").value(session.mLastUse);
out.name("mRegion").value(session.mRegion);
out.name("mId").value(session.mId);
out.name("mParentId").value(session.mParentId);
if (session.mSession != null) {
if (session.mSession.getSettings().getUsePrivateMode()) {
out.name("mSessionState").jsonValue(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class SessionStore implements GeckoSession.PermissionDelegate {

Expand Down Expand Up @@ -109,11 +111,11 @@ public void initializeStores(Context context) {
}

public Session createSession(boolean aPrivateMode) {
return createSession(aPrivateMode, null, true);
return createSession(aPrivateMode, null, Session.SESSION_OPEN);
}

public Session createSession(boolean aPrivateMode, @Nullable SessionSettings aSettings, boolean aOpen) {
Session session = new Session(mContext, mRuntime, aPrivateMode, aSettings, aOpen);
public Session createSession(boolean aPrivateMode, @Nullable SessionSettings aSettings, @Session.SessionOpenModeFlags int aOpenMode) {
Session session = new Session(mContext, mRuntime, aPrivateMode, aSettings, aOpenMode);
session.setPermissionDelegate(this);
session.addNavigationListener(mServices);
mSessions.add(session);
Expand All @@ -139,6 +141,10 @@ public void destroySession(Session aSession) {
}
}

public @Nullable Session getSession(String aId) {
return mSessions.stream().filter(session -> session.getId().equals(aId)).findFirst().orElse(null);
}

public void setActiveSession(Session aSession) {
mActiveSession = aSession;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1041,10 +1041,23 @@ public void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSessi
}

@Override
public void onNewTab(Session aTab) {
public void onStackSession(Session aSession) {
// e.g. tab opened via window.open()
setSession(aTab);
SessionStore.get().setActiveSession(aTab);
Session current = mSession;
setSession(aSession);
SessionStore.get().setActiveSession(aSession);
current.setActive(false);
mWidgetManager.getTray().showTabAddedNotification();
}

@Override
public void onUnstackSession(Session aSession, Session aParent) {
if (mSession == aSession) {
setSession(aParent);
aParent.setActive(true);
SessionStore.get().setActiveSession(aParent);
SessionStore.get().destroySession(aSession);
}
}

// View
Expand Down