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

Limit total number of GeckoSessions created to prevent OOM #2295

Merged
merged 1 commit into from
Nov 18, 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 @@ -99,6 +99,7 @@ protected Session(Context aContext, GeckoRuntime aRuntime,
mRuntime = aRuntime;
initialize();
mState = createSession(aSettings, aOpenMode);
mState.setActive(true);
}

protected Session(Context aContext, GeckoRuntime aRuntime, @NonNull SessionState aRestoreState) {
Expand Down Expand Up @@ -325,7 +326,7 @@ private void cleanSessionListeners(GeckoSession aSession) {
}

public void suspend() {
if (mState.mIsActive) {
if (mState.isActive()) {
Log.e(LOGTAG, "Active Sessions can not be suspended");
return;
}
Expand All @@ -345,29 +346,34 @@ private void restore() {
.build();
}

String restoreUri = mState.mUri;

mState.mSession = createGeckoSession(settings);
if (!mState.mSession.isOpen()) {
mState.mSession.open(mRuntime);
}

// data:text URLs can not be restored.
if (mState.mSessionState != null && ((mState.mUri == null) || mState.mUri.startsWith("data:text"))) {
mState.mSessionState = null;
mState.mUri = null;
}

if (mState.mSessionState != null) {
mState.mSession.restoreState(mState.mSessionState);
}

if ((mState.mSessionState == null) && (restoreUri != null)) {
mState.mSession.loadUri(restoreUri);
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.equals(mContext.getResources().getString(R.string.about_blank)) ||
} 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")) {
mState.mSession.loadUri(mState.mUri, GeckoSession.LOAD_FLAGS_REPLACE_HISTORY);
}

dumpAllState();
mState.setActive(true);
}


Expand Down Expand Up @@ -410,6 +416,7 @@ private void recreateSession() {
SessionState previous = mState;

mState = createSession(previous.mSettings, SESSION_OPEN);
mState.setActive(true);
if (previous.mSessionState != null) {
mState.mSession.restoreState(previous.mSessionState);
}
Expand All @@ -435,7 +442,7 @@ private void closeSession(@NonNull SessionState aState) {
aState.mDisplay = null;
}
aState.mSession.close();
aState.mIsActive = false;
aState.setActive(false);
}

public void captureBitmap() {
Expand Down Expand Up @@ -596,18 +603,19 @@ public void goForward() {

public void setActive(boolean aActive) {
// Flush the events queued while the session was inactive
if (mState.mSession != null && !mState.mIsActive && aActive) {
if (mState.mSession != null && !mState.isActive() && aActive) {
flushQueuedEvents();
}

if (mState.mSession != null) {
mState.mSession.setActive(aActive);
} else {
mState.setActive(aActive);
} else if (aActive) {
restore();
} else {
Log.e(LOGTAG, "ERROR: Setting null GeckoView to inactive!");
}

mState.mIsActive = aActive;

for (SessionChangeListener listener: mSessionChangeListeners) {
listener.onActiveStateChange(this, aActive);
}
Expand Down Expand Up @@ -661,6 +669,7 @@ public void toggleServo() {

mState = createSession(settings, SESSION_OPEN);
closeSession(previous);
mState.setActive(true);
loadUri(uri);
}

Expand Down Expand Up @@ -705,7 +714,7 @@ public int getUaMode() {
}

public boolean isActive() {
return mState.mIsActive;
return mState.isActive();
}

private static final String M_PREFIX = "m.";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package org.mozilla.vrbrowser.browser.engine;

import android.graphics.Bitmap;

import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.annotations.JsonAdapter;
Expand All @@ -25,7 +20,7 @@

@JsonAdapter(SessionState.SessionStateAdapterFactory.class)
public class SessionState {
public transient boolean mIsActive;
private transient boolean mIsActive;
public boolean mCanGoBack;
public boolean mCanGoForward;
public boolean mIsLoading;
Expand Down Expand Up @@ -64,6 +59,18 @@ public GeckoSession.SessionState read(JsonReader in) {
}
}

boolean isActive() {
return mIsActive;
}

void setActive(boolean active) {
if (active == mIsActive) {
return;
}
mIsActive = active;
SessionStore.get().sessionActiveStateChanged();
}

public class SessionStateAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package org.mozilla.vrbrowser.browser.engine;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.geckoview.ContentBlocking;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoRuntimeSettings;
Expand All @@ -20,11 +23,15 @@
import org.mozilla.vrbrowser.browser.Services;
import org.mozilla.vrbrowser.browser.SettingsStore;
import org.mozilla.vrbrowser.crashreporting.CrashReporterService;
import org.mozilla.vrbrowser.utils.SystemUtils;

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

public class SessionStore implements GeckoSession.PermissionDelegate {
private static final String LOGTAG = SystemUtils.createLogtag(SessionStore.class);
private static final int MAX_GECKO_SESSIONS = 5;

private static final String[] WEB_EXTENSIONS = new String[] {
"webcompat_vimeo",
Expand All @@ -48,6 +55,7 @@ public static SessionStore get() {
private BookmarksStore mBookmarksStore;
private HistoryStore mHistoryStore;
private Services mServices;
private boolean mSuspendPending;

private SessionStore() {
mSessions = new ArrayList<>();
Expand Down Expand Up @@ -113,6 +121,7 @@ private Session addSession(@NonNull Session aSession) {
aSession.setPermissionDelegate(this);
aSession.addNavigationListener(mServices);
mSessions.add(aSession);
sessionActiveStateChanged();
return aSession;
}

Expand Down Expand Up @@ -173,9 +182,46 @@ public void suspendAllInactiveSessions() {
}

public void setActiveSession(Session aSession) {
if (aSession != null) {
aSession.setActive(true);
}
mActiveSession = aSession;
}


private void limitInactiveSessions() {
Log.d(LOGTAG, "Limiting Inactive Sessions");
suspendAllInactiveSessions();
mSuspendPending = false;
}

void sessionActiveStateChanged() {
if (mSuspendPending) {
return;
}
int count = 0;
int activeCount = 0;
int inactiveCount = 0;
int suspendedCount = 0;
for(Session session: mSessions) {
if (session.getGeckoSession() != null) {
count++;
if (session.isActive()) {
activeCount++;
} else {
inactiveCount++;
}
} else {
suspendedCount++;
}
}
if (count > MAX_GECKO_SESSIONS) {
Log.d(LOGTAG, "Too many GeckoSessions. Active: " + activeCount + " Inactive: " + inactiveCount + " Suspended: " + suspendedCount);
mSuspendPending = true;
ThreadUtils.postToUiThread(this::limitInactiveSessions);
}
}

public Session getActiveSession() {
return mActiveSession;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,7 @@ public boolean isLayer() {
return mSurface != null && mTexture == null;
}


@Override
public void setVisible(boolean aVisible) {
if (mWidgetPlacement.visible == aVisible) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,9 @@ private void removeWindow(@NonNull WindowWidget aWindow) {
}

private void setWindowVisible(@NonNull WindowWidget aWindow, boolean aVisible) {
if (aVisible && (aWindow.getSession() != null) && (aWindow.getSession().getGeckoSession() == null)) {
setFirstPaint(aWindow, aWindow.getSession());
}
aWindow.setVisible(aVisible);
aWindow.getTopBar().setVisible(aVisible);
aWindow.getTitleBar().setVisible(aVisible);
Expand Down