1 // Copyright (c) 2013 Intel Corporation. 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.
5 package org.xwalk.core;
7 import java.io.InputStream;
8 import java.util.HashSet;
11 import android.content.Context;
12 import android.content.res.Resources.NotFoundException;
13 import android.os.Build;
14 import android.util.Log;
16 import org.chromium.base.ActivityStatus;
17 import org.chromium.base.CommandLine;
18 import org.chromium.base.PathUtils;
19 import org.chromium.base.ThreadUtils;
20 import org.chromium.base.library_loader.LibraryLoader;
21 import org.chromium.base.library_loader.ProcessInitException;
22 import org.chromium.content.browser.BrowserStartupController;
23 import org.chromium.content.browser.DeviceUtils;
24 import org.chromium.content.browser.ResourceExtractor;
25 import org.chromium.content.browser.ResourceExtractor.ResourceIntercepter;
27 class XWalkViewDelegate {
28 private static boolean sInitialized = false;
29 private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "xwalkcore";
30 private static final String[] MANDATORY_PAKS = {
31 "xwalk.pak", "en-US.pak" };
32 private static final String[] MANDATORY_LIBRARIES = {
35 private static final String TAG = "XWalkViewDelegate";
36 private static final String XWALK_RESOURCES_LIST_RES_NAME = "xwalk_resources_list";
38 public static void init(XWalkView xwalkView) {
43 // Initialize the ActivityStatus. This is needed and used by many internal
44 // features such as location provider to listen to activity status.
45 ActivityStatus.initialize(xwalkView.getActivity().getApplication());
47 final Context context = xwalkView.getViewContext();
49 // Last place to initialize CommandLine object. If you haven't initialize
50 // the CommandLine object before XWalkViewContent is created, here will create
51 // the object to guarantee the CommandLine object is not null and the
52 // consequent prodedure does not crash.
53 if (!CommandLine.isInitialized())
54 CommandLine.init(null);
56 // If context's applicationContext is not the same package with itself,
57 // It's a cross package invoking, load core library from library apk.
58 // Only load the native library from /data/data if the Android version is
59 // lower than 4.2. Android enables a system path /data/app-lib to store native
60 // libraries starting from 4.2 and load them automatically.
61 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 &&
62 !context.getApplicationContext().getPackageName().equals(context.getPackageName())) {
64 for (String library : MANDATORY_LIBRARIES) {
65 System.load("/data/data/" + context.getPackageName() + "/lib/" + library);
67 } catch (UnsatisfiedLinkError e) {
68 throw new RuntimeException("Cannot initialize Crosswalk Core", e);
72 DeviceUtils.addDeviceSpecificUserAgentSwitch(context);
74 ResourceExtractor.setMandatoryPaksToExtract(MANDATORY_PAKS);
75 final int resourcesListResId = context.getResources().getIdentifier(
76 XWALK_RESOURCES_LIST_RES_NAME, "array", context.getPackageName());
77 if (resourcesListResId != 0) {
78 ResourceExtractor.setResourceIntercepter(new ResourceIntercepter() {
81 public Set<String> getInterceptableResourceList() {
83 Set<String> resourcesList = new HashSet<String>();
84 String[] resources = context.getResources().getStringArray(resourcesListResId);
85 for (String resource : resources) {
86 resourcesList.add(resource);
89 } catch (NotFoundException e) {
90 Log.w(TAG, "R.array." + XWALK_RESOURCES_LIST_RES_NAME + " can't be found.");
96 public InputStream interceptLoadingForResource(String resource) {
97 String resourceName = resource.split("\\.")[0];
98 int resId = context.getResources().getIdentifier(
99 resourceName, "raw", context.getPackageName());
101 if (resId != 0) return context.getResources().openRawResource(resId);
102 } catch (NotFoundException e) {
103 Log.w(TAG, "R.raw." + resourceName + " can't be found.");
109 ResourceExtractor.setExtractImplicitLocaleForTesting(false);
110 // Use MixedContext to initialize the ResourceExtractor, as the pak file
111 // is in the library apk if in shared apk mode.
112 ResourceExtractor.get(context);
114 startBrowserProcess(context);
118 private static void loadLibrary() {
119 PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
121 LibraryLoader.loadNow();
122 } catch (ProcessInitException e) {
123 throw new RuntimeException("Cannot load Crosswalk Core", e);
127 private static void startBrowserProcess(final Context context) {
128 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
132 LibraryLoader.ensureInitialized();
133 } catch (ProcessInitException e) {
134 throw new RuntimeException("Cannot initialize Crosswalk Core", e);
137 BrowserStartupController.get(context).startBrowserProcessesSync(
138 BrowserStartupController.MAX_RENDERERS_SINGLE_PROCESS);
139 } catch (ProcessInitException e) {
140 throw new RuntimeException("Cannot initialize Crosswalk Core", e);