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

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

Issue 2874643002: Merging Managed and Important connection. (Closed)
Patch Set: Fix test + sync 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 /**
15 * ManagedChildProcessConnection is a connection to a child service that can hol d several bindings
16 * to the service so it can be more or less agressively protected against OOM.
17 * Accessed from the launcher thread. (but for isOomProtectedOrWasWhenDied()).
18 */
19 public class ManagedChildProcessConnection extends BaseChildProcessConnection {
20 private static final String TAG = "ManChildProcessConn";
21
22 public static final Factory FACTORY = new BaseChildProcessConnection.Factory () {
23 @Override
24 public BaseChildProcessConnection create(Context context, DeathCallback deathCallback,
25 String serviceClassName, Bundle childProcessCommonParameters,
26 ChildProcessCreationParams creationParams) {
27 assert LauncherThread.runningOnLauncherThread();
28 return new ManagedChildProcessConnection(context, deathCallback, ser viceClassName,
29 childProcessCommonParameters, creationParams);
30 }
31 };
32
33 // Initial binding protects the newly spawned process from being killed befo re it is put to use,
34 // it is maintained between calls to start() and removeInitialBinding().
35 private final ChildServiceConnection mInitialBinding;
36
37 // Strong binding will make the service priority equal to the priority of th e activity. We want
38 // the OS to be able to kill background renderers as it kills other backgrou nd apps, so strong
39 // bindings are maintained only for services that are active at the moment ( between
40 // addStrongBinding() and removeStrongBinding()).
41 private final ChildServiceConnection mStrongBinding;
42
43 // Low priority binding maintained in the entire lifetime of the connection, i.e. between calls
44 // to start() and stop().
45 private final ChildServiceConnection mWaivedBinding;
46
47 // Incremented on addStrongBinding(), decremented on removeStrongBinding().
48 private int mStrongBindingCount;
49
50 // Moderate binding will make the service priority equal to the priority of a visible process
51 // while the app is in the foreground. It will stay bound only while the app is in the
52 // foreground to protect a background process from the system out-of-memory killer.
53 private final ChildServiceConnection mModerateBinding;
54
55 // Indicates whether the connection is OOM protected (if the connection is u nbound, it contains
56 // the state at time of unbinding).
57 private boolean mOomProtected;
58
59 // Set to true once unbind() was called.
60 private boolean mUnbound;
61
62 @VisibleForTesting
63 ManagedChildProcessConnection(Context context, DeathCallback deathCallback,
64 String serviceClassName, Bundle childProcessCommonParameters,
65 ChildProcessCreationParams creationParams) {
66 super(context, deathCallback, serviceClassName, childProcessCommonParame ters,
67 creationParams);
68
69 int initialFlags = Context.BIND_AUTO_CREATE;
70 int extraBindFlags = shouldBindAsExportedService() ? Context.BIND_EXTERN AL_SERVICE : 0;
71 mInitialBinding = createServiceConnection(initialFlags | extraBindFlags) ;
72 mStrongBinding = createServiceConnection(
73 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT | extraBindFla gs);
74 mWaivedBinding = createServiceConnection(
75 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY | extraBi ndFlags);
76 mModerateBinding = createServiceConnection(Context.BIND_AUTO_CREATE | ex traBindFlags);
77 }
78
79 @Override
80 protected boolean bind() {
81 assert LauncherThread.runningOnLauncherThread();
82 assert !mUnbound;
83 if (!mInitialBinding.bind()) {
84 return false;
85 }
86 updateOomProtectedState();
87 mWaivedBinding.bind();
88 return true;
89 }
90
91 @Override
92 public void unbind() {
93 assert LauncherThread.runningOnLauncherThread();
94 mUnbound = true;
95 mInitialBinding.unbind();
96 mStrongBinding.unbind();
97 // Note that we don't update the OOM state here as to preserve the last OOM state.
98 mWaivedBinding.unbind();
99 mModerateBinding.unbind();
100 mStrongBindingCount = 0;
101 }
102
103 public boolean isInitialBindingBound() {
104 assert LauncherThread.runningOnLauncherThread();
105 return mInitialBinding.isBound();
106 }
107
108 public boolean isStrongBindingBound() {
109 assert LauncherThread.runningOnLauncherThread();
110 return mStrongBinding.isBound();
111 }
112
113 public void addInitialBinding() {
114 assert LauncherThread.runningOnLauncherThread();
115 mInitialBinding.bind();
116 updateOomProtectedState();
117 }
118
119 public void removeInitialBinding() {
120 assert LauncherThread.runningOnLauncherThread();
121 mInitialBinding.unbind();
122 updateOomProtectedState();
123 }
124
125 /**
126 * @return true if the connection is bound and OOM protected or was OOM prot ected when unbound.
127 */
128 public boolean isOomProtectedOrWasWhenDied() {
129 // WARNING: this method can be called from a thread other than the launc her thread.
130 // Note that it returns the current OOM protected state and is racy. Thi s not really
131 // preventable without changing the caller's API, short of blocking.
132 return mOomProtected;
133 }
134
135 public void dropOomBindings() {
136 assert LauncherThread.runningOnLauncherThread();
137 mInitialBinding.unbind();
138
139 mStrongBindingCount = 0;
140 mStrongBinding.unbind();
141 updateOomProtectedState();
142
143 mModerateBinding.unbind();
144 }
145
146 public void addStrongBinding() {
147 assert LauncherThread.runningOnLauncherThread();
148 if (!isConnected()) {
149 Log.w(TAG, "The connection is not bound for %d", getPid());
150 return;
151 }
152 if (mStrongBindingCount == 0) {
153 mStrongBinding.bind();
154 updateOomProtectedState();
155 }
156 mStrongBindingCount++;
157 }
158
159 public void removeStrongBinding() {
160 assert LauncherThread.runningOnLauncherThread();
161 if (!isConnected()) {
162 Log.w(TAG, "The connection is not bound for %d", getPid());
163 return;
164 }
165 assert mStrongBindingCount > 0;
166 mStrongBindingCount--;
167 if (mStrongBindingCount == 0) {
168 mStrongBinding.unbind();
169 updateOomProtectedState();
170 }
171 updateOomProtectedState();
172 }
173
174 public boolean isModerateBindingBound() {
175 assert LauncherThread.runningOnLauncherThread();
176 return mModerateBinding.isBound();
177 }
178
179 public void addModerateBinding() {
180 assert LauncherThread.runningOnLauncherThread();
181 if (!isConnected()) {
182 Log.w(TAG, "The connection is not bound for %d", getPid());
183 return;
184 }
185 mModerateBinding.bind();
186 }
187
188 public void removeModerateBinding() {
189 assert LauncherThread.runningOnLauncherThread();
190 if (!isConnected()) {
191 Log.w(TAG, "The connection is not bound for %d", getPid());
192 return;
193 }
194 mModerateBinding.unbind();
195 }
196
197 // Should be called every time the mInitialBinding or mStrongBinding are bou nd/unbound.
198 private void updateOomProtectedState() {
199 if (!mUnbound) {
200 mOomProtected = mInitialBinding.isBound() || mStrongBinding.isBound( );
201 }
202 }
203 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698