Index: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
index 71ad6d0861afde9d741aa6760acd8d16de411a65..e7ea3067ab03879152238b20704deb45317d6f2c 100644 |
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
@@ -4,10 +4,14 @@ |
package org.chromium.content.browser; |
+import android.annotation.SuppressLint; |
import android.content.Context; |
+import android.content.Intent; |
import android.content.pm.ApplicationInfo; |
import android.content.pm.PackageManager; |
import android.graphics.SurfaceTexture; |
+import android.os.Build; |
+import android.os.Bundle; |
import android.os.ParcelFileDescriptor; |
import android.os.RemoteException; |
import android.text.TextUtils; |
@@ -15,6 +19,7 @@ import android.util.Pair; |
import android.view.Surface; |
import org.chromium.base.CommandLine; |
+import org.chromium.base.CpuFeatures; |
import org.chromium.base.Log; |
import org.chromium.base.ThreadUtils; |
import org.chromium.base.TraceEvent; |
@@ -24,6 +29,7 @@ import org.chromium.base.annotations.JNINamespace; |
import org.chromium.base.library_loader.Linker; |
import org.chromium.content.app.ChildProcessService; |
import org.chromium.content.app.ChromiumLinkerParams; |
+import org.chromium.content.app.DownloadProcessService; |
import org.chromium.content.app.PrivilegedProcessService; |
import org.chromium.content.app.SandboxedProcessService; |
import org.chromium.content.common.IChildProcessCallback; |
@@ -31,7 +37,9 @@ import org.chromium.content.common.SurfaceWrapper; |
import java.io.IOException; |
import java.util.ArrayList; |
+import java.util.Arrays; |
import java.util.LinkedList; |
+import java.util.List; |
import java.util.Map; |
import java.util.Queue; |
import java.util.concurrent.ConcurrentHashMap; |
@@ -47,11 +55,13 @@ public class ChildProcessLauncher { |
static final int CALLBACK_FOR_GPU_PROCESS = 1; |
static final int CALLBACK_FOR_RENDERER_PROCESS = 2; |
static final int CALLBACK_FOR_UTILITY_PROCESS = 3; |
+ static final int CALLBACK_FOR_DOWNLOAD_PROCESS = 4; |
private static final String SWITCH_PROCESS_TYPE = "type"; |
private static final String SWITCH_RENDERER_PROCESS = "renderer"; |
private static final String SWITCH_UTILITY_PROCESS = "utility"; |
private static final String SWITCH_GPU_PROCESS = "gpu-process"; |
+ private static final String SWITCH_DOWNLOAD_PROCESS = "download"; |
/** |
* Allows specifying the package name for looking up child services |
@@ -110,7 +120,7 @@ public class ChildProcessLauncher { |
mFreeConnectionIndices.add(i); |
} |
mChildClass = |
- inSandbox ? SandboxedProcessService.class : PrivilegedProcessService.class; |
+ inSandbox ? SandboxedProcessService.class : PrivilegedProcessService.class; |
mInSandbox = inSandbox; |
} |
@@ -437,6 +447,10 @@ public class ChildProcessLauncher { |
private static Map<Pair<Integer, Integer>, Surface> sSurfaceTextureSurfaceMap = |
new ConcurrentHashMap<Pair<Integer, Integer>, Surface>(); |
+ // Map from channel id to a list of FileDescriptorInfo for download child process. |
+ private static Map<String, List<FileDescriptorInfo>> sDownloadFilesMap = |
+ new ConcurrentHashMap<String, List<FileDescriptorInfo>>(); |
+ |
// Whether the main application is currently brought to the foreground. |
private static boolean sApplicationInForeground = true; |
@@ -626,6 +640,9 @@ public class ChildProcessLauncher { |
} else if (SWITCH_UTILITY_PROCESS.equals(processType)) { |
// We only support sandboxed right now. |
callbackType = CALLBACK_FOR_UTILITY_PROCESS; |
+ } else if (SWITCH_DOWNLOAD_PROCESS.equals(processType)) { |
+ callbackType = CALLBACK_FOR_DOWNLOAD_PROCESS; |
+ inSandbox = false; |
} else { |
assert false; |
} |
@@ -645,6 +662,12 @@ public class ChildProcessLauncher { |
try { |
TraceEvent.begin("ChildProcessLauncher.startInternal"); |
+ if (callbackType == CALLBACK_FOR_DOWNLOAD_PROCESS) { |
+ ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnection(); |
+ startDownloadProcess(context, filesToBeMapped, commandLine, chromiumLinkerParams); |
+ return; |
+ } |
+ |
ChildProcessConnection allocatedConnection = null; |
synchronized (ChildProcessLauncher.class) { |
if (inSandbox) { |
@@ -675,6 +698,60 @@ public class ChildProcessLauncher { |
} |
} |
+ /** |
+ * Create the common bundle to be passed to child processes. |
+ * @param context Application context. |
+ * @param commandLine Command line params to be passed to the service. |
+ * @param linkerParams Linker params to start the service. |
+ */ |
+ protected static Bundle createsServiceBundle( |
svaldez
2016/01/25 15:33:43
createDownloadServiceBundle
qinmin
2016/01/25 22:48:23
This function is also used in ChildProcessConnecti
|
+ String[] commandLine, FileDescriptorInfo[] filesToBeMapped, Bundle sharedRelros) { |
+ Bundle bundle = new Bundle(); |
+ bundle.putStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE, commandLine); |
+ bundle.putParcelableArray(ChildProcessConstants.EXTRA_FILES, filesToBeMapped); |
+ bundle.putInt(ChildProcessConstants.EXTRA_CPU_COUNT, CpuFeatures.getCount()); |
+ bundle.putLong(ChildProcessConstants.EXTRA_CPU_FEATURES, CpuFeatures.getMask()); |
+ bundle.putBundle(Linker.EXTRA_LINKER_SHARED_RELROS, sharedRelros); |
+ return bundle; |
+ } |
+ |
+ /** |
+ * Create the background download service. The download service controls its own life |
+ * time and may out live chrome. |
+ * @param context Application context. |
+ * @param commandLine Command line params to be passed to the service. |
+ * @param linkerParams Linker params to start the service. |
+ */ |
+ @SuppressLint("NewApi") |
+ private static void startDownloadProcess(Context context, FileDescriptorInfo[] filesToBeMapped, |
+ final String[] commandLine, final ChromiumLinkerParams linkerParams) { |
+ assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; |
+ Intent intent = new Intent(); |
+ intent.setClass(context, DownloadProcessService.class); |
+ intent.setPackage(context.getPackageName()); |
+ |
+ if (commandLine != null) { |
+ intent.putExtra(ChildProcessConstants.EXTRA_COMMAND_LINE, commandLine); |
+ } |
+ Bundle bundle = |
+ createsServiceBundle(commandLine, null, Linker.getInstance().getSharedRelros()); |
+ // Pid doesn't matter for download process. |
+ bundle.putBinder(ChildProcessConstants.EXTRA_CHILD_PROCESS_CALLBACK, |
+ createCallback(0, CALLBACK_FOR_DOWNLOAD_PROCESS).asBinder()); |
+ intent.putExtras(bundle); |
+ if (linkerParams != null) { |
+ linkerParams.addIntentExtras(intent); |
+ } |
+ if (filesToBeMapped != null) { |
+ String channel = |
+ getSwitchValue(commandLine, ChildProcessConstants.PROCESS_CHANNEL_ID_SWITCH); |
+ assert channel != null; |
+ sDownloadFilesMap.put(channel, Arrays.asList(filesToBeMapped)); |
+ intent.putExtra(ChildProcessConstants.EXTRA_CHANNEL_ID, channel); |
+ } |
+ context.startService(intent); |
+ } |
+ |
@VisibleForTesting |
static void triggerConnectionSetup( |
final ChildProcessConnection connection, |
@@ -806,6 +883,12 @@ public class ChildProcessLauncher { |
return ChildProcessLauncher.getSurfaceTextureSurface(surfaceTextureId, |
childProcessId); |
} |
+ |
+ @Override |
+ public FileDescriptorInfo[] getFileDescriptorInfo(String channelId) { |
+ List<FileDescriptorInfo> info = sDownloadFilesMap.get(channelId); |
+ return info.toArray(new FileDescriptorInfo[info.size()]); |
+ } |
}; |
} |