OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.content.app; | 5 package org.chromium.content.app; |
6 | 6 |
7 import android.app.Service; | 7 import android.app.Service; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.graphics.SurfaceTexture; | 10 import android.graphics.SurfaceTexture; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 // Linker-specific parameters for this child process service. | 62 // Linker-specific parameters for this child process service. |
63 private ChromiumLinkerParams mLinkerParams; | 63 private ChromiumLinkerParams mLinkerParams; |
64 | 64 |
65 private static AtomicReference<Context> sContext = new AtomicReference<Conte
xt>(null); | 65 private static AtomicReference<Context> sContext = new AtomicReference<Conte
xt>(null); |
66 private boolean mLibraryInitialized = false; | 66 private boolean mLibraryInitialized = false; |
67 // Becomes true once the service is bound. Access must synchronize around mM
ainThread. | 67 // Becomes true once the service is bound. Access must synchronize around mM
ainThread. |
68 private boolean mIsBound = false; | 68 private boolean mIsBound = false; |
69 | 69 |
70 private final Semaphore mActivitySemaphore = new Semaphore(1); | 70 private final Semaphore mActivitySemaphore = new Semaphore(1); |
71 | 71 |
| 72 // Return a Linker instance. If testing, the Linker needs special setup. |
| 73 private Linker getLinker() { |
| 74 if (Linker.areTestsEnabled()) { |
| 75 // For testing, set the Linker implementation and the test runner |
| 76 // class name to match those used by the parent. |
| 77 assert mLinkerParams != null; |
| 78 Linker.setupForTesting( |
| 79 mLinkerParams.mLinkerImplementationForTesting, |
| 80 mLinkerParams.mTestRunnerClassNameForTesting); |
| 81 } |
| 82 return Linker.getInstance(); |
| 83 } |
| 84 |
72 // Binder object used by clients for this service. | 85 // Binder object used by clients for this service. |
73 private final IChildProcessService.Stub mBinder = new IChildProcessService.S
tub() { | 86 private final IChildProcessService.Stub mBinder = new IChildProcessService.S
tub() { |
74 // NOTE: Implement any IChildProcessService methods here. | 87 // NOTE: Implement any IChildProcessService methods here. |
75 @Override | 88 @Override |
76 public int setupConnection(Bundle args, IChildProcessCallback callback)
{ | 89 public int setupConnection(Bundle args, IChildProcessCallback callback)
{ |
77 mCallback = callback; | 90 mCallback = callback; |
78 // Required to unparcel FileDescriptorInfo. | 91 // Required to unparcel FileDescriptorInfo. |
79 args.setClassLoader(getClassLoader()); | 92 args.setClassLoader(getClassLoader()); |
80 synchronized (mMainThread) { | 93 synchronized (mMainThread) { |
81 // Allow the command line to be set via bind() intent or setupCo
nnection, but | 94 // Allow the command line to be set via bind() intent or setupCo
nnection, but |
82 // the FD can only be transferred here. | 95 // the FD can only be transferred here. |
83 if (mCommandLineParams == null) { | 96 if (mCommandLineParams == null) { |
84 mCommandLineParams = args.getStringArray( | 97 mCommandLineParams = args.getStringArray( |
85 ChildProcessConnection.EXTRA_COMMAND_LINE); | 98 ChildProcessConnection.EXTRA_COMMAND_LINE); |
86 } | 99 } |
87 // We must have received the command line by now | 100 // We must have received the command line by now |
88 assert mCommandLineParams != null; | 101 assert mCommandLineParams != null; |
89 mCpuCount = args.getInt(ChildProcessConnection.EXTRA_CPU_COUNT); | 102 mCpuCount = args.getInt(ChildProcessConnection.EXTRA_CPU_COUNT); |
90 mCpuFeatures = args.getLong(ChildProcessConnection.EXTRA_CPU_FEA
TURES); | 103 mCpuFeatures = args.getLong(ChildProcessConnection.EXTRA_CPU_FEA
TURES); |
91 assert mCpuCount > 0; | 104 assert mCpuCount > 0; |
92 Parcelable[] fdInfosAsParcelable = | 105 Parcelable[] fdInfosAsParcelable = |
93 args.getParcelableArray(ChildProcessConnection.EXTRA_FIL
ES); | 106 args.getParcelableArray(ChildProcessConnection.EXTRA_FIL
ES); |
94 // For why this arraycopy is necessary: | 107 // For why this arraycopy is necessary: |
95 // http://stackoverflow.com/questions/8745893/i-dont-get-why-thi
s-classcastexception-occurs | 108 // http://stackoverflow.com/questions/8745893/i-dont-get-why-thi
s-classcastexception-occurs |
96 mFdInfos = new FileDescriptorInfo[fdInfosAsParcelable.length]; | 109 mFdInfos = new FileDescriptorInfo[fdInfosAsParcelable.length]; |
97 System.arraycopy(fdInfosAsParcelable, 0, mFdInfos, 0, fdInfosAsP
arcelable.length); | 110 System.arraycopy(fdInfosAsParcelable, 0, mFdInfos, 0, fdInfosAsP
arcelable.length); |
98 Bundle sharedRelros = args.getBundle(Linker.EXTRA_LINKER_SHARED_
RELROS); | 111 Bundle sharedRelros = args.getBundle(Linker.EXTRA_LINKER_SHARED_
RELROS); |
99 if (sharedRelros != null) { | 112 if (sharedRelros != null) { |
100 Linker.getInstance().useSharedRelros(sharedRelros); | 113 getLinker().useSharedRelros(sharedRelros); |
101 sharedRelros = null; | 114 sharedRelros = null; |
102 } | 115 } |
103 mMainThread.notifyAll(); | 116 mMainThread.notifyAll(); |
104 } | 117 } |
105 return Process.myPid(); | 118 return Process.myPid(); |
106 } | 119 } |
107 | 120 |
108 @Override | 121 @Override |
109 public void crashIntentionallyForTesting() { | 122 public void crashIntentionallyForTesting() { |
110 Process.killProcess(Process.myPid()); | 123 Process.killProcess(Process.myPid()); |
111 } | 124 } |
112 }; | 125 }; |
113 | 126 |
114 /* package */ static Context getContext() { | 127 /* package */ static Context getContext() { |
115 return sContext.get(); | 128 return sContext.get(); |
116 } | 129 } |
117 | 130 |
118 // Return a new Linker instance. If testing, the Linker needs special setup. | |
119 private Linker getLinker() { | |
120 if (Linker.areLinkerTestsEnabled()) { | |
121 // If testing, set the Linker implementation and the test runner | |
122 // class name to match the one used by the parent. | |
123 assert mLinkerParams != null; | |
124 Linker.setLinkerImplementationForTesting( | |
125 mLinkerParams.mLinkerImplementationForTesting); | |
126 Linker linker = Linker.getInstance(); | |
127 linker.setTestRunnerClassNameForTesting( | |
128 mLinkerParams.mTestRunnerClassNameForTesting); | |
129 return linker; | |
130 } | |
131 // Not testing, so return a normal the Linker instantiation. | |
132 return Linker.getInstance(); | |
133 } | |
134 | |
135 @Override | 131 @Override |
136 public void onCreate() { | 132 public void onCreate() { |
137 Log.i(TAG, "Creating new ChildProcessService pid=%d", Process.myPid()); | 133 Log.i(TAG, "Creating new ChildProcessService pid=%d", Process.myPid()); |
138 if (sContext.get() != null) { | 134 if (sContext.get() != null) { |
139 throw new RuntimeException("Illegal child process reuse."); | 135 throw new RuntimeException("Illegal child process reuse."); |
140 } | 136 } |
141 sContext.set(this); | 137 sContext.set(this); |
142 super.onCreate(); | 138 super.onCreate(); |
143 | 139 |
144 mMainThread = new Thread(new Runnable() { | 140 mMainThread = new Thread(new Runnable() { |
145 @Override | 141 @Override |
146 @SuppressFBWarnings("DM_EXIT") | 142 @SuppressFBWarnings("DM_EXIT") |
147 public void run() { | 143 public void run() { |
148 try { | 144 try { |
149 // CommandLine must be initialized before others, e.g., Link
er.isUsed() | 145 // CommandLine must be initialized before everything else. |
150 // may check the command line options. | |
151 synchronized (mMainThread) { | 146 synchronized (mMainThread) { |
152 while (mCommandLineParams == null) { | 147 while (mCommandLineParams == null) { |
153 mMainThread.wait(); | 148 mMainThread.wait(); |
154 } | 149 } |
155 } | 150 } |
156 CommandLine.init(mCommandLineParams); | 151 CommandLine.init(mCommandLineParams); |
157 Linker linker = getLinker(); | 152 |
158 boolean useLinker = linker.isUsed(); | 153 Linker linker = null; |
159 boolean requestedSharedRelro = false; | 154 boolean requestedSharedRelro = false; |
160 if (useLinker) { | 155 if (Linker.isUsed()) { |
161 synchronized (mMainThread) { | 156 synchronized (mMainThread) { |
162 while (!mIsBound) { | 157 while (!mIsBound) { |
163 mMainThread.wait(); | 158 mMainThread.wait(); |
164 } | 159 } |
165 } | 160 } |
| 161 linker = getLinker(); |
166 if (mLinkerParams.mWaitForSharedRelro) { | 162 if (mLinkerParams.mWaitForSharedRelro) { |
167 requestedSharedRelro = true; | 163 requestedSharedRelro = true; |
168 linker.initServiceProcess(mLinkerParams.mBaseLoadAdd
ress); | 164 linker.initServiceProcess(mLinkerParams.mBaseLoadAdd
ress); |
169 } else { | 165 } else { |
170 linker.disableSharedRelros(); | 166 linker.disableSharedRelros(); |
171 } | 167 } |
172 } | 168 } |
173 boolean isLoaded = false; | 169 boolean isLoaded = false; |
174 if (CommandLine.getInstance().hasSwitch( | 170 if (CommandLine.getInstance().hasSwitch( |
175 BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER)) { | 171 BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER)) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 private static native void nativeInitChildProcess( | 405 private static native void nativeInitChildProcess( |
410 ChildProcessService service, int cpuCount, long cpuFeatures); | 406 ChildProcessService service, int cpuCount, long cpuFeatures); |
411 | 407 |
412 /** | 408 /** |
413 * Force the child process to exit. | 409 * Force the child process to exit. |
414 */ | 410 */ |
415 private static native void nativeExitChildProcess(); | 411 private static native void nativeExitChildProcess(); |
416 | 412 |
417 private native void nativeShutdownMainThread(); | 413 private native void nativeShutdownMainThread(); |
418 } | 414 } |
OLD | NEW |