Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/ManagedChildProcessConnection.java

Issue 2828793002: Refactoring ChildProcessConnection. (Closed)
Patch Set: More test fixing. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser;
6
7 import android.content.Context;
8 import android.os.Bundle;
9
10 import org.chromium.base.Log;
11 import org.chromium.base.VisibleForTesting;
12 import org.chromium.base.process_launcher.ChildProcessCreationParams;
13
14 import javax.annotation.concurrent.GuardedBy;
15
16 /**
17 * ManagedChildProcessConnection is a connection to a child service that can hol d several bindings
18 * to the service so it can be more or less agressively protected against OOM.
19 */
20 public class ManagedChildProcessConnection extends BaseChildProcessConnection {
21 private static final String TAG = "ManChildProcessConn";
22
23 public static final Factory FACTORY = new BaseChildProcessConnection.Factory () {
24 @Override
25 public BaseChildProcessConnection create(Context context, int number, bo olean sandboxed,
26 DeathCallback deathCallback, String serviceClassName,
27 Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams) {
28 return new ManagedChildProcessConnection(context, number, sandboxed, deathCallback,
29 serviceClassName, childProcessCommonParameters, creationPara ms);
30 }
31 };
32
33 // Synchronization: While most internal flow occurs on the UI thread, the pu blic API
34 // (specifically start and stop) may be called from any thread, hence all en try point methods
35 // into the class are synchronized on the lock to protect access to these me mbers.
36 private final Object mBindingLock = new Object();
37
38 // Initial binding protects the newly spawned process from being killed befo re it is put to use,
39 // it is maintained between calls to start() and removeInitialBinding().
40 @GuardedBy("mBindingLock")
41 private final ChildServiceConnection mInitialBinding;
42
43 // Strong binding will make the service priority equal to the priority of th e activity. We want
44 // the OS to be able to kill background renderers as it kills other backgrou nd apps, so strong
45 // bindings are maintained only for services that are active at the moment ( between
46 // addStrongBinding() and removeStrongBinding()).
47 @GuardedBy("mBindingLock")
48 private final ChildServiceConnection mStrongBinding;
49
50 // Low priority binding maintained in the entire lifetime of the connection, i.e. between calls
51 // to start() and stop().
52 @GuardedBy("mBindingLock")
53 private final ChildServiceConnection mWaivedBinding;
54
55 // Incremented on addStrongBinding(), decremented on removeStrongBinding().
56 @GuardedBy("mBindingLock")
57 private int mStrongBindingCount;
58
59 // Moderate binding will make the service priority equal to the priority of a visible process
60 // while the app is in the foreground. It will stay bound only while the app is in the
61 // foreground to protect a background process from the system out-of-memory killer.
62 @GuardedBy("mBindingLock")
63 private final ChildServiceConnection mModerateBinding;
64
65 @GuardedBy("mBindingLock")
66 private boolean mWasOomProtectedOnUnbind;
67
68 @VisibleForTesting
69 ManagedChildProcessConnection(Context context, int number, boolean sandboxed ,
70 DeathCallback deathCallback, String serviceClassName,
71 Bundle childProcessCommonParameters, ChildProcessCreationParams crea tionParams) {
72 super(context, number, sandboxed, deathCallback, serviceClassName,
73 childProcessCommonParameters, creationParams);
74
75 int initialFlags = Context.BIND_AUTO_CREATE;
76 int extraBindFlags = shouldBindAsExportedService() ? Context.BIND_EXTERN AL_SERVICE : 0;
77
78 synchronized (mBindingLock) {
79 mInitialBinding = createServiceConnection(initialFlags | extraBindFl ags);
80 mStrongBinding = createServiceConnection(
81 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT | extraBin dFlags);
82 mWaivedBinding = createServiceConnection(
83 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY | ext raBindFlags);
84 mModerateBinding = createServiceConnection(Context.BIND_AUTO_CREATE | extraBindFlags);
85 }
86 }
87
88 @Override
89 protected boolean bind() {
90 synchronized (mBindingLock) {
91 if (!mInitialBinding.bind()) {
92 return false;
93 }
94 mWaivedBinding.bind();
95 }
96 return true;
97 }
98
99 @Override
100 public void unbind() {
101 synchronized (mBindingLock) {
102 if (!isBound()) {
103 return;
104 }
105 mWasOomProtectedOnUnbind = isCurrentlyOomProtected();
106 mInitialBinding.unbind();
107 mStrongBinding.unbind();
108 mWaivedBinding.unbind();
109 mModerateBinding.unbind();
110 mStrongBindingCount = 0;
111 }
112 }
113
114 @GuardedBy("mBindingLock")
115 private boolean isBound() {
116 return mInitialBinding.isBound() || mStrongBinding.isBound() || mWaivedB inding.isBound()
117 || mModerateBinding.isBound();
118 }
119
120 public boolean isInitialBindingBound() {
121 synchronized (mBindingLock) {
122 return mInitialBinding.isBound();
123 }
124 }
125
126 public boolean isStrongBindingBound() {
127 synchronized (mBindingLock) {
128 return mStrongBinding.isBound();
129 }
130 }
131
132 public void removeInitialBinding() {
133 synchronized (mBindingLock) {
134 mInitialBinding.unbind();
135 }
136 }
137
138 public boolean isOomProtectedOrWasWhenDied() {
139 // Call isConnected() outside of the synchronized block or we could dead lock.
140 final boolean isConnected = isConnected();
141 synchronized (mBindingLock) {
142 if (isConnected) {
143 return isCurrentlyOomProtected();
144 }
145 return mWasOomProtectedOnUnbind;
146 }
147 }
148
149 @GuardedBy("mBindingLock")
150 private boolean isCurrentlyOomProtected() {
151 return mInitialBinding.isBound() || mStrongBinding.isBound();
152 }
153
154 public void dropOomBindings() {
155 synchronized (mBindingLock) {
156 mInitialBinding.unbind();
157
158 mStrongBindingCount = 0;
159 mStrongBinding.unbind();
160
161 mModerateBinding.unbind();
162 }
163 }
164
165 public void addStrongBinding() {
166 // Call isConnected() outside of the synchronized block or we could dead lock.
167 final boolean isConnected = isConnected();
168 synchronized (mBindingLock) {
169 if (!isConnected) {
170 Log.w(TAG, "The connection is not bound for %d", getPid());
171 return;
172 }
173 if (mStrongBindingCount == 0) {
174 mStrongBinding.bind();
175 }
176 mStrongBindingCount++;
177 }
178 }
179
180 public void removeStrongBinding() {
181 // Call isConnected() outside of the synchronized block or we could dead lock.
182 final boolean isConnected = isConnected();
183 synchronized (mBindingLock) {
184 if (!isConnected) {
185 Log.w(TAG, "The connection is not bound for %d", getPid());
186 return;
187 }
188 assert mStrongBindingCount > 0;
189 mStrongBindingCount--;
190 if (mStrongBindingCount == 0) {
191 mStrongBinding.unbind();
192 }
193 }
194 }
195
196 public boolean isModerateBindingBound() {
197 synchronized (mBindingLock) {
198 return mModerateBinding.isBound();
199 }
200 }
201
202 public void addModerateBinding() {
203 // Call isConnected() outside of the synchronized block or we could dead lock.
204 final boolean isConnected = isConnected();
205 synchronized (mBindingLock) {
206 if (!isConnected) {
207 Log.w(TAG, "The connection is not bound for %d", getPid());
208 return;
209 }
210 mModerateBinding.bind();
211 }
212 }
213
214 public void removeModerateBinding() {
215 // Call isConnected() outside of the synchronized block or we could dead lock.
216 final boolean isConnected = isConnected();
217 synchronized (mBindingLock) {
218 if (!isConnected) {
219 Log.w(TAG, "The connection is not bound for %d", getPid());
220 return;
221 }
222 mModerateBinding.unbind();
223 }
224 }
225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698