// NOTE: Implement any IChildProcessService methods here. @Override public int setupConnection(Bundle args, IChildProcessCallback callback) { mCallback = callback; // Required to unparcel FileDescriptorInfo. args.setClassLoader(getClassLoader()); synchronized (mMainThread) { // Allow the command line to be set via bind() intent or setupConnection, but // the FD can only be transferred here. if (mCommandLineParams == null) { mCommandLineParams = args.getStringArray(ChildProcessConnection.EXTRA_COMMAND_LINE); } // We must have received the command line by now assert mCommandLineParams != null; mCpuCount = args.getInt(ChildProcessConnection.EXTRA_CPU_COUNT); mCpuFeatures = args.getLong(ChildProcessConnection.EXTRA_CPU_FEATURES); assert mCpuCount > 0; Parcelable[] fdInfosAsParcelable = args.getParcelableArray(ChildProcessConnection.EXTRA_FILES); // For why this arraycopy is necessary: // http://stackoverflow.com/questions/8745893/i-dont-get-why-this-classcastexception-occurs mFdInfos = new FileDescriptorInfo[fdInfosAsParcelable.length]; System.arraycopy(fdInfosAsParcelable, 0, mFdInfos, 0, fdInfosAsParcelable.length); Bundle sharedRelros = args.getBundle(Linker.EXTRA_LINKER_SHARED_RELROS); if (sharedRelros != null) { Linker.getInstance().useSharedRelros(sharedRelros); sharedRelros = null; } mMainThread.notifyAll(); } return Process.myPid(); }
private static ChromiumLinkerParams getLinkerParamsForNewConnection() { if (!sLinkerInitialized) { if (Linker.isUsed()) { sLinkerLoadAddress = Linker.getBaseLoadAddress(); if (sLinkerLoadAddress == 0) { Log.i(TAG, "Shared RELRO support disabled!"); } } sLinkerInitialized = true; } if (sLinkerLoadAddress == 0) return null; // Always wait for the shared RELROs in service processes. final boolean waitForSharedRelros = true; return new ChromiumLinkerParams( sLinkerLoadAddress, waitForSharedRelros, Linker.getTestRunnerClassName()); }
@VisibleForTesting static void triggerConnectionSetup( final ChildProcessConnection connection, String[] commandLine, int childProcessId, FileDescriptorInfo[] filesToBeMapped, final int callbackType, final long clientContext) { ChildProcessConnection.ConnectionCallback connectionCallback = new ChildProcessConnection.ConnectionCallback() { @Override public void onConnected(int pid) { Log.d( TAG, "on connect callback, pid=" + pid + " context=" + clientContext + " callbackType=" + callbackType); if (pid != NULL_PROCESS_HANDLE) { sBindingManager.addNewConnection(pid, connection); sServiceMap.put(pid, connection); } // If the connection fails and pid == 0, the Java-side cleanup was already // handled by DeathCallback. We still have to call back to native for // cleanup there. if (clientContext != 0) { // Will be 0 in Java instrumentation tests. nativeOnChildProcessStarted(clientContext, pid); } } }; assert callbackType != CALLBACK_FOR_UNKNOWN_PROCESS; connection.setupConnection( commandLine, filesToBeMapped, createCallback(childProcessId, callbackType), connectionCallback, Linker.getSharedRelros()); }