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(); |
- } |
- } |
-} |