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

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

Issue 2828793002: Refactoring ChildProcessConnection. (Closed)
Patch Set: Refactoring ChildProcessConnection. Created 3 years, 8 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.Build;
9 import android.os.Bundle;
10
11 import org.chromium.base.Log;
12 import org.chromium.base.VisibleForTesting;
13 import org.chromium.base.process_launcher.ChildProcessCreationParams;
14
15 import javax.annotation.concurrent.GuardedBy;
16
17 /**
18 * ManagedChildProcessConnection is a connection to a child service that can hol d several bindings
19 * to the service so it can be more or less agressively protected against OOM.
20 */
21 public class ManagedChildProcessConnection extends BaseChildProcessConnection {
22 private static final String TAG = "ManChildProcessConn";
23
24 public static final Factory FACTORY = new BaseChildProcessConnection.Factory () {
25 @Override
26 public BaseChildProcessConnection create(Context context, int number, bo olean sandboxed,
27 DeathCallback deathCallback, String serviceClassName,
28 Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams) {
29 ManagedChildProcessConnection connection =
30 new ManagedChildProcessConnection(context, number, sandboxed , deathCallback,
31 serviceClassName, childProcessCommonParameters, crea tionParams);
32 connection.initBindings();
33 return connection;
34 }
35 };
36
37 // Synchronization: While most internal flow occurs on the UI thread, the pu blic API
38 // (specifically start and stop) may be called from any thread, hence all en try point methods
39 // into the class are synchronized on the lock to protect access to these me mbers.
40 private final Object mBindingLock = new Object();
41
42 // Initial binding protects the newly spawned process from being killed befo re it is put to use,
43 // it is maintained between calls to start() and removeInitialBinding().
44 @GuardedBy("mBindingLock")
45 private ChildServiceConnection mInitialBinding;
46
47 // Strong binding will make the service priority equal to the priority of th e activity. We want
48 // the OS to be able to kill background renderers as it kills other backgrou nd apps, so strong
49 // bindings are maintained only for services that are active at the moment ( between
50 // addStrongBinding() and removeStrongBinding()).
51 @GuardedBy("mBindingLock")
52 private ChildServiceConnection mStrongBinding;
53
54 // Low priority binding maintained in the entire lifetime of the connection, i.e. between calls
55 // to start() and stop().
56 @GuardedBy("mBindingLock")
57 private ChildServiceConnection mWaivedBinding;
58
59 // Incremented on addStrongBinding(), decremented on removeStrongBinding().
60 @GuardedBy("mBindingLock")
61 private int mStrongBindingCount;
62
63 // Moderate binding will make the service priority equal to the priority of a visible process
64 // while the app is in the foreground. It will stay bound only while the app is in the
65 // foreground to protect a background process from the system out-of-memory killer.
66 @GuardedBy("mBindingLock")
67 private ChildServiceConnection mModerateBinding;
68
69 @GuardedBy("mBindingLock")
70 private boolean mWasOomProtectedOnUnbind;
71
72 @VisibleForTesting
73 ManagedChildProcessConnection(Context context, int number, boolean sandboxed ,
74 DeathCallback deathCallback, String serviceClassName,
75 Bundle childProcessCommonParameters, ChildProcessCreationParams crea tionParams) {
76 super(context, number, sandboxed, deathCallback, serviceClassName,
77 childProcessCommonParameters, creationParams);
78 }
79
80 @VisibleForTesting
81 protected void initBindings() {
boliu 2017/04/20 22:33:34 again, nothing is overriding this? can just be par
Jay Civelli 2017/04/25 06:02:46 Oh right, we can do this now. (I used that origina
82 int initialFlags = Context.BIND_AUTO_CREATE;
83 int extraBindFlags = 0;
84 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && getCreationParams( ) != null
boliu 2017/04/20 22:33:34 avoid duplicating this if condition, just expand i
Jay Civelli 2017/04/25 06:02:46 Done.
85 && getCreationParams().getIsExternalService()
86 && isExportedService(isSandboxed(), getContext(), getServiceName ())) {
87 extraBindFlags = Context.BIND_EXTERNAL_SERVICE;
88 }
89
90 synchronized (mBindingLock) {
91 mInitialBinding = createServiceConnection(initialFlags | extraBindFl ags);
92 mStrongBinding = createServiceConnection(
93 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT | extraBin dFlags);
94 mWaivedBinding = createServiceConnection(
95 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY | ext raBindFlags);
96 mModerateBinding = createServiceConnection(Context.BIND_AUTO_CREATE | extraBindFlags);
97 }
98 }
99
100 @Override
101 protected boolean bind() {
102 synchronized (mBindingLock) {
103 if (!mInitialBinding.bind()) {
104 return false;
105 }
106 mWaivedBinding.bind();
107 }
108 return true;
109 }
110
111 @Override
112 public void unbind() {
113 synchronized (mBindingLock) {
114 mWasOomProtectedOnUnbind = isCurrentlyOomProtected();
115 mInitialBinding.unbind();
116 mStrongBinding.unbind();
117 mWaivedBinding.unbind();
118 mModerateBinding.unbind();
119 mStrongBindingCount = 0;
120 }
121 }
122
123 public boolean isInitialBindingBound() {
124 synchronized (mBindingLock) {
125 return mInitialBinding.isBound();
126 }
127 }
128
129 public boolean isStrongBindingBound() {
130 synchronized (mBindingLock) {
131 return mStrongBinding.isBound();
132 }
133 }
134
135 public void removeInitialBinding() {
136 synchronized (mBindingLock) {
137 mInitialBinding.unbind();
138 }
139 }
140
141 public boolean isOomProtectedOrWasWhenDied() {
142 synchronized (mBindingLock) {
143 if (isConnected()) {
144 return isCurrentlyOomProtected();
145 }
146 return mWasOomProtectedOnUnbind;
147 }
148 }
149
150 private boolean isCurrentlyOomProtected() {
151 synchronized (mBindingLock) {
152 return mInitialBinding.isBound() || mStrongBinding.isBound();
153 }
154 }
155
156 public void dropOomBindings() {
157 synchronized (mBindingLock) {
158 mInitialBinding.unbind();
159
160 mStrongBindingCount = 0;
161 mStrongBinding.unbind();
162
163 mModerateBinding.unbind();
164 }
165 }
166
167 public void addStrongBinding() {
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 synchronized (mBindingLock) {
182 if (!isConnected()) {
183 Log.w(TAG, "The connection is not bound for %d", getPid());
184 return;
185 }
186 assert mStrongBindingCount > 0;
187 mStrongBindingCount--;
188 if (mStrongBindingCount == 0) {
189 mStrongBinding.unbind();
190 }
191 }
192 }
193
194 public boolean isModerateBindingBound() {
195 synchronized (mBindingLock) {
196 return mModerateBinding.isBound();
197 }
198 }
199
200 public void addModerateBinding() {
201 synchronized (mBindingLock) {
202 if (!isConnected()) {
203 Log.w(TAG, "The connection is not bound for %d", getPid());
204 return;
205 }
206 mModerateBinding.bind();
207 }
208 }
209
210 public void removeModerateBinding() {
211 synchronized (mBindingLock) {
212 if (!isConnected()) {
213 Log.w(TAG, "The connection is not bound for %d", getPid());
214 return;
215 }
216 mModerateBinding.unbind();
217 }
218 }
219 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698