| Index: content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
|
| deleted file mode 100644
|
| index 40dc2cba76cb5c68d11c9e08b63495ffce8c2b0d..0000000000000000000000000000000000000000
|
| --- a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
|
| +++ /dev/null
|
| @@ -1,291 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -package org.chromium.content.browser;
|
| -
|
| -import android.util.Log;
|
| -import android.util.SparseArray;
|
| -
|
| -import com.google.common.annotations.VisibleForTesting;
|
| -
|
| -import org.chromium.base.SysUtils;
|
| -import org.chromium.base.ThreadUtils;
|
| -
|
| -/**
|
| - * Manages oom bindings used to bound child services.
|
| - */
|
| -class BindingManagerImpl implements BindingManager {
|
| - private static final String TAG = "BindingManager";
|
| -
|
| - // Delay of 1 second used when removing the initial oom binding of a process.
|
| - private static final long REMOVE_INITIAL_BINDING_DELAY_MILLIS = 1 * 1000;
|
| -
|
| - // Delay of 1 second used when removing temporary strong binding of a process (only on
|
| - // non-low-memory devices).
|
| - private static final long DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS = 1 * 1000;
|
| -
|
| - // These fields allow to override the parameters for testing - see
|
| - // createBindingManagerForTesting().
|
| - private final long mRemoveInitialBindingDelay;
|
| - private final long mRemoveStrongBindingDelay;
|
| - private final boolean mIsLowMemoryDevice;
|
| -
|
| - /**
|
| - * Wraps ChildProcessConnection keeping track of additional information needed to manage the
|
| - * bindings of the connection. The reference to ChildProcessConnection is cleared when the
|
| - * connection goes away, but ManagedConnection itself is kept (until overwritten by a new entry
|
| - * for the same pid).
|
| - */
|
| - private class ManagedConnection {
|
| - // Set in constructor, cleared in clearConnection().
|
| - private ChildProcessConnection mConnection;
|
| -
|
| - // True iff there is a strong binding kept on the service because it is working in
|
| - // foreground.
|
| - private boolean mInForeground;
|
| -
|
| - // True iff there is a strong binding kept on the service because it was bound for the
|
| - // application background period.
|
| - private boolean mBoundForBackgroundPeriod;
|
| -
|
| - // When mConnection is cleared, oom binding status is stashed here.
|
| - private boolean mWasOomProtected;
|
| -
|
| - /** Removes the initial service binding. */
|
| - private void removeInitialBinding() {
|
| - final ChildProcessConnection connection = mConnection;
|
| - if (connection == null || !connection.isInitialBindingBound()) return;
|
| -
|
| - ThreadUtils.postOnUiThreadDelayed(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - if (connection.isInitialBindingBound()) {
|
| - connection.removeInitialBinding();
|
| - }
|
| - }
|
| - }, mRemoveInitialBindingDelay);
|
| - }
|
| -
|
| - /** Adds a strong service binding. */
|
| - private void addStrongBinding() {
|
| - ChildProcessConnection connection = mConnection;
|
| - if (connection == null) return;
|
| -
|
| - connection.addStrongBinding();
|
| - }
|
| -
|
| - /** Removes a strong service binding. */
|
| - private void removeStrongBinding() {
|
| - final ChildProcessConnection connection = mConnection;
|
| - // We have to fail gracefully if the strong binding is not present, as on low-end the
|
| - // binding could have been removed by dropOomBindings() when a new service was started.
|
| - if (connection == null || !connection.isStrongBindingBound()) return;
|
| -
|
| - // This runnable performs the actual unbinding. It will be executed synchronously when
|
| - // on low-end devices and posted with a delay otherwise.
|
| - Runnable doUnbind = new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - if (connection.isStrongBindingBound()) {
|
| - connection.removeStrongBinding();
|
| - }
|
| - }
|
| - };
|
| -
|
| - if (mIsLowMemoryDevice) {
|
| - doUnbind.run();
|
| - } else {
|
| - ThreadUtils.postOnUiThreadDelayed(doUnbind, mRemoveStrongBindingDelay);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Drops the service bindings. This is used on low-end to drop bindings of the current
|
| - * service when a new one is created.
|
| - */
|
| - private void dropBindings() {
|
| - assert mIsLowMemoryDevice;
|
| - ChildProcessConnection connection = mConnection;
|
| - if (connection == null) return;
|
| -
|
| - connection.dropOomBindings();
|
| - }
|
| -
|
| - ManagedConnection(ChildProcessConnection connection) {
|
| - mConnection = connection;
|
| - }
|
| -
|
| - /**
|
| - * Sets the visibility of the service, adding or removing the strong binding as needed. This
|
| - * also removes the initial binding, as the service visibility is now known.
|
| - */
|
| - void setInForeground(boolean nextInForeground) {
|
| - if (!mInForeground && nextInForeground) {
|
| - addStrongBinding();
|
| - } else if (mInForeground && !nextInForeground) {
|
| - removeStrongBinding();
|
| - }
|
| -
|
| - removeInitialBinding();
|
| - mInForeground = nextInForeground;
|
| - }
|
| -
|
| - /**
|
| - * Sets or removes additional binding when the service is main service during the embedder
|
| - * background period.
|
| - */
|
| - void setBoundForBackgroundPeriod(boolean nextBound) {
|
| - if (!mBoundForBackgroundPeriod && nextBound) {
|
| - addStrongBinding();
|
| - } else if (mBoundForBackgroundPeriod && !nextBound) {
|
| - removeStrongBinding();
|
| - }
|
| -
|
| - mBoundForBackgroundPeriod = nextBound;
|
| - }
|
| -
|
| - boolean isOomProtected() {
|
| - // When a process crashes, we can be queried about its oom status before or after the
|
| - // connection is cleared. For the latter case, the oom status is stashed in
|
| - // mWasOomProtected.
|
| - return mConnection != null ?
|
| - mConnection.isOomProtectedOrWasWhenDied() : mWasOomProtected;
|
| - }
|
| -
|
| - void clearConnection() {
|
| - mWasOomProtected = mConnection.isOomProtectedOrWasWhenDied();
|
| - mConnection = null;
|
| - }
|
| -
|
| - /** @return true iff the reference to the connection is no longer held */
|
| - @VisibleForTesting
|
| - boolean isConnectionCleared() {
|
| - return mConnection == null;
|
| - }
|
| - }
|
| -
|
| - // This can be manipulated on different threads, synchronize access on mManagedConnections.
|
| - private final SparseArray<ManagedConnection> mManagedConnections =
|
| - new SparseArray<ManagedConnection>();
|
| -
|
| - // The connection that was most recently set as foreground (using setInForeground()). This is
|
| - // used to add additional binding on it when the embedder goes to background. On low-end, this
|
| - // is also used to drop process bidnings when a new one is created, making sure that only one
|
| - // renderer process at a time is protected from oom killing.
|
| - private ManagedConnection mLastInForeground;
|
| -
|
| - // Synchronizes operations that access mLastInForeground: setInForeground() and
|
| - // addNewConnection().
|
| - private final Object mLastInForegroundLock = new Object();
|
| -
|
| - // The connection bound with additional binding in onSentToBackground().
|
| - private ManagedConnection mBoundForBackgroundPeriod;
|
| -
|
| - /**
|
| - * The constructor is private to hide parameters exposed for testing from the regular consumer.
|
| - * Use factory methods to create an instance.
|
| - */
|
| - private BindingManagerImpl(boolean isLowMemoryDevice, long removeInitialBindingDelay,
|
| - long removeStrongBindingDelay) {
|
| - mIsLowMemoryDevice = isLowMemoryDevice;
|
| - mRemoveInitialBindingDelay = removeInitialBindingDelay;
|
| - mRemoveStrongBindingDelay = removeStrongBindingDelay;
|
| - }
|
| -
|
| - public static BindingManagerImpl createBindingManager() {
|
| - return new BindingManagerImpl(SysUtils.isLowEndDevice(),
|
| - REMOVE_INITIAL_BINDING_DELAY_MILLIS, DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS);
|
| - }
|
| -
|
| - /**
|
| - * Creates a testing instance of BindingManager. Testing instance will have the unbinding delays
|
| - * set to 0, so that the tests don't need to deal with actual waiting.
|
| - * @param isLowEndDevice true iff the created instance should apply low-end binding policies
|
| - */
|
| - public static BindingManagerImpl createBindingManagerForTesting(boolean isLowEndDevice) {
|
| - return new BindingManagerImpl(isLowEndDevice, 0, 0);
|
| - }
|
| -
|
| - @Override
|
| - public void addNewConnection(int pid, ChildProcessConnection connection) {
|
| - synchronized (mLastInForegroundLock) {
|
| - if (mIsLowMemoryDevice && mLastInForeground != null) mLastInForeground.dropBindings();
|
| - }
|
| -
|
| - // This will reset the previous entry for the pid in the unlikely event of the OS
|
| - // reusing renderer pids.
|
| - synchronized (mManagedConnections) {
|
| - mManagedConnections.put(pid, new ManagedConnection(connection));
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void setInForeground(int pid, boolean inForeground) {
|
| - ManagedConnection managedConnection;
|
| - synchronized (mManagedConnections) {
|
| - managedConnection = mManagedConnections.get(pid);
|
| - }
|
| -
|
| - if (managedConnection == null) {
|
| - Log.w(TAG, "Cannot setInForeground() - never saw a connection for the pid: " +
|
| - Integer.toString(pid));
|
| - return;
|
| - }
|
| -
|
| - synchronized (mLastInForegroundLock) {
|
| - managedConnection.setInForeground(inForeground);
|
| - if (inForeground) mLastInForeground = managedConnection;
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onSentToBackground() {
|
| - assert mBoundForBackgroundPeriod == null;
|
| - synchronized (mLastInForegroundLock) {
|
| - // mLastInForeground can be null at this point as the embedding application could be
|
| - // used in foreground without spawning any renderers.
|
| - if (mLastInForeground != null) {
|
| - mLastInForeground.setBoundForBackgroundPeriod(true);
|
| - mBoundForBackgroundPeriod = mLastInForeground;
|
| - }
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onBroughtToForeground() {
|
| - if (mBoundForBackgroundPeriod != null) {
|
| - mBoundForBackgroundPeriod.setBoundForBackgroundPeriod(false);
|
| - mBoundForBackgroundPeriod = null;
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public boolean isOomProtected(int pid) {
|
| - // In the unlikely event of the OS reusing renderer pid, the call will refer to the most
|
| - // recent renderer of the given pid. The binding state for a pid is being reset in
|
| - // addNewConnection().
|
| - ManagedConnection managedConnection;
|
| - synchronized (mManagedConnections) {
|
| - managedConnection = mManagedConnections.get(pid);
|
| - }
|
| - return managedConnection != null ? managedConnection.isOomProtected() : false;
|
| - }
|
| -
|
| - @Override
|
| - public void clearConnection(int pid) {
|
| - ManagedConnection managedConnection;
|
| - synchronized (mManagedConnections) {
|
| - managedConnection = mManagedConnections.get(pid);
|
| - }
|
| - if (managedConnection != null) managedConnection.clearConnection();
|
| - }
|
| -
|
| - /** @return true iff the connection reference is no longer held */
|
| - @VisibleForTesting
|
| - public boolean isConnectionCleared(int pid) {
|
| - synchronized (mManagedConnections) {
|
| - return mManagedConnections.get(pid).isConnectionCleared();
|
| - }
|
| - }
|
| -}
|
|
|