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

Side by Side Diff: content/public/android/java/org/chromium/content/app/SandboxedProcessService.java

Issue 10546079: Added sandboxed process service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed the comments and add 'jni+' into common/DEPS. Created 8 years, 6 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.app;
6
7 import android.app.Service;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.graphics.SurfaceTexture;
11 import android.os.Bundle;
12 import android.os.IBinder;
13 import android.os.ParcelFileDescriptor;
14 import android.os.Process;
15 import android.os.RemoteException;
16 import android.util.Log;
17 import android.view.Surface;
18
19 import org.chromium.base.CalledByNative;
20 import org.chromium.content.app.ContentMain;
21 import org.chromium.content.browser.SandboxedProcessConnection;
22 import org.chromium.content.common.ISandboxedProcessCallback;
23 import org.chromium.content.common.ISandboxedProcessService;
24 import org.chromium.content.common.SurfaceCallback;
25
26 /**
27 * This is the base class for sandboxed services; the SandboxedProcessService0, 1.. etc
28 * subclasses provide the concrete service entry points, to enable the browser t o connect
29 * to more than one distinct process (i.e. one process per service number, up to limit of N).
30 * The embedding application must declare these service instances in the applica tion section
31 * of its AndroidManifest.xml, for example with N entries of the form:-
32 * <service android:name="org.chromium.content.browser.SandboxedProcessServi ceX"
33 * android:process=":sandboxed_processX" />
34 * for X in 0...N-1 (where N is {@link SandboxedProcessLauncher#MAX_REGISTERED_S ERVICES})
35 */
36 public class SandboxedProcessService extends Service {
37 private static final String MAIN_THREAD_NAME = "SandboxedProcessMain";
38 private static final String TAG = "SandboxedProcessService";
39 private ISandboxedProcessCallback mCallback;
40
41 // This is the native "Main" thread for the renderer / utility process.
42 private Thread mSandboxMainThread;
43 // Parameters received via IPC, only accessed while holding the mSandboxMain Thread monitor.
44 private String[] mCommandLineParams;
45 private ParcelFileDescriptor mIPCFd;
46 private ParcelFileDescriptor mCrashFd;
47 private ParcelFileDescriptor mChromePakFd;
48 private ParcelFileDescriptor mLocalePakFd;
49
50 private static Context sContext = null;
51 private boolean mLibraryInitialized = false;
52
53 // Binder object used by clients for this service.
54 private final ISandboxedProcessService.Stub mBinder = new ISandboxedProcessS ervice.Stub() {
55 // NOTE: Implement any ISandboxedProcessService methods here.
56 @Override
57 public int setupConnection(Bundle args, ISandboxedProcessCallback callba ck) {
58 mCallback = callback;
59 synchronized (mSandboxMainThread) {
60 // Allow the command line to be set via bind() intent or setupCo nnection, but
61 // the FD can only be transferred here.
62 if (mCommandLineParams == null) {
63 mCommandLineParams = args.getStringArray(
64 SandboxedProcessConnection.EXTRA_COMMAND_LINE);
65 }
66 // We must have received the command line by now
67 assert mCommandLineParams != null;
68 mIPCFd = args.getParcelable(SandboxedProcessConnection.EXTRA_IPC _FD);
69 mLocalePakFd = args.getParcelable(SandboxedProcessConnection.EXT RA_LOCALE_PAK_FD);
70 // mCrashFd may be null if native crash reporting is disabled.
71 if (args.containsKey(SandboxedProcessConnection.EXTRA_CRASH_FD)) {
72 mCrashFd = args.getParcelable(SandboxedProcessConnection.EXT RA_CRASH_FD);
73 }
74 mSandboxMainThread.notifyAll();
75 }
76 return Process.myPid();
77 }
78
79 @Override
80 public void setSurface(int type, Surface surface, int primaryID, int sec ondaryID) {
81 // This gives up ownership of the Surface.
82 SurfaceCallback.setSurface(type, surface, primaryID, secondaryID);
83 }
84 };
85
86 /* package */ static Context getContext() {
87 return sContext;
88 }
89
90 @Override
91 public void onCreate() {
92 sContext = this;
93 super.onCreate();
94
95 mSandboxMainThread = new Thread(new Runnable() {
96 @Override
97 public void run() {
98 try {
99 // TODO(michaelbai): Upstream LibraryLoader.java
100 // if (!LibraryLoader.loadNow()) return;
101 synchronized (mSandboxMainThread) {
102 while (mCommandLineParams == null) {
103 mSandboxMainThread.wait();
104 }
105 }
106 // LibraryLoader.initializeOnMainThread(mCommandLineParams);
107 synchronized (mSandboxMainThread) {
108 mLibraryInitialized = true;
109 mSandboxMainThread.notifyAll();
110 while (mIPCFd == null) {
111 mSandboxMainThread.wait();
112 }
113 }
114 int crashFd = (mCrashFd == null) ? -1 : mCrashFd.detachFd();
115 ContentMain.initApplicationContext(sContext.getApplicationCo ntext());
116 nativeInitSandboxedProcess(sContext.getApplicationContext(),
117 SandboxedProcessService.this, mIPCFd.detachFd(), cra shFd,
118 mChromePakFd.detachFd(), mLocalePakFd.detachFd());
Yaron 2012/06/11 20:45:51 You're guaranteeing crashes here. Just pass NULL/0
michaelbai 2012/06/11 21:00:10 Removed them.
119 ContentMain.start();
120 nativeExitSandboxedProcess();
121 } catch (InterruptedException e) {
122 Log.w(TAG, MAIN_THREAD_NAME + " startup failed: " + e);
123 }
124 }
125 }, MAIN_THREAD_NAME);
126 mSandboxMainThread.start();
127 }
128
129 @Override
130 public void onDestroy() {
131 super.onDestroy();
132 if (mCommandLineParams == null) {
133 // This process was destroyed before it even started. Nothing more t o do.
134 return;
135 }
136 synchronized (mSandboxMainThread) {
137 try {
138 while (!mLibraryInitialized) {
139 // Avoid a potential race in calling through to native code before the library
140 // has loaded.
141 mSandboxMainThread.wait();
142 }
143 } catch (InterruptedException e) {
144 }
145 }
146
147 // This is not synchronized with the main thread in any way, but this is analogous
148 // to how desktop chrome terminates processes using SIGTERM. The mSandbo xMainThread
149 // may run briefly before this is executed, but will eventually get a ch annel error
150 // and similarly commit suicide via SuicideOnChannelErrorFilter().
151 // TODO(tedbo): Why doesn't the activity manager SIGTERM/SIGKILL this se rvice process?
152 nativeExitSandboxedProcess();
153 }
154
155 @Override
156 public IBinder onBind(Intent intent) {
157 // We call stopSelf() to request that this service be stopped as soon as the client
158 // unbinds. Otherwise the system may keep it around and available for a reconnect. The
159 // sandboxed processes do not currently support reconnect; they must be initialized from
160 // scratch every time.
161 stopSelf();
162
163 synchronized (mSandboxMainThread) {
164 mCommandLineParams = intent.getStringArrayExtra(
165 SandboxedProcessConnection.EXTRA_COMMAND_LINE);
166 mSandboxMainThread.notifyAll();
167 }
168
169 return mBinder;
170 }
171
172 /**
173 * Called from native code to share a surface texture with another child pro cess.
174 * Through using the callback object the browser is used as a proxy to route the
175 * call to the correct process.
176 *
177 * @param pid Process handle of the sandboxed process to share the SurfaceTe xture with.
178 * @param type The type of process that the SurfaceTexture is for.
179 * @param surfaceObject The Surface or SurfaceTexture to share with the othe r sandboxed process.
180 * @param primaryID Used to route the call to the correct client instance.
181 * @param secondaryID Used to route the call to the correct client instance.
182 */
183 @SuppressWarnings("unused")
184 @CalledByNative
185 private void establishSurfaceTexturePeer(int pid, int type, Object surfaceOb ject, int primaryID,
186 int secondaryID) {
187 if (mCallback == null) {
188 Log.e(TAG, "No callback interface has been provided.");
189 return;
190 }
191
192 Surface surface = null;
193 boolean needRelease = false;
194 if (surfaceObject instanceof Surface) {
195 surface = (Surface)surfaceObject;
196 } else if (surfaceObject instanceof SurfaceTexture) {
197 surface = new Surface((SurfaceTexture)surfaceObject);
198 needRelease = true;
199 } else {
200 Log.e(TAG, "Not a valid surfaceObject: " + surfaceObject);
201 return;
202 }
203 try {
204 mCallback.establishSurfacePeer(pid, type, surface, primaryID, second aryID);
205 } catch (RemoteException e) {
206 Log.e(TAG, "Unable to call establishSurfaceTexturePeer: " + e);
207 return;
208 } finally {
209 if (needRelease) {
210 surface.release();
211 }
212 }
213 }
214
215 /**
216 * The main entry point for a sandboxed process. This should be called from a new thread since
217 * it will not return until the sandboxed process exits. See sandboxed_proce ss_service.{h,cc}
218 *
219 * @param applicationContext The Application Context of the current process.
220 * @param service The current SandboxedProcessService object.
221 * @param ipcFd File descriptor to use for ipc.
222 * @param crashFd File descriptor for signaling crashes.
223 */
224 private static native void nativeInitSandboxedProcess(Context applicationCon text,
225 SandboxedProcessService service, int ipcFd, int crashFd, int chromeP akFd,
226 int localePakFd);
227
228 /**
229 * Force the sandboxed process to exit.
230 */
231 private static native void nativeExitSandboxedProcess();
232 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698