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

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: Init 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 mChromePakFd = args.getParcelable(SandboxedProcessConnection.EXT RA_CHROME_PAK_FD);
Yaron 2012/06/11 19:46:22 Hmm. Not entirely sure how to fix this right now a
michaelbai 2012/06/11 20:30:16 Done.
Yaron 2012/06/11 20:45:51 So mLocalePakFd is part of the same problem. Pleas
70 mLocalePakFd = args.getParcelable(SandboxedProcessConnection.EXT RA_LOCALE_PAK_FD);
71 // mCrashFd may be null if native crash reporting is disabled.
72 if (args.containsKey(SandboxedProcessConnection.EXTRA_CRASH_FD)) {
73 mCrashFd = args.getParcelable(SandboxedProcessConnection.EXT RA_CRASH_FD);
74 }
75 mSandboxMainThread.notifyAll();
76 }
77 return Process.myPid();
78 }
79
80 @Override
81 public void setSurface(int type, Surface surface, int primaryID, int sec ondaryID) {
82 // This gives up ownership of the Surface.
83 SurfaceCallback.setSurface(type, surface, primaryID, secondaryID);
84 }
85 };
86
87 /* package */ static Context getContext() {
88 return sContext;
89 }
90
91 @Override
92 public void onCreate() {
93 sContext = this;
94 super.onCreate();
95
96 mSandboxMainThread = new Thread(new Runnable() {
97 @Override
98 public void run() {
99 try {
100 // TODO(michaelbai): Upstream LibraryLoader.java
101 // if (!LibraryLoader.loadNow()) return;
102 synchronized (mSandboxMainThread) {
103 while (mCommandLineParams == null) {
104 mSandboxMainThread.wait();
105 }
106 }
107 // LibraryLoader.initializeOnMainThread(mCommandLineParams);
108 synchronized (mSandboxMainThread) {
109 mLibraryInitialized = true;
110 mSandboxMainThread.notifyAll();
111 while (mIPCFd == null) {
112 mSandboxMainThread.wait();
113 }
114 }
115 int crashFd = (mCrashFd == null) ? -1 : mCrashFd.detachFd();
116 ContentMain.initApplicationContext(sContext.getApplicationCo ntext());
117 nativeInitSandboxedProcess(sContext.getApplicationContext(),
118 SandboxedProcessService.this, mIPCFd.detachFd(), cra shFd,
119 mChromePakFd.detachFd(), mLocalePakFd.detachFd());
120 ContentMain.start();
121 nativeExitSandboxedProcess();
122 } catch (InterruptedException e) {
123 Log.w(TAG, MAIN_THREAD_NAME + " startup failed: " + e);
124 }
125 }
126 }, MAIN_THREAD_NAME);
127 mSandboxMainThread.start();
128 }
129
130 @Override
131 public void onDestroy() {
132 super.onDestroy();
133 if (mCommandLineParams == null) {
134 // This process was destroyed before it even started. Nothing more t o do.
135 return;
136 }
137 synchronized (mSandboxMainThread) {
138 try {
139 while (!mLibraryInitialized) {
140 // Avoid a potential race in calling through to native code before the library
141 // has loaded.
142 mSandboxMainThread.wait();
143 }
144 } catch (InterruptedException e) {
145 }
146 }
147
148 // This is not synchronized with the main thread in any way, but this is analogous
149 // to how desktop chrome terminates processes using SIGTERM. The mSandbo xMainThread
150 // may run briefly before this is executed, but will eventually get a ch annel error
151 // and similarly commit suicide via SuicideOnChannelErrorFilter().
152 // TODO(tedbo): Why doesn't the activity manager SIGTERM/SIGKILL this se rvice process?
153 nativeExitSandboxedProcess();
154 }
155
156 @Override
157 public IBinder onBind(Intent intent) {
158 // We call stopSelf() to request that this service be stopped as soon as the client
159 // unbinds. Otherwise the system may keep it around and available for a reconnect. The
160 // sandboxed processes do not currently support reconnect; they must be initialized from
161 // scratch every time.
162 stopSelf();
163
164 synchronized (mSandboxMainThread) {
165 mCommandLineParams = intent.getStringArrayExtra(
166 SandboxedProcessConnection.EXTRA_COMMAND_LINE);
167 mSandboxMainThread.notifyAll();
168 }
169
170 return mBinder;
171 }
172
173 /**
174 * Called from native code to share a surface texture with another child pro cess.
175 * Through using the callback object the browser is used as a proxy to route the
176 * call to the correct process.
177 *
178 * @param pid Process handle of the sandboxed process to share the SurfaceTe xture with.
179 * @param type The type of process that the SurfaceTexture is for.
180 * @param surfaceObject The Surface or SurfaceTexture to share with the othe r sandboxed process.
181 * @param primaryID Used to route the call to the correct client instance.
182 * @param secondaryID Used to route the call to the correct client instance.
183 */
184 @SuppressWarnings("unused")
185 @CalledByNative
186 private void establishSurfaceTexturePeer(int pid, int type, Object surfaceOb ject, int primaryID,
187 int secondaryID) {
188 if (mCallback == null) {
189 Log.e(TAG, "No callback interface has been provided.");
190 return;
191 }
192
193 Surface surface = null;
194 boolean needRelease = false;
195 if (surfaceObject instanceof Surface) {
196 surface = (Surface)surfaceObject;
197 } else if (surfaceObject instanceof SurfaceTexture) {
198 surface = new Surface((SurfaceTexture)surfaceObject);
199 needRelease = true;
200 } else {
201 Log.e(TAG, "Not a valid surfaceObject: " + surfaceObject);
202 return;
203 }
204 try {
205 mCallback.establishSurfacePeer(pid, type, surface, primaryID, second aryID);
206 } catch (RemoteException e) {
207 Log.e(TAG, "Unable to call establishSurfaceTexturePeer: " + e);
208 return;
209 } finally {
210 if (needRelease) {
211 surface.release();
212 }
213 }
214 }
215
216 /**
217 * The main entry point for a sandboxed process. This should be called from a new thread since
218 * it will not return until the sandboxed process exits. See sandboxed_proce ss_service.{h,cc}
219 *
220 * @param applicationContext The Application Context of the current process.
221 * @param service The current SandboxedProcessService object.
222 * @param ipcFd File descriptor to use for ipc.
223 * @param crashFd File descriptor for signaling crashes.
224 */
225 private static native void nativeInitSandboxedProcess(Context applicationCon text,
226 SandboxedProcessService service, int ipcFd, int crashFd, int chromeP akFd,
227 int localePakFd);
228
229 /**
230 * Force the sandboxed process to exit.
231 */
232 private static native void nativeExitSandboxedProcess();
233 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698