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

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

Issue 2845243002: Moving BindingManager and ChildProcessConnection to base/.
Patch Set: Moving BindingManager and ChildProcessConnection to base/. 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, int number, bo olean sandboxed,
25 DeathCallback deathCallback, String serviceClassName,
26 Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams) {
27 assert LauncherThread.runningOnLauncherThread();
28 return new ManagedChildProcessConnection(context, number, sandboxed, deathCallback,
29 serviceClassName, childProcessCommonParameters, creationPara ms);
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, int number, boolean sandboxed ,
64 DeathCallback deathCallback, String serviceClassName,
65 Bundle childProcessCommonParameters, ChildProcessCreationParams crea tionParams) {
66 super(context, number, sandboxed, deathCallback, serviceClassName,
67 childProcessCommonParameters, 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 removeInitialBinding() {
114 assert LauncherThread.runningOnLauncherThread();
115 mInitialBinding.unbind();
116 updateOomProtectedState();
117 }
118
119 /**
120 * @return true if the connection is bound and OOM protected or was OOM prot ected when unbound.
121 */
122 public boolean isOomProtectedOrWasWhenDied() {
123 // WARNING: this method can be called from a thread other than the launc her thread.
124 // Note that it returns the current OOM protected state and is racy. Thi s not really
125 // preventable without changing the caller's API, short of blocking.
126 return mOomProtected;
127 }
128
129 public void dropOomBindings() {
130 assert LauncherThread.runningOnLauncherThread();
131 mInitialBinding.unbind();
132
133 mStrongBindingCount = 0;
134 mStrongBinding.unbind();
135 updateOomProtectedState();
136
137 mModerateBinding.unbind();
138 }
139
140 public void addStrongBinding() {
141 assert LauncherThread.runningOnLauncherThread();
142 if (!isConnected()) {
143 Log.w(TAG, "The connection is not bound for %d", getPid());
144 return;
145 }
146 if (mStrongBindingCount == 0) {
147 mStrongBinding.bind();
148 updateOomProtectedState();
149 }
150 mStrongBindingCount++;
151 }
152
153 public void removeStrongBinding() {
154 assert LauncherThread.runningOnLauncherThread();
155 if (!isConnected()) {
156 Log.w(TAG, "The connection is not bound for %d", getPid());
157 return;
158 }
159 assert mStrongBindingCount > 0;
160 mStrongBindingCount--;
161 if (mStrongBindingCount == 0) {
162 mStrongBinding.unbind();
163 updateOomProtectedState();
164 }
165 updateOomProtectedState();
166 }
167
168 public boolean isModerateBindingBound() {
169 assert LauncherThread.runningOnLauncherThread();
170 return mModerateBinding.isBound();
171 }
172
173 public void addModerateBinding() {
174 assert LauncherThread.runningOnLauncherThread();
175 if (!isConnected()) {
176 Log.w(TAG, "The connection is not bound for %d", getPid());
177 return;
178 }
179 mModerateBinding.bind();
180 }
181
182 public void removeModerateBinding() {
183 assert LauncherThread.runningOnLauncherThread();
184 if (!isConnected()) {
185 Log.w(TAG, "The connection is not bound for %d", getPid());
186 return;
187 }
188 mModerateBinding.unbind();
189 }
190
191 // Should be called every time the mInitialBinding or mStrongBinding are bou nd/unbound.
192 private void updateOomProtectedState() {
193 if (!mUnbound) {
194 mOomProtected = mInitialBinding.isBound() || mStrongBinding.isBound( );
195 }
196 }
197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698