| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
| 8 import android.content.ComponentCallbacks2; | 8 import android.content.ComponentCallbacks2; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.content.res.Configuration; | 10 import android.content.res.Configuration; |
| 11 import android.os.Build; | 11 import android.os.Build; |
| 12 import android.os.Handler; | 12 import android.os.Handler; |
| 13 import android.util.LruCache; | 13 import android.util.LruCache; |
| 14 import android.util.SparseArray; | 14 import android.util.SparseArray; |
| 15 | 15 |
| 16 import org.chromium.base.Log; | 16 import org.chromium.base.Log; |
| 17 import org.chromium.base.SysUtils; | 17 import org.chromium.base.SysUtils; |
| 18 import org.chromium.base.ThreadUtils; | 18 import org.chromium.base.ThreadUtils; |
| 19 import org.chromium.base.VisibleForTesting; | 19 import org.chromium.base.VisibleForTesting; |
| 20 import org.chromium.base.metrics.RecordHistogram; | 20 import org.chromium.base.metrics.RecordHistogram; |
| 21 | 21 |
| 22 import java.util.Map; | 22 import java.util.Map; |
| 23 import java.util.concurrent.atomic.AtomicReference; | 23 import java.util.concurrent.atomic.AtomicReference; |
| 24 | 24 |
| 25 import javax.annotation.concurrent.GuardedBy; |
| 26 |
| 25 /** | 27 /** |
| 26 * Manages oom bindings used to bound child services. | 28 * Manages oom bindings used to bound child services. |
| 27 */ | 29 */ |
| 28 class BindingManagerImpl implements BindingManager { | 30 class BindingManagerImpl implements BindingManager { |
| 29 private static final String TAG = "cr.BindingManager"; | 31 private static final String TAG = "cr.BindingManager"; |
| 30 | 32 |
| 31 // Low reduce ratio of moderate binding. | 33 // Low reduce ratio of moderate binding. |
| 32 private static final float MODERATE_BINDING_LOW_REDUCE_RATIO = 0.25f; | 34 private static final float MODERATE_BINDING_LOW_REDUCE_RATIO = 0.25f; |
| 33 // High reduce ratio of moderate binding. | 35 // High reduce ratio of moderate binding. |
| 34 private static final float MODERATE_BINDING_HIGH_REDUCE_RATIO = 0.5f; | 36 private static final float MODERATE_BINDING_HIGH_REDUCE_RATIO = 0.5f; |
| 35 | 37 |
| 36 // Delay of 1 second used when removing temporary strong binding of a proces
s (only on | 38 // Delay of 1 second used when removing temporary strong binding of a proces
s (only on |
| 37 // non-low-memory devices). | 39 // non-low-memory devices). |
| 38 private static final long DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS = 1 * 1000; | 40 private static final long DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS = 1 * 1000; |
| 39 | 41 |
| 40 // Delays used when clearing moderate binding pool when onSentToBackground h
appens. | 42 // Delays used when clearing moderate binding pool when onSentToBackground h
appens. |
| 41 private static final long MODERATE_BINDING_POOL_CLEARER_DELAY_MILLIS = 10 *
1000; | 43 private static final long MODERATE_BINDING_POOL_CLEARER_DELAY_MILLIS = 10 *
1000; |
| 42 | 44 |
| 43 // These fields allow to override the parameters for testing - see | 45 // These fields allow to override the parameters for testing - see |
| 44 // createBindingManagerForTesting(). | 46 // createBindingManagerForTesting(). |
| 45 private final boolean mIsLowMemoryDevice; | 47 private final boolean mIsLowMemoryDevice; |
| 46 | 48 |
| 47 private static class ModerateBindingPool | 49 private static class ModerateBindingPool |
| 48 extends LruCache<Integer, ManagedConnection> implements ComponentCal
lbacks2 { | 50 extends LruCache<Integer, ManagedConnection> implements ComponentCal
lbacks2 { |
| 49 private final Object mDelayedClearerLock = new Object(); | 51 private final Object mDelayedClearerLock = new Object(); |
| 52 |
| 53 @GuardedBy("mDelayedClearerLock") |
| 50 private Runnable mDelayedClearer; | 54 private Runnable mDelayedClearer; |
| 55 |
| 51 private final Handler mHandler = new Handler(ThreadUtils.getUiThreadLoop
er()); | 56 private final Handler mHandler = new Handler(ThreadUtils.getUiThreadLoop
er()); |
| 52 | 57 |
| 53 public ModerateBindingPool(int maxSize) { | 58 public ModerateBindingPool(int maxSize) { |
| 54 super(maxSize); | 59 super(maxSize); |
| 55 } | 60 } |
| 56 | 61 |
| 57 @Override | 62 @Override |
| 58 public void onTrimMemory(int level) { | 63 public void onTrimMemory(int level) { |
| 59 Log.i(TAG, "onTrimMemory: level=%d, size=%d", level, size()); | 64 Log.i(TAG, "onTrimMemory: level=%d, size=%d", level, size()); |
| 60 if (size() > 0) { | 65 if (size() > 0) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 int count = 0; | 100 int count = 0; |
| 96 for (Map.Entry<Integer, ManagedConnection> entry : snapshot().en
trySet()) { | 101 for (Map.Entry<Integer, ManagedConnection> entry : snapshot().en
trySet()) { |
| 97 remove(entry.getKey()); | 102 remove(entry.getKey()); |
| 98 ++count; | 103 ++count; |
| 99 if (count == oldSize - newSize) break; | 104 if (count == oldSize - newSize) break; |
| 100 } | 105 } |
| 101 } | 106 } |
| 102 } | 107 } |
| 103 | 108 |
| 104 void addConnection(ManagedConnection managedConnection) { | 109 void addConnection(ManagedConnection managedConnection) { |
| 105 ChildProcessConnection connection = managedConnection.mConnection; | 110 ManagedChildProcessConnection connection = managedConnection.mConnec
tion; |
| 106 if (connection != null && connection.isInSandbox()) { | 111 if (connection != null && connection.isSandboxed()) { |
| 107 managedConnection.addModerateBinding(); | 112 managedConnection.addModerateBinding(); |
| 108 if (connection.isModerateBindingBound()) { | 113 if (connection.isModerateBindingBound()) { |
| 109 put(connection.getServiceNumber(), managedConnection); | 114 put(connection.getServiceNumber(), managedConnection); |
| 110 } else { | 115 } else { |
| 111 remove(connection.getServiceNumber()); | 116 remove(connection.getServiceNumber()); |
| 112 } | 117 } |
| 113 } | 118 } |
| 114 } | 119 } |
| 115 | 120 |
| 116 void removeConnection(ManagedConnection managedConnection) { | 121 void removeConnection(ManagedConnection managedConnection) { |
| 117 ChildProcessConnection connection = managedConnection.mConnection; | 122 ManagedChildProcessConnection connection = managedConnection.mConnec
tion; |
| 118 if (connection != null && connection.isInSandbox()) { | 123 if (connection != null && connection.isSandboxed()) { |
| 119 remove(connection.getServiceNumber()); | 124 remove(connection.getServiceNumber()); |
| 120 } | 125 } |
| 121 } | 126 } |
| 122 | 127 |
| 123 @Override | 128 @Override |
| 124 protected void entryRemoved(boolean evicted, Integer key, ManagedConnect
ion oldValue, | 129 protected void entryRemoved(boolean evicted, Integer key, ManagedConnect
ion oldValue, |
| 125 ManagedConnection newValue) { | 130 ManagedConnection newValue) { |
| 126 if (oldValue != newValue) { | 131 if (oldValue != newValue) { |
| 127 oldValue.removeModerateBinding(); | 132 oldValue.removeModerateBinding(); |
| 128 } | 133 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 156 mHandler.removeCallbacks(mDelayedClearer); | 161 mHandler.removeCallbacks(mDelayedClearer); |
| 157 mDelayedClearer = null; | 162 mDelayedClearer = null; |
| 158 } | 163 } |
| 159 } | 164 } |
| 160 } | 165 } |
| 161 | 166 |
| 162 private final AtomicReference<ModerateBindingPool> mModerateBindingPool = | 167 private final AtomicReference<ModerateBindingPool> mModerateBindingPool = |
| 163 new AtomicReference<>(); | 168 new AtomicReference<>(); |
| 164 | 169 |
| 165 /** | 170 /** |
| 166 * Wraps ChildProcessConnection keeping track of additional information need
ed to manage the | 171 * Wraps ManagedChildProcessConnection keeping track of additional informati
on needed to manage |
| 167 * bindings of the connection. The reference to ChildProcessConnection is cl
eared when the | 172 * the bindings of the connection. The reference to ManagedChildProcessConne
ction is cleared |
| 168 * connection goes away, but ManagedConnection itself is kept (until overwri
tten by a new entry | 173 * when the connection goes away, but ManagedConnection itself is kept (unti
l overwritten by a |
| 169 * for the same pid). | 174 * new entry for the same pid). |
| 170 */ | 175 */ |
| 171 private class ManagedConnection { | 176 private class ManagedConnection { |
| 172 // Set in constructor, cleared in clearConnection() (on a separate threa
d). | 177 // Set in constructor, cleared in clearConnection() (on a separate threa
d). |
| 173 // Need to keep a local reference to avoid it being cleared while using
it. | 178 // Need to keep a local reference to avoid it being cleared while using
it. |
| 174 private ChildProcessConnection mConnection; | 179 private ManagedChildProcessConnection mConnection; |
| 175 | 180 |
| 176 // True iff there is a strong binding kept on the service because it is
working in | 181 // True iff there is a strong binding kept on the service because it is
working in |
| 177 // foreground. | 182 // foreground. |
| 178 private boolean mInForeground; | 183 private boolean mInForeground; |
| 179 | 184 |
| 180 // True iff there is a strong binding kept on the service because it was
bound for the | 185 // True iff there is a strong binding kept on the service because it was
bound for the |
| 181 // application background period. | 186 // application background period. |
| 182 private boolean mBoundForBackgroundPeriod; | 187 private boolean mBoundForBackgroundPeriod; |
| 183 | 188 |
| 184 // When mConnection is cleared, oom binding status is stashed here. | |
| 185 private boolean mWasOomProtected; | |
| 186 | |
| 187 /** | 189 /** |
| 188 * Removes the initial service binding. | 190 * Removes the initial service binding. |
| 189 * @return true if the binding was removed. | 191 * @return true if the binding was removed. |
| 190 */ | 192 */ |
| 191 private boolean removeInitialBinding() { | 193 private boolean removeInitialBinding() { |
| 192 ChildProcessConnection connection = mConnection; | 194 ManagedChildProcessConnection connection = mConnection; |
| 193 if (connection == null || !connection.isInitialBindingBound()) retur
n false; | 195 if (connection == null || !connection.isInitialBindingBound()) retur
n false; |
| 194 | 196 |
| 195 connection.removeInitialBinding(); | 197 connection.removeInitialBinding(); |
| 196 return true; | 198 return true; |
| 197 } | 199 } |
| 198 | 200 |
| 199 /** Adds a strong service binding. */ | 201 /** Adds a strong service binding. */ |
| 200 private void addStrongBinding() { | 202 private void addStrongBinding() { |
| 201 ChildProcessConnection connection = mConnection; | 203 ManagedChildProcessConnection connection = mConnection; |
| 202 if (connection == null) return; | 204 if (connection == null) return; |
| 203 | 205 |
| 204 connection.addStrongBinding(); | 206 connection.addStrongBinding(); |
| 205 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get()
; | 207 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get()
; |
| 206 if (moderateBindingPool != null) moderateBindingPool.removeConnectio
n(this); | 208 if (moderateBindingPool != null) moderateBindingPool.removeConnectio
n(this); |
| 207 } | 209 } |
| 208 | 210 |
| 209 /** Removes a strong service binding. */ | 211 /** Removes a strong service binding. */ |
| 210 private void removeStrongBinding(final boolean keepAsModerate) { | 212 private void removeStrongBinding(final boolean keepAsModerate) { |
| 211 final ChildProcessConnection connection = mConnection; | 213 final ManagedChildProcessConnection connection = mConnection; |
| 212 // We have to fail gracefully if the strong binding is not present,
as on low-end the | 214 // We have to fail gracefully if the strong binding is not present,
as on low-end the |
| 213 // binding could have been removed by dropOomBindings() when a new s
ervice was started. | 215 // binding could have been removed by dropOomBindings() when a new s
ervice was started. |
| 214 if (connection == null || !connection.isStrongBindingBound()) return
; | 216 if (connection == null || !connection.isStrongBindingBound()) return
; |
| 215 | 217 |
| 216 // This runnable performs the actual unbinding. It will be executed
synchronously when | 218 // This runnable performs the actual unbinding. It will be executed
synchronously when |
| 217 // on low-end devices and posted with a delay otherwise. | 219 // on low-end devices and posted with a delay otherwise. |
| 218 Runnable doUnbind = new Runnable() { | 220 Runnable doUnbind = new Runnable() { |
| 219 @Override | 221 @Override |
| 220 public void run() { | 222 public void run() { |
| 221 if (connection.isStrongBindingBound()) { | 223 if (connection.isStrongBindingBound()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 232 } else { | 234 } else { |
| 233 ThreadUtils.postOnUiThreadDelayed(doUnbind, DETACH_AS_ACTIVE_HIG
H_END_DELAY_MILLIS); | 235 ThreadUtils.postOnUiThreadDelayed(doUnbind, DETACH_AS_ACTIVE_HIG
H_END_DELAY_MILLIS); |
| 234 } | 236 } |
| 235 } | 237 } |
| 236 | 238 |
| 237 /** | 239 /** |
| 238 * Adds connection to the moderate binding pool. No-op if the connection
has a strong | 240 * Adds connection to the moderate binding pool. No-op if the connection
has a strong |
| 239 * binding. | 241 * binding. |
| 240 * @param connection The ChildProcessConnection to add to the moderate b
inding pool. | 242 * @param connection The ChildProcessConnection to add to the moderate b
inding pool. |
| 241 */ | 243 */ |
| 242 private void addConnectionToModerateBindingPool(ChildProcessConnection c
onnection) { | 244 private void addConnectionToModerateBindingPool(ManagedChildProcessConne
ction connection) { |
| 243 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get()
; | 245 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get()
; |
| 244 if (moderateBindingPool != null && !connection.isStrongBindingBound(
)) { | 246 if (moderateBindingPool != null && !connection.isStrongBindingBound(
)) { |
| 245 moderateBindingPool.addConnection(ManagedConnection.this); | 247 moderateBindingPool.addConnection(ManagedConnection.this); |
| 246 } | 248 } |
| 247 } | 249 } |
| 248 | 250 |
| 249 /** Removes the moderate service binding. */ | 251 /** Removes the moderate service binding. */ |
| 250 private void removeModerateBinding() { | 252 private void removeModerateBinding() { |
| 251 ChildProcessConnection connection = mConnection; | 253 ManagedChildProcessConnection connection = mConnection; |
| 252 if (connection == null || !connection.isModerateBindingBound()) retu
rn; | 254 if (connection == null || !connection.isModerateBindingBound()) retu
rn; |
| 253 | |
| 254 connection.removeModerateBinding(); | 255 connection.removeModerateBinding(); |
| 255 } | 256 } |
| 256 | 257 |
| 257 /** Adds the moderate service binding. */ | 258 /** Adds the moderate service binding. */ |
| 258 private void addModerateBinding() { | 259 private void addModerateBinding() { |
| 259 ChildProcessConnection connection = mConnection; | 260 ManagedChildProcessConnection connection = mConnection; |
| 260 if (connection == null) return; | 261 if (connection == null) return; |
| 261 | 262 |
| 262 connection.addModerateBinding(); | 263 connection.addModerateBinding(); |
| 263 } | 264 } |
| 264 | 265 |
| 265 /** | 266 /** |
| 266 * Drops the service bindings. This is used on low-end to drop bindings
of the current | 267 * Drops the service bindings. This is used on low-end to drop bindings
of the current |
| 267 * service when a new one is used in foreground. | 268 * service when a new one is used in foreground. |
| 268 */ | 269 */ |
| 269 private void dropBindings() { | 270 private void dropBindings() { |
| 270 assert mIsLowMemoryDevice; | 271 assert mIsLowMemoryDevice; |
| 271 ChildProcessConnection connection = mConnection; | 272 ManagedChildProcessConnection connection = mConnection; |
| 272 if (connection == null) return; | 273 if (connection == null) return; |
| 273 | 274 |
| 274 connection.dropOomBindings(); | 275 connection.dropOomBindings(); |
| 275 } | 276 } |
| 276 | 277 |
| 277 ManagedConnection(ChildProcessConnection connection) { | 278 ManagedConnection(ManagedChildProcessConnection connection) { |
| 278 mConnection = connection; | 279 mConnection = connection; |
| 279 } | 280 } |
| 280 | 281 |
| 281 /** | 282 /** |
| 282 * Sets the visibility of the service, adding or removing the strong bin
ding as needed. | 283 * Sets the visibility of the service, adding or removing the strong bin
ding as needed. |
| 283 */ | 284 */ |
| 284 void setInForeground(boolean nextInForeground) { | 285 void setInForeground(boolean nextInForeground) { |
| 285 if (!mInForeground && nextInForeground) { | 286 if (!mInForeground && nextInForeground) { |
| 286 addStrongBinding(); | 287 addStrongBinding(); |
| 287 } else if (mInForeground && !nextInForeground) { | 288 } else if (mInForeground && !nextInForeground) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 308 void setBoundForBackgroundPeriod(boolean nextBound) { | 309 void setBoundForBackgroundPeriod(boolean nextBound) { |
| 309 if (!mBoundForBackgroundPeriod && nextBound) { | 310 if (!mBoundForBackgroundPeriod && nextBound) { |
| 310 addStrongBinding(); | 311 addStrongBinding(); |
| 311 } else if (mBoundForBackgroundPeriod && !nextBound) { | 312 } else if (mBoundForBackgroundPeriod && !nextBound) { |
| 312 removeStrongBinding(false); | 313 removeStrongBinding(false); |
| 313 } | 314 } |
| 314 | 315 |
| 315 mBoundForBackgroundPeriod = nextBound; | 316 mBoundForBackgroundPeriod = nextBound; |
| 316 } | 317 } |
| 317 | 318 |
| 318 boolean isOomProtected() { | |
| 319 // When a process crashes, we can be queried about its oom status be
fore or after the | |
| 320 // connection is cleared. For the latter case, the oom status is sta
shed in | |
| 321 // mWasOomProtected. | |
| 322 ChildProcessConnection connection = mConnection; | |
| 323 return connection != null | |
| 324 ? connection.isOomProtectedOrWasWhenDied() : mWasOomProtecte
d; | |
| 325 } | |
| 326 | |
| 327 void clearConnection() { | 319 void clearConnection() { |
| 328 mWasOomProtected = mConnection.isOomProtectedOrWasWhenDied(); | |
| 329 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get()
; | 320 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get()
; |
| 330 if (moderateBindingPool != null) moderateBindingPool.removeConnectio
n(this); | 321 if (moderateBindingPool != null) moderateBindingPool.removeConnectio
n(this); |
| 331 mConnection = null; | 322 mConnection = null; |
| 332 } | 323 } |
| 333 | |
| 334 /** @return true iff the reference to the connection is no longer held *
/ | |
| 335 @VisibleForTesting | |
| 336 boolean isConnectionCleared() { | |
| 337 return mConnection == null; | |
| 338 } | |
| 339 } | 324 } |
| 340 | 325 |
| 341 // This can be manipulated on different threads, synchronize access on mMana
gedConnections. | 326 // This can be manipulated on different threads, synchronize access on mMana
gedConnections. |
| 342 private final SparseArray<ManagedConnection> mManagedConnections = | 327 private final SparseArray<ManagedConnection> mManagedConnections = |
| 343 new SparseArray<ManagedConnection>(); | 328 new SparseArray<ManagedConnection>(); |
| 344 | 329 |
| 345 // The connection that was most recently set as foreground (using setInForeg
round()). This is | 330 // The connection that was most recently set as foreground (using setInForeg
round()). This is |
| 346 // used to add additional binding on it when the embedder goes to background
. On low-end, this | 331 // used to add additional binding on it when the embedder goes to background
. On low-end, this |
| 347 // is also used to drop process bidnings when a new one is created, making s
ure that only one | 332 // is also used to drop process bidnings when a new one is created, making s
ure that only one |
| 348 // renderer process at a time is protected from oom killing. | 333 // renderer process at a time is protected from oom killing. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 374 /** | 359 /** |
| 375 * Creates a testing instance of BindingManager. Testing instance will have
the unbinding delays | 360 * Creates a testing instance of BindingManager. Testing instance will have
the unbinding delays |
| 376 * set to 0, so that the tests don't need to deal with actual waiting. | 361 * set to 0, so that the tests don't need to deal with actual waiting. |
| 377 * @param isLowEndDevice true iff the created instance should apply low-end
binding policies | 362 * @param isLowEndDevice true iff the created instance should apply low-end
binding policies |
| 378 */ | 363 */ |
| 379 public static BindingManagerImpl createBindingManagerForTesting(boolean isLo
wEndDevice) { | 364 public static BindingManagerImpl createBindingManagerForTesting(boolean isLo
wEndDevice) { |
| 380 return new BindingManagerImpl(isLowEndDevice, true); | 365 return new BindingManagerImpl(isLowEndDevice, true); |
| 381 } | 366 } |
| 382 | 367 |
| 383 @Override | 368 @Override |
| 384 public void addNewConnection(int pid, ChildProcessConnection connection) { | 369 public void addNewConnection(int pid, ManagedChildProcessConnection connecti
on) { |
| 385 // This will reset the previous entry for the pid in the unlikely event
of the OS | 370 // This will reset the previous entry for the pid in the unlikely event
of the OS |
| 386 // reusing renderer pids. | 371 // reusing renderer pids. |
| 387 synchronized (mManagedConnections) { | 372 synchronized (mManagedConnections) { |
| 388 mManagedConnections.put(pid, new ManagedConnection(connection)); | 373 mManagedConnections.put(pid, new ManagedConnection(connection)); |
| 389 } | 374 } |
| 390 } | 375 } |
| 391 | 376 |
| 392 @Override | 377 @Override |
| 393 public void setInForeground(int pid, boolean inForeground) { | 378 public void setInForeground(int pid, boolean inForeground) { |
| 394 ManagedConnection managedConnection; | 379 ManagedConnection managedConnection; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 public void onBroughtToForeground() { | 432 public void onBroughtToForeground() { |
| 448 if (mBoundForBackgroundPeriod != null) { | 433 if (mBoundForBackgroundPeriod != null) { |
| 449 mBoundForBackgroundPeriod.setBoundForBackgroundPeriod(false); | 434 mBoundForBackgroundPeriod.setBoundForBackgroundPeriod(false); |
| 450 mBoundForBackgroundPeriod = null; | 435 mBoundForBackgroundPeriod = null; |
| 451 } | 436 } |
| 452 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); | 437 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); |
| 453 if (moderateBindingPool != null) moderateBindingPool.onBroughtToForegrou
nd(); | 438 if (moderateBindingPool != null) moderateBindingPool.onBroughtToForegrou
nd(); |
| 454 } | 439 } |
| 455 | 440 |
| 456 @Override | 441 @Override |
| 457 public boolean isOomProtected(int pid) { | 442 public void removeConnection(int pid) { |
| 458 // In the unlikely event of the OS reusing renderer pid, the call will r
efer to the most | |
| 459 // recent renderer of the given pid. The binding state for a pid is bein
g reset in | |
| 460 // addNewConnection(). | |
| 461 ManagedConnection managedConnection; | 443 ManagedConnection managedConnection; |
| 462 synchronized (mManagedConnections) { | 444 synchronized (mManagedConnections) { |
| 463 managedConnection = mManagedConnections.get(pid); | 445 managedConnection = mManagedConnections.get(pid); |
| 446 if (managedConnection != null) { |
| 447 mManagedConnections.remove(pid); |
| 448 } |
| 464 } | 449 } |
| 465 return managedConnection != null ? managedConnection.isOomProtected() :
false; | 450 if (managedConnection != null) { |
| 466 } | 451 managedConnection.clearConnection(); |
| 467 | |
| 468 @Override | |
| 469 public void clearConnection(int pid) { | |
| 470 ManagedConnection managedConnection; | |
| 471 synchronized (mManagedConnections) { | |
| 472 managedConnection = mManagedConnections.get(pid); | |
| 473 } | 452 } |
| 474 if (managedConnection != null) managedConnection.clearConnection(); | |
| 475 } | 453 } |
| 476 | 454 |
| 477 /** @return true iff the connection reference is no longer held */ | 455 /** @return true iff the connection reference is no longer held */ |
| 478 @VisibleForTesting | 456 @VisibleForTesting |
| 479 public boolean isConnectionCleared(int pid) { | 457 public boolean isConnectionCleared(int pid) { |
| 480 synchronized (mManagedConnections) { | 458 synchronized (mManagedConnections) { |
| 481 return mManagedConnections.get(pid).isConnectionCleared(); | 459 return mManagedConnections.get(pid) == null; |
| 482 } | 460 } |
| 483 } | 461 } |
| 484 | 462 |
| 485 @Override | 463 @Override |
| 486 public void startModerateBindingManagement(Context context, int maxSize) { | 464 public void startModerateBindingManagement(Context context, int maxSize) { |
| 487 if (mIsLowMemoryDevice) return; | 465 if (mIsLowMemoryDevice) return; |
| 488 ModerateBindingPool pool = new ModerateBindingPool(maxSize); | 466 ModerateBindingPool pool = new ModerateBindingPool(maxSize); |
| 489 if (mModerateBindingPool.compareAndSet(null, pool)) { | 467 if (mModerateBindingPool.compareAndSet(null, pool)) { |
| 490 Log.i(TAG, "Moderate binding enabled: maxSize=%d", maxSize); | 468 Log.i(TAG, "Moderate binding enabled: maxSize=%d", maxSize); |
| 491 if (context != null) context.registerComponentCallbacks(pool); | 469 if (context != null) context.registerComponentCallbacks(pool); |
| 492 } | 470 } |
| 493 } | 471 } |
| 494 | 472 |
| 495 @Override | 473 @Override |
| 496 public void releaseAllModerateBindings() { | 474 public void releaseAllModerateBindings() { |
| 497 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); | 475 ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); |
| 498 if (moderateBindingPool != null) { | 476 if (moderateBindingPool != null) { |
| 499 Log.i(TAG, "Release all moderate bindings: %d", moderateBindingPool.
size()); | 477 Log.i(TAG, "Release all moderate bindings: %d", moderateBindingPool.
size()); |
| 500 moderateBindingPool.evictAll(); | 478 moderateBindingPool.evictAll(); |
| 501 } | 479 } |
| 502 } | 480 } |
| 503 } | 481 } |
| OLD | NEW |