blob: f6337593f4463853ac5f95e7886a772832a39df5 [file] [log] [blame]
// Copyright 2013 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.mojo.shell;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.mojo.bindings.InterfaceRequest;
import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojo.system.MojoException;
import org.chromium.mojo.system.Pair;
import org.chromium.mojo.system.impl.CoreImpl;
import org.chromium.mojom.mojo.ServiceProvider;
import org.chromium.mojom.mojo.Shell;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A placeholder class to call native functions.
**/
@JNINamespace("shell")
public class ShellMain {
private static final String TAG = "ShellMain";
// Directory where applications bundled with the shell will be extracted.
private static final String LOCAL_APP_DIRECTORY = "local_apps";
// Individual applications bundled with the shell as assets.
private static final String NETWORK_LIBRARY_APP = "network_service.mojo";
// Directory where the child executable will be extracted.
private static final String CHILD_DIRECTORY = "child";
// Directory to set TMPDIR to.
private static final String TMP_DIRECTORY = "tmp";
// Directory to set HOME to.
private static final String HOME_DIRECTORY = "home";
// Name of the child executable.
private static final String MOJO_SHELL_CHILD_EXECUTABLE = "mojo_shell_child";
// Path to the default origin of mojo: apps.
private static final String DEFAULT_ORIGIN = "https://core.mojoapps.io/";
// Name of the default window manager.
private static final String DEFAULT_WM = "mojo:kiosk_wm";
private static class ShellImpl implements Shell {
private static final ShellImpl INSTANCE = new ShellImpl();
/**
* @see Shell#close()
*/
@Override
public void close() {}
/**
* @see Shell#onConnectionError(org.chromium.mojo.system.MojoException)
*/
@Override
public void onConnectionError(MojoException e) {}
/**
* @see Shell#connectToApplication(String, InterfaceRequest, ServiceProvider)
*/
@Override
public void connectToApplication(String applicationUrl,
InterfaceRequest<ServiceProvider> services, ServiceProvider exposedServices) {
int exposedServicesHandle = CoreImpl.INVALID_HANDLE;
if (exposedServices != null) {
if (exposedServices instanceof ServiceProvider.Proxy) {
ServiceProvider.Proxy proxy = (ServiceProvider.Proxy) exposedServices;
exposedServicesHandle =
proxy.getProxyHandler().passHandle().releaseNativeHandle();
} else {
Pair<MessagePipeHandle, MessagePipeHandle> pipes =
CoreImpl.getInstance().createMessagePipe(null);
ServiceProvider.MANAGER.bind(exposedServices, pipes.first);
exposedServicesHandle = pipes.second.releaseNativeHandle();
}
}
nativeConnectToApplication(applicationUrl,
services == null ? CoreImpl.INVALID_HANDLE
: services.passHandle().releaseNativeHandle(),
exposedServicesHandle);
}
}
/**
* A guard flag for calling nativeInit() only once.
**/
private static boolean sInitialized = false;
static boolean isInitialized() {
return sInitialized;
}
/**
* Initializes the native system.
**/
static void ensureInitialized(Context applicationContext, String[] parameters) {
if (sInitialized) return;
try {
FileHelper.extractFromAssets(applicationContext, NETWORK_LIBRARY_APP,
getLocalAppsDir(applicationContext), false);
FileHelper.extractFromAssets(applicationContext, MOJO_SHELL_CHILD_EXECUTABLE,
getChildDir(applicationContext), false);
File mojoShellChild =
new File(getChildDir(applicationContext), MOJO_SHELL_CHILD_EXECUTABLE);
// The shell child executable needs to be ... executable.
mojoShellChild.setExecutable(true, true);
List<String> parametersList = new ArrayList<String>();
parametersList.add("--args-for=mojo:notifications " + R.mipmap.ic_launcher);
// Program name.
if (parameters != null) {
parametersList.addAll(Arrays.asList(parameters));
} else {
// Apply default parameters.
parametersList.add("--origin=" + DEFAULT_ORIGIN);
parametersList.add("--url-mappings=mojo:window_manager=" + DEFAULT_WM);
}
nativeInit(applicationContext, mojoShellChild.getAbsolutePath(),
parametersList.toArray(new String[parametersList.size()]),
getLocalAppsDir(applicationContext).getAbsolutePath(),
getTmpDir(applicationContext).getAbsolutePath(),
getHomeDir(applicationContext).getAbsolutePath());
sInitialized = true;
} catch (Exception e) {
Log.e(TAG, "ShellMain initialization failed.", e);
throw new RuntimeException(e);
}
start();
}
/**
* Starts the specified application in the specified context.
*
* @return <code>true</code> if an application has been launched.
**/
static boolean start() {
return nativeStart();
}
/**
* Adds the given URL to the set of mojo applications to run on start.
*/
static void addApplicationURL(String url) {
nativeAddApplicationURL(url);
}
/**
* Starts this application in an already-initialized shell.
*/
static void startApplicationURL(String url) {
nativeStartApplicationURL(url);
}
/**
* Returns an instance of the shell interface that allows to interact with mojo applications.
*/
static Shell getShell() {
return ShellImpl.INSTANCE;
}
private static File getLocalAppsDir(Context context) {
return context.getDir(LOCAL_APP_DIRECTORY, Context.MODE_PRIVATE);
}
private static File getChildDir(Context context) {
return context.getDir(CHILD_DIRECTORY, Context.MODE_PRIVATE);
}
private static File getTmpDir(Context context) {
return new File(context.getCacheDir(), TMP_DIRECTORY);
}
private static File getHomeDir(Context context) {
return context.getDir(HOME_DIRECTORY, Context.MODE_PRIVATE);
}
@CalledByNative
private static void finishActivity(Activity activity) {
activity.finish();
}
/**
* Initializes the native system. This API should be called only once per process.
**/
private static native void nativeInit(Context context, String mojoShellChildPath,
String[] parameters, String bundledAppsDirectory, String tmpDir, String homeDir);
private static native boolean nativeStart();
private static native void nativeAddApplicationURL(String url);
private static native void nativeStartApplicationURL(String url);
private static native void nativeConnectToApplication(
String applicationURL, int servicesHandle, int exposedServicesHandle);
}