Commit c55c0a6c authored by sky's avatar sky Committed by Commit bot

Gets mandoline working on android

This consists of the following pieces:
. html_viewer now uses ResourceProvider to get resources.
. html_viewer no longer directly uses java.
. The java support for mojo_runner/shell has been mode pluggable:
  . You specify the name of the .so to load by way of a meta-tag in
    the manifest. This way mandoline can specify it's own.
  . Android's main function calls to an InitContext() function that
    mandoline plugs in.
  . The apk can include resources to extract. These are listed in the
    file 'assets_list.' The gn template rule
    generate_mojo_shell_assets_list does this for you given a
    directory.
. Changed around scripts to work with both mojo_shell/runner and
  mandoline.

BUG=481698
TEST=covered by tests
R=ben@chromim.org, jcivelli@chromium.org

Review URL: https://codereview.chromium.org/1130763004

Cr-Commit-Position: refs/heads/master@{#329250}
parent 56078ce4
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/module_args/v8.gni")
import("//mojo/mojo_application_package.gni")
import("//testing/test.gni")
import("//third_party/mojo/src/mojo/public/mojo.gni")
......@@ -132,6 +133,8 @@ source_set("lib") {
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/native_theme",
# TODO(sky): we shouldn't be using ui_test_pak.
"//ui/resources:ui_test_pak",
"//url",
]
......@@ -155,71 +158,36 @@ source_set("lib") {
]
}
if (is_android) {
import("//build/config/android/rules.gni")
java_library_path = "$target_out_dir/java_library.dex.jar"
mojo_android_application("html_viewer") {
input_so = "$root_out_dir/lib.stripped/libhtml_viewer_lib.so"
input_dex_jar = java_library_path
}
shared_library("html_viewer_lib") {
sources = [
"android/android_hooks.cc",
"html_viewer.cc",
"ui_setup.h",
"ui_setup_android.cc",
"ui_setup_android.h",
]
deps = [
":html_viewer_jni_headers",
":lib",
"//base",
"//ui/gfx:gfx_jni_headers",
]
data_deps = [ "//mojo/services/network:network" ]
}
generate_jni("html_viewer_jni_headers") {
sources = [
"android/java/org/chromium/html_viewer/Main.java",
]
jni_package = "components/html_viewer"
}
android_library("html_viewer_java_classes") {
java_files = [ "android/java/org/chromium/html_viewer/Main.java" ]
deps = [
"//base:base_java",
]
}
android_standalone_library("java_library") {
dex_path = java_library_path
deps = [
":html_viewer_java_classes",
mojo_application_package("html_viewer") {
sources = [
"html_viewer.cc",
"ui_setup.h",
"ui_setup_android.cc",
"ui_setup_android.h",
]
deps = [
":lib",
"//components/resource_provider/public/cpp",
"//components/resource_provider/public/interfaces",
"//mojo/common",
"//mojo/platform_handle",
"//third_party/icu:icudata",
"//ui/resources:ui_test_pak",
]
data_deps = [
"//mojo/services/network:network",
"//components/resource_provider",
]
resources = [
"$root_out_dir/icudtl.dat",
"$root_out_dir/ui_test.pak",
]
# TODO(sky): this is WAY more than we need. We really only need
# DeviceDisplayInfo. Refactor to make this clearer.
"//ui/android:ui_java",
]
}
} else {
mojo_native_application("html_viewer") {
sources = [
"html_viewer.cc",
]
deps = [
":lib",
"//ui/resources:ui_test_pak",
if (v8_use_external_startup_data) {
resources += [
"$root_build_dir/natives_blob.bin",
"$root_build_dir/snapshot_blob.bin",
]
data_deps = [ "//mojo/services/network:network" ]
}
}
......
......@@ -6,6 +6,7 @@ include_rules = [
"+components/clipboard",
"+components/gpu",
"+components/mime_util",
"+components/resource_provider/public",
"+components/scheduler",
"+components/surfaces",
"+components/view_manager",
......@@ -17,6 +18,7 @@ include_rules = [
"+mojo/cc",
"+mojo/common",
"+mojo/converters/surfaces",
"+mojo/platform_handle",
"+mojo/public",
"+mojo/services/network",
"+net/base",
......
// 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.
#include <vector>
#include "base/android/base_jni_onload.h"
#include "base/android/jni_android.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/bind.h"
#include "components/html_viewer/jni/Main_jni.h"
namespace {
bool RegisterJNI(JNIEnv* env) {
return true;
}
bool Init() {
Java_Main_init(base::android::AttachCurrentThread(),
base::android::GetApplicationContext());
return true;
}
} // namespace
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
std::vector<base::android::RegisterCallback> register_callbacks;
register_callbacks.push_back(base::Bind(&RegisterJNI));
register_callbacks.push_back(base::Bind(&RegisterNativesImpl));
std::vector<base::android::InitCallback> init_callbacks;
init_callbacks.push_back(base::Bind(&Init));
if (!base::android::OnJNIOnLoadRegisterJNI(vm, register_callbacks) ||
!base::android::OnJNIOnLoadInit(init_callbacks)) {
return -1;
}
// There cannot be two AtExitManagers at the same time. Remove the one from
// LibraryLoader as ApplicationRunnerChromium also uses one.
base::android::LibraryLoaderExitHook();
return JNI_VERSION_1_4;
}
extern "C" JNI_EXPORT void InitApplicationContext(
const base::android::JavaRef<jobject>& context) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::InitApplicationContext(env, context);
}
// 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.html_viewer;
import android.content.Context;
import org.chromium.base.CalledByNative;
import org.chromium.base.PathUtils;
/**
* This class does setup for html_viewer.
*/
public final class Main {
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "html_viewer";
private Main() {}
@SuppressWarnings("unused")
@CalledByNative
private static void init(Context context) {
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
}
}
......@@ -14,9 +14,13 @@
#include "components/html_viewer/discardable_memory_allocator.h"
#include "components/html_viewer/html_document.h"
#include "components/html_viewer/web_media_player_factory.h"
#include "components/resource_provider/public/cpp/resource_loader.h"
#include "components/resource_provider/public/interfaces/resource_provider.mojom.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
#include "gin/v8_initializer.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/platform_handle/platform_handle_functions.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
......@@ -48,6 +52,7 @@ using mojo::ShellPtr;
using mojo::String;
using mojo::URLLoaderPtr;
using mojo::URLResponsePtr;
using resource_provider::ResourceLoader;
namespace html_viewer {
......@@ -169,13 +174,32 @@ class HTMLViewer : public mojo::ApplicationDelegate,
public:
HTMLViewer()
: discardable_memory_allocator_(kDesiredMaxMemory),
compositor_thread_("compositor thread") {}
compositor_thread_("compositor thread"),
is_headless_(false) {}
~HTMLViewer() override { blink::shutdown(); }
private:
// Overridden from ApplicationDelegate:
void Initialize(mojo::ApplicationImpl* app) override {
// TODO(sky): make this typesafe and not leak.
std::set<std::string> paths;
paths.insert("icudtl.dat");
paths.insert("ui_test.pak");
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
paths.insert("natives_blob.bin");
paths.insert("snapshot_blob.bin");
#endif
ResourceLoader resource_loader(app->shell(), paths);
if (!resource_loader.BlockUntilLoaded()) {
// Assume on error we're being shut down.
LOG(WARNING) << "html_viewer errored getting resources, exiting";
mojo::ApplicationImpl::Terminate();
return;
}
ResourceLoader::ResourceMap resource_map(resource_loader.resource_map());
ui_setup_.reset(new UISetup);
base::DiscardableMemoryAllocator::SetInstance(
&discardable_memory_allocator_);
......@@ -185,10 +209,13 @@ class HTMLViewer : public mojo::ApplicationDelegate,
new BlinkPlatformImpl(app, renderer_scheduler_.get()));
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
// Note: this requires file system access.
gin::V8Initializer::LoadV8Snapshot();
CHECK(gin::V8Initializer::LoadV8SnapshotFromFD(
resource_map["natives_blob.bin"], 0u, 0u,
resource_map["snapshot_blob.bin"], 0u, 0u));
#endif
blink::initialize(blink_platform_.get());
base::i18n::InitializeICU();
base::i18n::InitializeICUWithFileDescriptor(
resource_map["icudtl.dat"], base::MemoryMappedFile::Region::kWholeFile);
ui::RegisterPathProvider();
......@@ -205,11 +232,14 @@ class HTMLViewer : public mojo::ApplicationDelegate,
is_headless_ = command_line->HasSwitch(kIsHeadless);
if (!is_headless_) {
// TODO(sky): consider putting this into the .so so that we don't need
// file system access.
base::FilePath ui_test_pak_path;
CHECK(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
// TODO(sky): fix lifetime here.
MojoPlatformHandle platform_handle = resource_map["ui_test.pak"];
// TODO(sky): the first call should be for strings, not images.
ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
base::File(platform_handle).Pass(),
base::MemoryMappedFile::Region::kWholeFile);
ui::ResourceBundle::GetSharedInstance().AddDataPackFromFile(
base::File(platform_handle).Pass(), ui::SCALE_FACTOR_100P);
}
compositor_thread_.Start();
......
......@@ -7,8 +7,9 @@ assert(is_android)
import("//third_party/mojo/src/mojo/public/mojo.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//mojo/generate_mojo_shell_assets_list.gni")
mojo_runner_assets_dir = "$root_build_dir/mojo_runner_assets"
mandoline_assets_dir = "$root_build_dir/mandoline_assets"
group("android") {
deps = [
......@@ -16,18 +17,74 @@ group("android") {
]
}
executable("mandoline_runner") {
deps = [
"//mojo/common",
"//mojo/environment:chromium",
"//mojo/runner:mojo_runner_lib",
]
sources = [
"../core_services_initialization.cc",
"mandoline_context_init.cc",
]
# On android, the executable is also the native library used by the apk.
# It means dynamic symbols must be preserved and exported.
ldflags = [ "-Wl,--export-dynamic" ]
}
copy("copy_mandoline_runner") {
deps = [
":mandoline_runner",
]
sources = [
"$root_out_dir/exe.stripped/mandoline_runner",
]
outputs = [
"$root_out_dir/lib.stripped/libmandoline_runner.so",
]
}
copy_ex("copy_mandoline_assets") {
clear_dir = true
dest = mandoline_assets_dir
deps = [
"//components/html_viewer",
"//components/resource_provider",
"//components/surfaces",
"//mandoline/services/core_services",
]
sources = [
"$root_out_dir/core_services.mojo",
"$root_out_dir/html_viewer",
"$root_out_dir/lib.stripped/libbootstrap.so",
"$root_out_dir/network_service.mojo",
"$root_out_dir/obj/mojo/runner/bootstrap_java.dex.jar",
"$root_out_dir/resource_provider.mojo",
"$root_out_dir/surfaces_service.mojo",
]
}
generate_mojo_shell_assets_list("build_mandoline_assets") {
deps = [
":copy_mandoline_assets",
]
dir = mandoline_assets_dir
}
android_apk("mandoline_apk") {
apk_name = "Mandoline"
android_manifest = "apk/AndroidManifest.xml"
native_libs = [ "libmojo_runner.so" ]
native_libs = [ "libmandoline_runner.so" ]
asset_location = mojo_runner_assets_dir
asset_location = mandoline_assets_dir
deps = [
"//mojo/runner:copy_mojo_runner",
"//mojo/runner:copy_mojo_runner_assets",
":build_mandoline_assets",
":copy_mandoline_runner",
"//mojo/runner:java",
"//mojo/runner:resources",
"//base:base_java",
......
......@@ -13,11 +13,13 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application android:name="MojoShellApplication"
<application android:name="org.chromium.mojo.shell.MojoShellApplication"
android:label="Mandoline">
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity android:name="MojoShellActivity"
<meta-data android:name="mojo_lib"
android:value="libmandoline_runner.so" />
<activity android:name="org.chromium.mojo.shell.MojoShellActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
......
// 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.
#include "base/logging.h"
#include "mandoline/app/core_services_initialization.h"
namespace mojo {
namespace runner {
void InitContext(Context* context) {
mandoline::InitCoreServicesForContext(context);
}
} // namespace runner
} // namespace mojo
......@@ -29,7 +29,6 @@ def main():
dest='debug', action='store_false')
parser.add_argument('--target-cpu', help='CPU architecture to run for.',
choices=['x64', 'x86', 'arm'])
parser.add_argument('--origin', help='Origin for mojo: URLs.')
parser.add_argument('--target-device', help='Device to run on.')
launcher_args, args = parser.parse_known_args()
......@@ -39,9 +38,10 @@ def main():
apk_name="Mandoline.apk")
paths = Paths(config)
shell = AndroidShell(paths.target_mojo_shell_path, paths.build_dir,
paths.adb_path, launcher_args.target_device)
paths.adb_path, launcher_args.target_device,
target_package='org.chromium.mandoline')
extra_shell_args = shell.PrepareShellRun(launcher_args.origin)
extra_shell_args = shell.PrepareShellRun()
args.extend(extra_shell_args)
shell.CleanLogs()
......
# 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.
# Used to generate an assets_list file. To use supply the argument 'dir', which
# is where the assets can be found.
# TODO(sky): Perhaps combine this with the copy step?
template("generate_mojo_shell_assets_list") {
action(target_name) {
script = "//mojo/tools/generate_mojo_shell_assets_list.py"
args = [
"--dir",
rebase_path(invoker.dir, root_build_dir),
]
outputs = [
invoker.dir + "/assets_list",
]
if (defined(invoker.deps)) {
deps = invoker.deps
}
}
}
......@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//build/config/ui.gni")
import("//mojo/generate_mojo_shell_assets_list.gni")
import("//third_party/mojo/src/mojo/public/mojo.gni")
import("//third_party/mojo/src/mojo/public/mojo_application.gni")
import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni")
......@@ -29,7 +30,7 @@ if (is_android) {
import("//build/config/android/rules.gni")
}
executable("mojo_runner") {
source_set("mojo_runner_lib") {
sources = []
deps = [
......@@ -48,15 +49,12 @@ executable("mojo_runner") {
]
} else {
sources += [
"android/context_init.h",
"android/library_loader.cc",
"android/main.cc",
"android/main.h",
]
# On android, the executable is also the native library used by the apk.
# It means dynamic symbols must be preserved and exported.
ldflags = [ "-Wl,--export-dynamic" ]
deps += [
":jni_headers",
"//components/native_viewport:lib",
......@@ -66,6 +64,22 @@ executable("mojo_runner") {
}
}
executable("mojo_runner") {
deps = [
":mojo_runner_lib",
]
if (is_android) {
sources = [
"android/context_init.cc",
]
# On android, the executable is also the native library used by the apk.
# It means dynamic symbols must be preserved and exported.
ldflags = [ "-Wl,--export-dynamic" ]
}
}
source_set("in_process_native_runner") {
sources = [
"in_process_native_runner.cc",
......@@ -250,6 +264,7 @@ if (is_android) {
]
deps = [
":resources",
"//base:base_java",
]
}
......@@ -265,6 +280,9 @@ if (is_android) {
copy_ex("copy_mojo_runner_assets") {
clear_dir = true
dest = mojo_runner_assets_dir
deps = [
":copy_mojo_runner",
]
sources = [
"$root_out_dir/lib.stripped/libbootstrap.so",
"$root_out_dir/network_service.mojo",
......@@ -272,6 +290,13 @@ if (is_android) {
]
}
generate_mojo_shell_assets_list("build_mojo_runner_assets") {
deps = [
":copy_mojo_runner_assets",
]
dir = mojo_runner_assets_dir
}
copy("copy_mojo_runner") {
sources = [
"$root_out_dir/exe.stripped/mojo_runner",
......@@ -300,8 +325,7 @@ if (is_android) {
asset_location = mojo_runner_assets_dir
deps = [
":copy_mojo_runner",
":copy_mojo_runner_assets",
":build_mojo_runner_assets",
":java",
":resources",
"//base:base_java",
......@@ -310,6 +334,13 @@ if (is_android) {
]
}
generate_mojo_shell_assets_list("build_mojo_runner_test_assets") {
deps = [
":copy_mojo_runner_test_assets",
]
dir = mojo_runner_test_assets_dir
}
android_library("mojo_runner_tests_java") {
java_files =
[ "android/tests/src/org/chromium/mojo/shell/ShellTestBase.java" ]
......@@ -374,7 +405,7 @@ test("tests") {
deps += [ ":jni_headers" ]
apk_deps = [
":copy_mojo_runner_test_assets",
":build_mojo_runner_test_assets",
":mojo_runner_tests_java",
]
......
......@@ -17,6 +17,8 @@
android:label="Mojo Shell">
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data android:name="mojo_lib"
android:value="libmojo_runner.so" />
<activity android:name="MojoShellActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
......
......@@ -101,6 +101,7 @@ class FileHelper {
if (outputFile.exists()) {
return outputFile;
}
outputFile.getParentFile().mkdirs();
}
BufferedInputStream inputStream = new BufferedInputStream(
......
......@@ -11,7 +11,11 @@ import android.util.Log;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
......@@ -25,25 +29,52 @@ public class 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";
// The mojo_shell library is also an executable run in forked processes when running
// multi-process.
private static final String MOJO_SHELL_EXECUTABLE = "libmojo_runner.so";
// Name of the file containing the assets to extract. File format is a file per line.
private static final String ASSETS_LIST_NAME = "assets_list";
/**
* A guard flag for calling nativeInit() only once.
**/
private static boolean sInitialized = false;
/**
* Returns the names of the assets in ASSETS_LIST_NAME.
*/
private static List<String> getAssetsList(Context context) throws IOException {
List<String> results = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(
context.getAssets().open(ASSETS_LIST_NAME), Charset.forName("UTF-8")));
try {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
// These two are read by the system and don't need to be extracted.
if (!line.isEmpty() && !line.equals("bootstrap_java.dex.jar")
&& !line.equals("libbootstrap.so")) {
results.add(line);
}
}
} finally {
reader.close();
}
return results;
}
/**
* Initializes the native system.
**/
static void ensureInitialized(Context applicationContext, String[] parameters) {
if (sInitialized) return;
File localAppsDir = getLocalAppsDir(applicationContext);
try {
FileHelper.extractFromAssets(applicationContext, NETWORK_LIBRARY_APP,
getLocalAppsDir(applicationContext), false);
for (String assetPath : getAssetsList(applicationContext)) {
FileHelper.extractFromAssets(applicationContext, assetPath, localAppsDir, false);
}
File mojoShell = new File(applicationContext.getApplicationInfo().nativeLibraryDir,
MOJO_SHELL_EXECUTABLE);
......@@ -55,7 +86,7 @@ public class ShellMain {
nativeInit(applicationContext, mojoShell.getAbsolutePath(),
parametersList.toArray(new String[parametersList.size()]),
getLocalAppsDir(applicationContext).getAbsolutePath(),
localAppsDir.getAbsolutePath(),
getTmpDir(applicationContext).getAbsolutePath());
sInitialized = true;
} catch (Exception e) {
......
// 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.
#include "mojo/runner/android/context_init.h"
namespace mojo {
namespace runner {
void InitContext(Context* context) {
}
} // namespace runner
} // namespace mojo
// 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.
#ifndef MOJO_RUNNER_ANDROID_CONTEXT_INIT_H_
#define MOJO_RUNNER_ANDROID_CONTEXT_INIT_H_
namespace mojo {
namespace runner {
class Context;
// Any Context specific initialization goes here.
void InitContext(Context* context);
} // namespace runner
} // namespace mojo
#endif // MOJO_RUNNER_ANDROID_CONTEXT_INIT_H_
......@@ -23,6 +23,7 @@
#include "mojo/common/message_pump_mojo.h"
#include "mojo/runner/android/android_handler_loader.h"
#include "mojo/runner/android/background_application_loader.h"
#include "mojo/runner/android/context_init.h"
#include "mojo/runner/android/native_viewport_application_loader.h"
#include "mojo/runner/android/ui_application_loader_android.h"
#include "mojo/runner/context.h"
......@@ -166,6 +167,7 @@ static void Init(JNIEnv* env,
Context* shell_context = new Context();
shell_context->SetShellFileRoot(base::FilePath(
base::android::ConvertJavaStringToUTF8(env, j_local_apps_directory)));
InitContext(shell_context);
g_context.Get().reset(shell_context);
g_java_message_loop.Get().reset(new base::MessageLoopForUI);
......
#!/usr/bin/env python
#
# 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.
"""Generates the assets_list file from a directory."""
import argparse
import os
import sys
def main():
parser = argparse.ArgumentParser(usage="--dir <directory>")
parser.add_argument('--dir', help='Directory read files from.', required=True)
options, _ = parser.parse_known_args()
if not os.path.exists(options.dir) or not os.path.isdir(options.dir):
print 'Directory does not exist, or path is not a directory', options.dir
return -1
root_dir = os.path.abspath(options.dir)
all_files = []
for current_root, _, files in os.walk(options.dir):
current_root_absolute = os.path.abspath(current_root)
if len(current_root_absolute) < len(root_dir):
print 'unexpected directory', current_root_absolute
return -1
rel_root = current_root_absolute[len(root_dir):]
if len(rel_root) and rel_root.startswith(os.sep):
rel_root = rel_root[len(os.sep):]
if len(rel_root) and not rel_root.endswith(os.sep):
rel_root += os.sep
all_files.extend([rel_root + f for f in files])
with open(os.path.join(options.dir, 'assets_list'), 'w') as f:
for a_file in all_files:
f.write(a_file + '\n')
return 0
if __name__ == '__main__':
sys.exit(main())
......@@ -191,11 +191,13 @@ class AndroidShell(object):
target_device: device to run on, if multiple devices are connected
"""
def __init__(
self, shell_apk_path, local_dir=None, adb_path="adb", target_device=None):
self, shell_apk_path, local_dir=None, adb_path="adb", target_device=None,
target_package=MOJO_SHELL_PACKAGE_NAME):
self.shell_apk_path = shell_apk_path
self.adb_path = adb_path
self.local_dir = local_dir
self.target_device = target_device
self.target_package = target_package
def _CreateADBCommand(self, args):
adb_command = [self.adb_path]
......@@ -325,13 +327,14 @@ class AndroidShell(object):
raise Exception("Unable to run adb as root.")
subprocess.check_call(
self._CreateADBCommand(['install', '-r', self.shell_apk_path, '-i',
MOJO_SHELL_PACKAGE_NAME]))
self.target_package]))
atexit.register(self.StopShell)
extra_shell_args = []
origin_url = origin if origin else self._StartHttpServerForDirectory(
self.local_dir, DEFAULT_BASE_PORT if fixed_port else 0)
extra_shell_args.append("--origin=" + origin_url)
if origin:
origin_url = origin if origin else self._StartHttpServerForDirectory(
self.local_dir, DEFAULT_BASE_PORT if fixed_port else 0)
extra_shell_args.append("--origin=" + origin_url)
return extra_shell_args
......@@ -346,7 +349,7 @@ class AndroidShell(object):
The |arguments| list must contain the "--origin=" arg from PrepareShellRun.
If |stdout| is not None, it should be a valid argument for subprocess.Popen.
"""
STDOUT_PIPE = "/data/data/%s/stdout.fifo" % MOJO_SHELL_PACKAGE_NAME
STDOUT_PIPE = "/data/data/%s/stdout.fifo" % self.target_package
cmd = self._CreateADBCommand([
'shell',
......@@ -354,16 +357,15 @@ class AndroidShell(object):
'start',
'-S',
'-a', 'android.intent.action.VIEW',
'-n', '%s/.MojoShellActivity' % MOJO_SHELL_PACKAGE_NAME])
'-n', '%s/%s.MojoShellActivity' % (self.target_package,
MOJO_SHELL_PACKAGE_NAME)])
parameters = []
if stdout or on_application_stop:
subprocess.check_call(self._CreateADBCommand(
['shell', 'rm', STDOUT_PIPE]))
['shell', 'rm', '-f', STDOUT_PIPE]))
parameters.append('--fifo-path=%s' % STDOUT_PIPE)
self._ReadFifo(STDOUT_PIPE, stdout, on_application_stop)
# The origin has to be specified whether it's local or external.
assert any("--origin=" in arg for arg in arguments)
# Extract map-origin arguments.
map_parameters, other_parameters = _Split(arguments, _IsMapOrigin)
......@@ -385,7 +387,7 @@ class AndroidShell(object):
subprocess.check_call(self._CreateADBCommand(['shell',
'am',
'force-stop',
MOJO_SHELL_PACKAGE_NAME]))
self.target_package]))
def CleanLogs(self):
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment