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

Unified Diff: services/android/java/src/org/chromium/services/android/JavaHandler.java

Issue 898853006: Java content handler for Android. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/android/BUILD.gn ('k') | services/android/java_handler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/android/java/src/org/chromium/services/android/JavaHandler.java
diff --git a/services/android/java/src/org/chromium/services/android/JavaHandler.java b/services/android/java/src/org/chromium/services/android/JavaHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..7abdcf402c93245bdd87314e36e310585097d2d7
--- /dev/null
+++ b/services/android/java/src/org/chromium/services/android/JavaHandler.java
@@ -0,0 +1,141 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.services.android;
+
+import android.content.Context;
+import android.util.Log;
+
+import dalvik.system.DexClassLoader;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.MessagePipeHandle;
+import org.chromium.mojo.system.impl.CoreImpl;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * Content handler for Android Java code.
+ */
+@JNINamespace("services::android")
+public class JavaHandler {
+ private static final String TAG = "JavaHandler";
+
+ // File extensions used to identify application libraries in the provided
+ // archive.
+ private static final String JAVA_LIBRARY_SUFFIX = ".dex.jar";
+ // Filename sections used for naming temporary files holding application
+ // files.
+ private static final String ARCHIVE_PREFIX = "archive";
+
+ // Directories used to hold temporary files. These are cleared when
+ // clearTemporaryFiles() is called.
+ private static final String DEX_OUTPUT_DIRECTORY = "dex_output";
+ private static final String APP_DIRECTORY = "applications";
+
+ private static final int BUFFER_SIZE = 1024;
+
+ /**
+ * Deletes directories holding the temporary files.
+ */
+ private static void clearTemporaryFiles(Context context, File archive) {
+ deleteRecursively(getDexOutputDir(context));
+ deleteRecursively(archive);
+ }
+
+ /**
+ * Deletes a file or directory. Directory will be deleted even if not empty.
+ */
+ private static void deleteRecursively(File file) {
+ if (file.isDirectory()) {
+ for (File child : file.listFiles()) {
+ deleteRecursively(child);
+ }
+ }
+ file.delete();
+ }
+
+ /**
+ * Returns the path at which the native part should save the application archive.
+ */
+ @CalledByNative
+ private static String getNewTempLibraryPath(Context context) throws IOException {
+ return File.createTempFile(ARCHIVE_PREFIX, JAVA_LIBRARY_SUFFIX, getAppDir(context))
+ .getAbsolutePath();
+ }
+
+ /**
+ * Extracts and runs the application libraries contained by the indicated archive.
+ *
+ * @param context the application context
+ * @param archivePath the path of the archive containing the application to be run
+ * @param handle handle to the shell to be passed to the native application. On the Java side
+ * this is opaque payload.
+ * @param runApplicationPtr pointer to the function that will set the native thunks and call
+ * into the application MojoMain. On the Java side this is opaque payload.
+ */
+ @CalledByNative
+ private static boolean bootstrap(Context context, String archivePath,
+ int applicationRequestHandle) {
+ File application_java_library = new File(archivePath);
+
+ String dexPath = application_java_library.getAbsolutePath();
+ DexClassLoader bootstrapLoader = new DexClassLoader(dexPath,
+ getDexOutputDir(context).getAbsolutePath(), null,
+ JavaHandler.class.getClassLoader());
+
+ // The starting Mojo class is a class implementing a static MojoMain
+ // method. Its name
+ // is defined in the .jar manifest file, like a .jar defines a
+ // Main-Class attribute for
+ // the starting point of a standalone java application.
+ String mojoClass;
+ try {
+ try {
+ JarFile jar = new JarFile(application_java_library);
+ Manifest manifest = jar.getManifest();
+ mojoClass = manifest.getMainAttributes().getValue("Mojo-Class");
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to extract Manifest attributes", e);
+ return false;
+ }
+
+ if (mojoClass == null) {
+ Log.e(TAG, "Mojo-Class class not found");
+ return false;
+ }
+
+ Core core = CoreImpl.getInstance();
+ MessagePipeHandle handle =
+ core.acquireNativeHandle(applicationRequestHandle).toMessagePipeHandle();
+ try {
+ Class<?> loadedClass = bootstrapLoader.loadClass(mojoClass);
+ Method mojoMain =
+ loadedClass.getMethod("mojoMain", Context.class, Core.class,
+ MessagePipeHandle.class);
+ mojoMain.invoke(null, context, core, handle);
+ } catch (Throwable t) {
+ Log.e(TAG, "Running MojoMain failed.", t);
+ return false;
+ }
+ } finally {
+ clearTemporaryFiles(context, application_java_library);
+ }
+ return true;
+ }
+
+ private static File getDexOutputDir(Context context) {
+ return context.getDir(DEX_OUTPUT_DIRECTORY, Context.MODE_PRIVATE);
+ }
+
+ private static File getAppDir(Context context) {
+ return context.getDir(APP_DIRECTORY, Context.MODE_PRIVATE);
+ }
+}
« no previous file with comments | « services/android/BUILD.gn ('k') | services/android/java_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698