Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkApplication.java

Issue 1965583002: Move //webapk to //chrome/android/webapk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. 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.chromium.webapk.shell_apk;
6
7 import android.app.Application;
8 import android.content.Context;
9 import android.util.Log;
10
11 import org.chromium.webapk.lib.common.WebApkUtils;
12
13 import java.lang.reflect.Array;
14 import java.util.List;
15
16 /**
17 * Example application for a minted APK.
18 */
19 public class WebApkApplication extends Application {
20 // Context of Chrome.
21 private Context mRemoteContext = null;
22
23 private static final String TAG = "cr.WebApkApplication";
24 /**
25 * Copy all the objects from a specified field of the hostInstance to the sa me field of the
26 * mintInstance. As a result, the given field of the mintInstance will conta in all the
27 * objects from both instances.
28 * @param mintInstance the first instance which contains a field of the give n fieldName.
29 * @param fieldName the name of field to expand to an Object array.
30 * @param hostInstance the second instance which has a field of the given fi eldName.
31 * @throws NoSuchFieldException
32 * @throws IllegalArgumentException
33 * @throws IllegalAccessException
34 */
35 private static void expandField(Object mintInstance, String fieldName, Objec t hostInstance)
36 throws NoSuchFieldException, IllegalArgumentException,
37 IllegalAccessException {
38 try {
39 Object hostCurrentDirs = Reflect.getField(hostInstance, fieldName);
40 Object mintCurrentDirs = Reflect.getField(mintInstance, fieldName);
41 // Switched from an array to an ArrayList in Lollipop.
42 if (mintCurrentDirs instanceof List) {
43 List<Object> mintDirsAsList = (List<Object>) mintCurrentDirs;
44 concatAndRemoveEndDuplicates(mintDirsAsList, (List<Object>) host CurrentDirs);
45 } else {
46 Object[] mintDirsAsArray = (Object[]) mintCurrentDirs;
47 Object[] hostDirsAsArray = (Object[]) hostCurrentDirs;
48 Reflect.setField(mintInstance, fieldName,
49 concatAndRemoveEndDuplicates(mintDirsAsArray, hostDirsAs Array));
50 }
51 } catch (ReflectiveOperationException e) {
52 e.printStackTrace();
53 }
54 }
55
56 /**
57 * Combines two arrays into a new array.
58 * If the two arrays end with duplicated elements, keep one copy only. For e xample,
59 * the first array is [A, B, C, D], and the second array is [E, F, C, D], th e combined one is
60 * [A, B, E, F, C, D]. The unique elements are stored before the duplicates.
61 * The arrays must be of the same type.
62 * @param mintArrays: the array from a WebAPK
63 * @param hostArrays: the array from the host
64 * @return: a combined array consists of [WebAPK unique elements, host's uni que elements,
65 * duplicated one]
66 */
67 private static Object[] concatAndRemoveEndDuplicates(Object[] mintArrays, Ob ject[] hostArrays) {
68 int duplicate1 = mintArrays.length - 1;
69 int duplicate2 = hostArrays.length - 1;
70 int count = 0;
71 while (duplicate1 >= 0 && duplicate2 >= 0
72 && mintArrays[duplicate1].toString().equals(hostArrays[duplicate 2].toString())) {
73 --duplicate1;
74 --duplicate2;
75 ++count;
76 }
77 Object[] combined = (Object[]) Array.newInstance(mintArrays.getClass().g etComponentType(),
78 mintArrays.length + hostArrays.length - count);
79 if (mintArrays.length - count > 0) {
80 System.arraycopy(mintArrays, 0, combined, 0, mintArrays.length - cou nt);
81 }
82 System.arraycopy(hostArrays, 0, combined, mintArrays.length - count, hos tArrays.length);
83 return combined;
84 }
85
86 /**
87 * Add the unique elements of the second list to the first one.
88 * If the two lists end with duplicated elements, keep one copy only. For ex ample,
89 * the first list is [A, B, C, D], and the second list is [E, F, C, D], the combined one is
90 * [A, B, E, F, C, D]. The unique elements are store before the duplicates.
91 * The lists must be of the same type.
92 * @param mintList: the list from a WebAPK
93 * @param hostList: the list from the host
94 * @return: a combined list consists of [WebAPK unique elements, host's uniq ue elements,
95 * duplicated one]
96 */
97 private static void concatAndRemoveEndDuplicates(List<Object> mintList, List <Object> hostList) {
98 int duplicate1 = mintList.size() - 1;
99 int duplicate2 = hostList.size() - 1;
100 while (duplicate1 >= 0 && duplicate2 >= 0
101 && mintList.get(duplicate1).toString().equals(hostList.get(dupli cate2).toString()))
102 {
103 --duplicate1;
104 --duplicate2;
105 }
106 for (int i = 0; i < duplicate2 + 1; i++) {
107 mintList.add(duplicate1 + i, hostList.get(i));
108 }
109 }
110
111 private void addExternalLoader() throws ReflectiveOperationException {
112 if (mRemoteContext == null) {
113 Log.w(TAG, "Failed to add external loader since the remote context i s null.");
114 return;
115 }
116 ClassLoader externalLoader = mRemoteContext.getClassLoader();
117 ClassLoader mintLoader = getClassLoader();
118
119 Object extDexPathList = Reflect.getField(externalLoader, "pathList");
120 Object mintDexPathList = Reflect.getField(mintLoader, "pathList");
121 expandField(mintDexPathList, "dexElements", extDexPathList);
122 }
123
124 private void addNativeLibrarySearchPath() throws ReflectiveOperationExceptio n {
125 if (mRemoteContext == null) {
126 Log.w(TAG, "Failed to add external loader since the remote context i s null.");
127 return;
128 }
129 ClassLoader externalLoader = mRemoteContext.getClassLoader();
130 ClassLoader mintLoader = getClassLoader();
131
132 // Since both WebAPK and its host have the "system/lib" and "vendor/lib" at the end of
133 // the native library directory path list, we want to add host's directo ries before the
134 // system directory, and only keep one copy of the system directories.
135 // This is because when System.loadLibrary() is called, we want it searc h the host's
136 // native library directories first. If a ".so" file doesn't exit, then search /system/lib.
137 Object extDexPathList = Reflect.getField(externalLoader, "pathList");
138 Object mintDexPathList = Reflect.getField(mintLoader, "pathList");
139 expandField(mintDexPathList, "nativeLibraryDirectories", extDexPathList) ;
140 expandField(mintDexPathList, "nativeLibraryPathElements", extDexPathList );
141 }
142
143 @Override
144 public void onCreate() {
145 super.onCreate();
146 mRemoteContext = WebApkUtils.getHostBrowserContext(this);
147 try {
148 addExternalLoader();
149 addNativeLibrarySearchPath();
150 } catch (ReflectiveOperationException e) {
151 e.printStackTrace();
152 }
153 Log.w(TAG, "Successfully add external loader.");
154 }
155 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698