Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / XWalkViewDelegate.java
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.
4
5 package org.xwalk.core;
6
7 import java.io.InputStream;
8 import java.util.HashSet;
9 import java.util.Set;
10
11 import android.content.Context;
12 import android.content.res.Resources.NotFoundException;
13 import android.os.Build;
14 import android.util.Log;
15
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;
26
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 = {
33             "libxwalkcore.so"
34     };
35     private static final String TAG = "XWalkViewDelegate";
36     private static final String XWALK_RESOURCES_LIST_RES_NAME = "xwalk_resources_list";
37
38     public static void init(XWalkView xwalkView) {
39         if (sInitialized) {
40             return;
41         }
42
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());
46
47         final Context context = xwalkView.getViewContext();
48
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);
55
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())) {
63             try {
64                 for (String library : MANDATORY_LIBRARIES) {
65                     System.load("/data/data/" + context.getPackageName() + "/lib/" + library);
66                 }
67             } catch (UnsatisfiedLinkError e) {
68                 throw new RuntimeException("Cannot initialize Crosswalk Core", e);
69             }
70         }
71         loadLibrary();
72         DeviceUtils.addDeviceSpecificUserAgentSwitch(context);
73
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() {
79
80                 @Override
81                 public Set<String> getInterceptableResourceList() {
82                     try {
83                         Set<String> resourcesList = new HashSet<String>();
84                         String[] resources = context.getResources().getStringArray(resourcesListResId);
85                         for (String resource : resources) {
86                             resourcesList.add(resource);
87                         }
88                         return resourcesList;
89                     } catch (NotFoundException e) {
90                         Log.w(TAG, "R.array." + XWALK_RESOURCES_LIST_RES_NAME + " can't be found.");
91                     }
92                     return null;
93                 }
94
95                 @Override
96                 public InputStream interceptLoadingForResource(String resource) {
97                     String resourceName = resource.split("\\.")[0];
98                     int resId = context.getResources().getIdentifier(
99                             resourceName, "raw", context.getPackageName());
100                     try {
101                         if (resId != 0) return context.getResources().openRawResource(resId);
102                     } catch (NotFoundException e) {
103                         Log.w(TAG, "R.raw." + resourceName + " can't be found.");
104                     }
105                     return null;
106                 }
107             });
108         }
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);
113
114         startBrowserProcess(context);
115         sInitialized = true;
116     }
117
118     private static void loadLibrary() {
119         PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
120         try {
121             LibraryLoader.loadNow();
122         } catch (ProcessInitException e) {
123             throw new RuntimeException("Cannot load Crosswalk Core", e);
124         }
125     }
126
127     private static void startBrowserProcess(final Context context) {
128         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
129             @Override
130             public void run() {
131                 try {
132                     LibraryLoader.ensureInitialized();
133                 } catch (ProcessInitException e) {
134                     throw new RuntimeException("Cannot initialize Crosswalk Core", e);
135                 }
136                 try {
137                     BrowserStartupController.get(context).startBrowserProcessesSync(
138                         BrowserStartupController.MAX_RENDERERS_SINGLE_PROCESS);
139                 } catch (ProcessInitException e) {
140                     throw new RuntimeException("Cannot initialize Crosswalk Core", e);
141                 }
142             }
143         });
144     }
145 }