diff options
author | ben <ben@chromium.org> | 2015-04-27 14:52:57 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-27 21:52:56 +0000 |
commit | ee05293936b654dfbc42889ba374bba21bd5c453 (patch) | |
tree | de694f31a0a2f21e60750a9b92902127f08293fc /mojo/shell | |
parent | 9cfdfc07ef3042e059d5a51a91cbe4f13cfca341 (diff) | |
download | chromium_src-ee05293936b654dfbc42889ba374bba21bd5c453.zip chromium_src-ee05293936b654dfbc42889ba374bba21bd5c453.tar.gz chromium_src-ee05293936b654dfbc42889ba374bba21bd5c453.tar.bz2 |
Separate mojo/shell into a runner and the application manager (shell)
R=sky@chromium.org
BUG=
Review URL: https://codereview.chromium.org/1091513005
Cr-Commit-Position: refs/heads/master@{#327148}
Diffstat (limited to 'mojo/shell')
90 files changed, 97 insertions, 5586 deletions
diff --git a/mojo/shell/BUILD.gn b/mojo/shell/BUILD.gn index 38b8639f..5a13e6b 100644 --- a/mojo/shell/BUILD.gn +++ b/mojo/shell/BUILD.gn @@ -2,334 +2,49 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/ui.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") import("//testing/test.gni") -# We don't support building in the component build since mojo apps are -# inherently components. -assert(!is_component_build) - -group("shell") { - testonly = true - - deps = [ - ":mojo_shell", - ":tests", - "//mojo/shell/application_manager:tests", - ] - - if (is_android) { - deps += [ - ":mojo_shell_apk", - ":tests_apk", - ] - } -} - -if (is_android) { - import("//build/config/android/config.gni") - import("//build/config/android/rules.gni") -} - -executable("mojo_shell") { - sources = [] - - deps = [ - ":lib", - "//base", - "//build/config/sanitizers:deps", - "//mojo/common", - "//mojo/environment:chromium", - ] - - if (!is_android) { - sources += [ - "desktop/launcher_process.cc", - "desktop/launcher_process.h", - "desktop/main.cc", - ] - } else { - sources += [ - "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", - "//mojo/shell/application_manager", - "//ui/gl", - ] - } -} - -source_set("in_process_native_runner") { +source_set("shell") { + output_name = "mojo_shell" sources = [ - "in_process_native_runner.cc", - "in_process_native_runner.h", + "application_loader.h", + "application_manager.cc", + "application_manager.h", + "data_pipe_peek.cc", + "data_pipe_peek.h", + "fetcher.cc", + "fetcher.h", + "identity.cc", + "identity.h", + "local_fetcher.cc", + "local_fetcher.h", + "native_runner.h", + "network_fetcher.cc", + "network_fetcher.h", + "query_util.cc", + "query_util.h", + "shell_impl.cc", + "shell_impl.h", + "switches.cc", + "switches.h", ] public_deps = [ - ":native_application_support", - "//mojo/shell/application_manager", - ] - - deps = [ - "//base", - ] -} - -source_set("lib") { - sources = [ - "child_process.cc", - "child_process.h", - "child_process_host.cc", - "child_process_host.h", - "context.cc", - "context.h", - "filename_util.cc", - "filename_util.h", - "init.cc", - "init.h", - "out_of_process_native_runner.cc", - "out_of_process_native_runner.h", - "task_runners.cc", - "task_runners.h", - "url_resolver.cc", - "url_resolver.h", - ] - - deps = [ - ":child_process_bindings", - ":in_process_native_runner", - ":native_application_support", "//base", - "//base/third_party/dynamic_annotations", - "//base:base_static", - "//mojo/application", "//mojo/common", - "//mojo/common:tracing_impl", - "//third_party/mojo/src/mojo/edk/system", - "//third_party/mojo/src/mojo/public/cpp/bindings", - "//third_party/mojo/src/mojo/public/interfaces/application", + "//third_party/mojo/src/mojo/public/interfaces/application:application", "//mojo/services/network/public/interfaces", - "//mojo/shell/application_manager", - "//mojo/services/tracing:bindings", - "//ui/gl", "//url", ] - - public_deps = [ - ":switches", - ] - - if (is_android) { - sources += [ - "android/android_handler.cc", - "android/android_handler.h", - "android/android_handler_loader.cc", - "android/android_handler_loader.h", - "android/background_application_loader.cc", - "android/background_application_loader.h", - "android/native_viewport_application_loader.cc", - "android/native_viewport_application_loader.h", - "android/ui_application_loader_android.cc", - "android/ui_application_loader_android.h", - ] - - deps += [ - ":jni_headers", - ":run_android_application_function", - "//components/gles2", - "//components/native_viewport:lib", - "//mojo/application:content_handler", - ] - } - - # This target includes some files behind #ifdef OS... guards. Since gn is not - # smart enough to understand preprocess includes, it does complains about - # these includes when not using the build files for that OS. Suppress checking - # so we can enable checking for the rest of the targets in this file. - # TODO: Might be better to split the files with OS-specific includes out to a - # separate source_set so we can leave checking on for the rest of the target. - check_includes = false -} - -source_set("native_application_support") { - sources = [ - "native_application_support.cc", - "native_application_support.h", - ] - - public_deps = [ - "//third_party/mojo/src/mojo/public/cpp/bindings", - ] - deps = [ - "//base", - "//mojo/gles2", - ] - - # This target has to include the public thunk headers, which generally - # shouldn't be included without picking an implementation. We are providing - # the implementation but the thunk header target cannot declare that we are - # permitted to include it since it's in the public SDK and we are not. - # Suppress include checking so we can still check the rest of the targets in - # this file. - check_includes = false -} - -source_set("switches") { - sources = [ - "switches.cc", - "switches.h", - ] - - deps = [ - "//base", - ] -} - -if (is_android) { - generate_jni("jni_headers") { - sources = [ - "android/apk/src/org/chromium/mojo/shell/AndroidHandler.java", - "android/apk/src/org/chromium/mojo/shell/Bootstrap.java", - "android/apk/src/org/chromium/mojo/shell/ShellMain.java", - "android/tests/src/org/chromium/mojo/shell/ShellTestBase.java", - ] - jni_package = "mojo/shell" - } - - android_library("bootstrap_java") { - java_files = [ "android/apk/src/org/chromium/mojo/shell/Bootstrap.java" ] - - deps = [ - "//base:base_java", - ] - - dex_path = "$target_out_dir/bootstrap_java.dex.jar" - } - - shared_library("bootstrap") { - sources = [ - "android/bootstrap.cc", - ] - deps = [ - ":jni_headers", - ":lib", - ":run_android_application_function", - "//base", - ] - } - - # Shared header between the bootstrap and the main shell .so. - source_set("run_android_application_function") { - sources = [ - "android/run_android_application_function.h", - ] - - deps = [ - "//base", - ] - } - - android_library("java") { - java_files = [ - "android/apk/src/org/chromium/mojo/shell/AndroidHandler.java", - "android/apk/src/org/chromium/mojo/shell/FileHelper.java", - "android/apk/src/org/chromium/mojo/shell/MojoShellActivity.java", - "android/apk/src/org/chromium/mojo/shell/MojoShellApplication.java", - "android/apk/src/org/chromium/mojo/shell/ShellMain.java", - ] - - deps = [ - "//base:base_java", - ] - } - - android_resources("resources") { - resource_dirs = [ "android/apk/res" ] - custom_package = "org.chromium.mojo.shell" - } - - mojo_shell_assets_dir = "$root_build_dir/mojo_shell_assets" - mojo_shell_test_assets_dir = "$root_build_dir/mojo_shell_test_assets" - - copy_ex("copy_mojo_shell_assets") { - clear_dir = true - dest = mojo_shell_assets_dir - sources = [ - "$root_out_dir/lib.stripped/libbootstrap.so", - "$root_out_dir/network_service.mojo", - "$root_out_dir/obj/mojo/shell/bootstrap_java.dex.jar", - ] - } - - copy("copy_mojo_shell") { - sources = [ - "$root_out_dir/exe.stripped/mojo_shell", - ] - outputs = [ - "$root_out_dir/lib.stripped/libmojo_shell.so", - ] - } - - copy_ex("copy_mojo_shell_test_assets") { - clear_dir = true - dest = mojo_shell_test_assets_dir - sources = [ - "$root_out_dir/test_app.mojo", - "$root_out_dir/test_request_tracker_app.mojo", - ] - } - - android_apk("mojo_shell_apk") { - apk_name = "MojoShell" - - android_manifest = "android/apk/AndroidManifest.xml" - - native_libs = [ "libmojo_shell.so" ] - - asset_location = mojo_shell_assets_dir - - deps = [ - ":copy_mojo_shell", - ":copy_mojo_shell_assets", - ":java", - ":resources", - "//base:base_java", - "//components/native_viewport:native_viewport_java", - "//third_party/android_tools:google_play_services_default_resources", - ] - } - - android_library("mojo_shell_tests_java") { - java_files = - [ "android/tests/src/org/chromium/mojo/shell/ShellTestBase.java" ] - - deps = [ - ":java", - "//base:base_java", - ] - } -} - -mojom("child_process_bindings") { - sources = [ - "child_process.mojom", - ] - - deps = [ - "//third_party/mojo/src/mojo/public/interfaces/application", + "//base/third_party/dynamic_annotations", + "//crypto:crypto", + "//url", + "//third_party/mojo/src/mojo/edk/system", + "//mojo/environment:chromium", + "//third_party/mojo_services/src/content_handler/public/interfaces", + "//mojo/runner:native_application_support", ] } @@ -337,77 +52,27 @@ test("tests") { output_name = "mojo_shell_unittests" sources = [ - "child_process_host_unittest.cc", - "data_pipe_peek_unittest.cc", - "in_process_native_runner_unittest.cc", - "native_runner_unittest.cc", - "shell_test_base.cc", - "shell_test_base.h", - "shell_test_base_android.cc", - "shell_test_base_unittest.cc", - "shell_test_main.cc", - "url_resolver_unittest.cc", + "application_manager_unittest.cc", + "query_util_unittest.cc", ] deps = [ - ":in_process_native_runner", - ":lib", + ":shell", + ":test_bindings", "//base", - "//base:i18n", - "//base/test:test_support", - "//testing/gtest", - "//url", + "//mojo/application", "//mojo/common", - "//third_party/mojo/src/mojo/edk/system", + "//third_party/mojo/src/mojo/edk/test:run_all_unittests", "//mojo/environment:chromium", + "//third_party/mojo/src/mojo/public/cpp/application", "//third_party/mojo/src/mojo/public/cpp/bindings", - "//mojo/services/test_service:bindings", - "//mojo/shell/application_manager", - ] - - datadeps = [ - "//mojo/services/test_service:test_app", - "//mojo/services/test_service:test_request_tracker_app", + "//testing/gtest", + "//url", ] - - if (is_android) { - sources += [ "android/background_application_loader_unittest.cc" ] - - deps += [ ":jni_headers" ] - - apk_deps = [ - ":copy_mojo_shell_test_assets", - ":mojo_shell_tests_java", - ] - - apk_asset_location = mojo_shell_test_assets_dir - } } -mojo_native_application("apptests") { - output_name = "shell_apptests" - - testonly = true - +mojom("test_bindings") { sources = [ - # TODO(jam): needs http_server service. - #"shell_apptest.cc", - ] - - deps = [ - "//base", - "//mojo/application", - "//mojo/application:test_support", - "//mojo/common:common", - "//third_party/mojo/src/mojo/public/cpp/bindings:callback", - "//third_party/mojo/src/mojo/public/cpp/environment", - "//third_party/mojo/src/mojo/public/cpp/system:system", - - #"//mojo/services/http_server/public/cpp", - #"//mojo/services/http_server/public/interfaces", - "//mojo/services/network/public/interfaces", - "//mojo/shell/test:bindings", + "test.mojom", ] - - #data_deps = [ "//services/http_server:http_server($default_toolchain)" ] } diff --git a/mojo/shell/DEPS b/mojo/shell/DEPS index eae3273..7014b6f 100644 --- a/mojo/shell/DEPS +++ b/mojo/shell/DEPS @@ -1,9 +1,4 @@ include_rules = [ - "+components/gles2", - "+components/gpu", - "+components/native_viewport", "+crypto", - "+jni", - "+third_party/mojo_services", - "+ui", + "+third_party/mojo_services/src/content_handler/public/interfaces", ] diff --git a/mojo/shell/PRESUBMIT.py b/mojo/shell/PRESUBMIT.py deleted file mode 100644 index fb19030..0000000 --- a/mojo/shell/PRESUBMIT.py +++ /dev/null @@ -1,16 +0,0 @@ -# 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. - -"""Presubmit script for shell. - -See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts -for more details about the presubmit API built into depot_tools. -""" - -def CheckChangeOnUpload(input_api, output_api): - results = [] - results += input_api.canned_checks.CheckChangeHasOnlyOneEol(input_api, - output_api) - results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api) - return results diff --git a/mojo/shell/android/android_handler.cc b/mojo/shell/android/android_handler.cc deleted file mode 100644 index 383dc72..0000000 --- a/mojo/shell/android/android_handler.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2014 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/shell/android/android_handler.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/scoped_native_library.h" -#include "jni/AndroidHandler_jni.h" -#include "mojo/common/data_pipe_utils.h" -#include "mojo/public/c/system/main.h" -#include "mojo/public/cpp/application/application_impl.h" -#include "mojo/shell/android/run_android_application_function.h" -#include "mojo/shell/native_application_support.h" - -using base::android::AttachCurrentThread; -using base::android::ScopedJavaLocalRef; -using base::android::ConvertJavaStringToUTF8; -using base::android::ConvertUTF8ToJavaString; -using base::android::GetApplicationContext; - -namespace mojo { -namespace shell { - -namespace { - -// This function loads the application library, sets the application context and -// thunks and calls into the application MojoMain. To ensure that the thunks are -// set correctly we keep it in the Mojo shell .so and pass the function pointer -// to the helper libbootstrap.so. -void RunAndroidApplication(JNIEnv* env, - jobject j_context, - const base::FilePath& app_path, - jint j_handle) { - InterfaceRequest<Application> application_request = - MakeRequest<Application>(MakeScopedHandle(MessagePipeHandle(j_handle))); - - // Load the library, so that we can set the application context there if - // needed. - // TODO(vtl): We'd use a ScopedNativeLibrary, but it doesn't have .get()! - base::NativeLibrary app_library = - LoadNativeApplication(app_path, NativeApplicationCleanup::DELETE); - if (!app_library) - return; - - // Set the application context if needed. Most applications will need to - // access the Android ApplicationContext in which they are run. If the - // application library exports the InitApplicationContext function, we will - // set it there. - const char* init_application_context_name = "InitApplicationContext"; - typedef void (*InitApplicationContextFn)( - const base::android::JavaRef<jobject>&); - InitApplicationContextFn init_application_context = - reinterpret_cast<InitApplicationContextFn>( - base::GetFunctionPointerFromNativeLibrary( - app_library, init_application_context_name)); - if (init_application_context) { - base::android::ScopedJavaLocalRef<jobject> scoped_context(env, j_context); - init_application_context(scoped_context); - } - - // Run the application. - RunNativeApplication(app_library, application_request.Pass()); - // TODO(vtl): See note about unloading and thread-local destructors above - // declaration of |LoadNativeApplication()|. - base::UnloadNativeLibrary(app_library); -} - -} // namespace - -AndroidHandler::AndroidHandler() : content_handler_factory_(this) { -} - -AndroidHandler::~AndroidHandler() { -} - -void AndroidHandler::RunApplication( - InterfaceRequest<Application> application_request, - URLResponsePtr response) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> j_archive_path = - Java_AndroidHandler_getNewTempArchivePath(env, GetApplicationContext()); - base::FilePath archive_path( - ConvertJavaStringToUTF8(env, j_archive_path.obj())); - - common::BlockingCopyToFile(response->body.Pass(), archive_path); - RunAndroidApplicationFn run_android_application_fn = &RunAndroidApplication; - Java_AndroidHandler_bootstrap( - env, GetApplicationContext(), j_archive_path.obj(), - application_request.PassMessagePipe().release().value(), - reinterpret_cast<jlong>(run_android_application_fn)); -} - -void AndroidHandler::Initialize(ApplicationImpl* app) { -} - -bool AndroidHandler::ConfigureIncomingConnection( - ApplicationConnection* connection) { - connection->AddService(&content_handler_factory_); - return true; -} - -bool RegisterAndroidHandlerJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/android/android_handler.h b/mojo/shell/android/android_handler.h deleted file mode 100644 index 868c263..0000000 --- a/mojo/shell/android/android_handler.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2014 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_SHELL_ANDROID_CONTENT_HANDLER_H_ -#define MOJO_SHELL_ANDROID_CONTENT_HANDLER_H_ - -#include <jni.h> - -#include "mojo/application/content_handler_factory.h" -#include "mojo/public/cpp/application/application_delegate.h" -#include "mojo/public/cpp/application/interface_factory_impl.h" -#include "third_party/mojo_services/src/content_handler/public/interfaces/content_handler.mojom.h" - -namespace base { -class FilePath; -} - -namespace mojo { -namespace shell { - -class AndroidHandler : public ApplicationDelegate, - public ContentHandlerFactory::Delegate { - public: - AndroidHandler(); - ~AndroidHandler(); - - private: - // ApplicationDelegate: - void Initialize(ApplicationImpl* app) override; - bool ConfigureIncomingConnection(ApplicationConnection* connection) override; - - // ContentHandlerFactory::Delegate: - void RunApplication(InterfaceRequest<Application> application_request, - URLResponsePtr response) override; - - ContentHandlerFactory content_handler_factory_; - MOJO_DISALLOW_COPY_AND_ASSIGN(AndroidHandler); -}; - -bool RegisterAndroidHandlerJni(JNIEnv* env); - -} // namespace shell -} // namespace mojo - -#endif // MOJO_SHELL_ANDROID_CONTENT_HANDLER_H_ diff --git a/mojo/shell/android/android_handler_loader.cc b/mojo/shell/android/android_handler_loader.cc deleted file mode 100644 index 922dbb5..0000000 --- a/mojo/shell/android/android_handler_loader.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2014 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/shell/android/android_handler_loader.h" - -namespace mojo { -namespace shell { - -AndroidHandlerLoader::AndroidHandlerLoader() { -} - -AndroidHandlerLoader::~AndroidHandlerLoader() { -} - -void AndroidHandlerLoader::Load( - const GURL& url, - InterfaceRequest<Application> application_request) { - DCHECK(application_request.is_pending()); - application_.reset( - new ApplicationImpl(&android_handler_, application_request.Pass())); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/android/android_handler_loader.h b/mojo/shell/android/android_handler_loader.h deleted file mode 100644 index 91592737..0000000 --- a/mojo/shell/android/android_handler_loader.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 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 SHELL_ANDROID_ANDROID_HANDLER_LOADER_H_ -#define SHELL_ANDROID_ANDROID_HANDLER_LOADER_H_ - -#include "base/containers/scoped_ptr_hash_map.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "mojo/public/cpp/application/application_impl.h" -#include "mojo/shell/android/android_handler.h" -#include "mojo/shell/application_manager/application_loader.h" - -namespace mojo { -namespace shell { - -class AndroidHandlerLoader : public ApplicationLoader { - public: - AndroidHandlerLoader(); - virtual ~AndroidHandlerLoader(); - - private: - // ApplicationLoader overrides: - void Load(const GURL& url, - InterfaceRequest<Application> application_request) override; - - AndroidHandler android_handler_; - scoped_ptr<ApplicationImpl> application_; - - DISALLOW_COPY_AND_ASSIGN(AndroidHandlerLoader); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_ANDROID_ANDROID_HANDLER_LOADER_H_ diff --git a/mojo/shell/android/apk/AndroidManifest.xml b/mojo/shell/android/apk/AndroidManifest.xml deleted file mode 100644 index 0d374c9..0000000 --- a/mojo/shell/android/apk/AndroidManifest.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- 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. - --> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.mojo.shell"> - - <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" /> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> - - <application android:name="MojoShellApplication" - android:label="Mojo Shell"> - <meta-data android:name="com.google.android.gms.version" - android:value="@integer/google_play_services_version" /> - <activity android:name="MojoShellActivity" - android:launchMode="singleTask" - android:theme="@android:style/Theme.Holo.Light.NoActionBar" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize" - android:hardwareAccelerated="true"> - <intent-filter> - <action android:name="android.intent.action.VIEW"/> - </intent-filter> - </activity> - </application> - -</manifest> diff --git a/mojo/shell/android/apk/res/values/strings.xml b/mojo/shell/android/apk/res/values/strings.xml deleted file mode 100644 index ff3f8bb..0000000 --- a/mojo/shell/android/apk/res/values/strings.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- 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. - --> - -<resources> -</resources> diff --git a/mojo/shell/android/apk/src/org/chromium/mojo/shell/AndroidHandler.java b/mojo/shell/android/apk/src/org/chromium/mojo/shell/AndroidHandler.java deleted file mode 100644 index 610ff16..0000000 --- a/mojo/shell/android/apk/src/org/chromium/mojo/shell/AndroidHandler.java +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2014 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.content.Context; -import android.util.Log; - -import dalvik.system.DexClassLoader; - -import org.chromium.base.CalledByNative; -import org.chromium.base.JNINamespace; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Constructor; - -/** - * Content handler for archives containing native libraries bundled with Java code. - * <p> - * TODO(ppi): create a seperate instance for each application being bootstrapped to keep track of - * the temporary files and clean them up once the execution finishes. - */ -@JNINamespace("mojo::shell") -public class AndroidHandler { - private static final String TAG = "AndroidHandler"; - - // Bootstrap native and java libraries are packaged with the MojoShell APK as assets. - private static final String BOOTSTRAP_JAVA_LIBRARY = "bootstrap_java.dex.jar"; - private static final String BOOTSTRAP_NATIVE_LIBRARY = "libbootstrap.so"; - // Name of the bootstrapping runnable shipped in the packaged Java library. - private static final String BOOTSTRAP_CLASS = "org.chromium.mojo.shell.Bootstrap"; - - // File extensions used to identify application libraries in the provided archive. - private static final String JAVA_LIBRARY_SUFFIX = ".dex.jar"; - private static final String NATIVE_LIBRARY_SUFFIX = ".so"; - // Filename sections used for naming temporary files holding application files. - private static final String ARCHIVE_PREFIX = "archive"; - private static final String ARCHIVE_SUFFIX = ".zip"; - - // 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 String ASSET_DIRECTORY = "assets"; - - /** - * Deletes directories holding the temporary files. This should be called early on shell startup - * to clean up after the previous run. - */ - static void clearTemporaryFiles(Context context) { - FileHelper.deleteRecursively(getDexOutputDir(context)); - FileHelper.deleteRecursively(getAppDir(context)); - FileHelper.deleteRecursively(getAssetDir(context)); - } - - /** - * Returns the path at which the native part should save the application archive. - */ - @CalledByNative - private static String getNewTempArchivePath(Context context) throws IOException { - return File.createTempFile(ARCHIVE_PREFIX, ARCHIVE_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 handle, - long runApplicationPtr) { - File bootstrap_java_library; - File bootstrap_native_library; - try { - bootstrap_java_library = FileHelper.extractFromAssets(context, BOOTSTRAP_JAVA_LIBRARY, - getAssetDir(context), true); - bootstrap_native_library = FileHelper.extractFromAssets(context, - BOOTSTRAP_NATIVE_LIBRARY, getAssetDir(context), true); - } catch (Exception e) { - Log.e(TAG, "Extraction of bootstrap files from assets failed.", e); - return false; - } - - File application_java_library; - File application_native_library; - try { - File archive = new File(archivePath); - application_java_library = FileHelper.extractFromArchive(archive, JAVA_LIBRARY_SUFFIX, - getAppDir(context)); - application_native_library = FileHelper.extractFromArchive(archive, - NATIVE_LIBRARY_SUFFIX, getAppDir(context)); - } catch (Exception e) { - Log.e(TAG, "Extraction of application files from the archive failed.", e); - return false; - } - - String dexPath = bootstrap_java_library.getAbsolutePath() + File.pathSeparator - + application_java_library.getAbsolutePath(); - DexClassLoader bootstrapLoader = new DexClassLoader(dexPath, - getDexOutputDir(context).getAbsolutePath(), null, - ClassLoader.getSystemClassLoader()); - - try { - Class<?> loadedClass = bootstrapLoader.loadClass(BOOTSTRAP_CLASS); - Class<? extends Runnable> bootstrapClass = loadedClass.asSubclass(Runnable.class); - Constructor<? extends Runnable> constructor = bootstrapClass.getConstructor( - Context.class, File.class, File.class, Integer.class, Long.class); - Runnable bootstrapRunnable = constructor.newInstance(context, bootstrap_native_library, - application_native_library, Integer.valueOf(handle), - Long.valueOf(runApplicationPtr)); - bootstrapRunnable.run(); - } catch (Throwable t) { - Log.e(TAG, "Running Bootstrap failed.", t); - return false; - } - 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); - } - - private static File getAssetDir(Context context) { - return context.getDir(ASSET_DIRECTORY, Context.MODE_PRIVATE); - } -} diff --git a/mojo/shell/android/apk/src/org/chromium/mojo/shell/Bootstrap.java b/mojo/shell/android/apk/src/org/chromium/mojo/shell/Bootstrap.java deleted file mode 100644 index 9916c83..0000000 --- a/mojo/shell/android/apk/src/org/chromium/mojo/shell/Bootstrap.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2014 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.content.Context; - -import org.chromium.base.JNINamespace; - -import java.io.File; - -/** - * Runnable used to bootstrap execution of Android Mojo application. For the JNI to work, we need a - * Java class with the application classloader in the call stack. We load this class in the - * application classloader and call into native from it to achieve that. - */ -@JNINamespace("mojo::shell") -public class Bootstrap implements Runnable { - private final Context mContext; - private final File mBootstrapNativeLibrary; - private final File mApplicationNativeLibrary; - private final int mHandle; - private final long mRunApplicationPtr; - - public Bootstrap(Context context, File bootstrapNativeLibrary, File applicationNativeLibrary, - Integer handle, Long runApplicationPtr) { - mContext = context; - mBootstrapNativeLibrary = bootstrapNativeLibrary; - mApplicationNativeLibrary = applicationNativeLibrary; - mHandle = handle; - mRunApplicationPtr = runApplicationPtr; - } - - @Override - public void run() { - System.load(mBootstrapNativeLibrary.getAbsolutePath()); - System.load(mApplicationNativeLibrary.getAbsolutePath()); - nativeBootstrap(mContext, mApplicationNativeLibrary.getAbsolutePath(), mHandle, - mRunApplicationPtr); - } - - native void nativeBootstrap(Context context, String libraryPath, int handle, - long runApplicationPtr); -} diff --git a/mojo/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java b/mojo/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java deleted file mode 100644 index c455251..0000000 --- a/mojo/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2014 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.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.util.Log; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * Helper methods for file extraction from APK assets and zip archives. - */ -class FileHelper { - public static final String TAG = "MojoFileHelper"; - - // Size of the buffer used in streaming file operations. - private static final int BUFFER_SIZE = 1024 * 1024; - // Prefix used when naming temporary files. - private static final String TEMP_FILE_PREFIX = "temp-"; - // Prefix used when naming timestamp files. - private static final String TIMESTAMP_PREFIX = "asset_timestamp-"; - - /** - * Looks for a timestamp file on disk that indicates the version of the APK that the resource - * assets were extracted from. Returns null if a timestamp was found and it indicates that the - * resources match the current APK. Otherwise returns a String that represents the filename of a - * timestamp to create. - */ - private static String checkAssetTimestamp(Context context, File outputDir) { - PackageManager pm = context.getPackageManager(); - PackageInfo pi = null; - - try { - pi = pm.getPackageInfo(context.getPackageName(), 0); - } catch (PackageManager.NameNotFoundException e) { - return TIMESTAMP_PREFIX; - } - - if (pi == null) { - return TIMESTAMP_PREFIX; - } - - String expectedTimestamp = TIMESTAMP_PREFIX + pi.versionCode + "-" + pi.lastUpdateTime; - - String[] timestamps = outputDir.list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.startsWith(TIMESTAMP_PREFIX); - } - }); - - if (timestamps.length != 1) { - // If there's no timestamp, nuke to be safe as we can't tell the age of the files. - // If there's multiple timestamps, something's gone wrong so nuke. - return expectedTimestamp; - } - - if (!expectedTimestamp.equals(timestamps[0])) { - return expectedTimestamp; - } - - // Timestamp file is already up-to date. - return null; - } - - public static File extractFromAssets(Context context, String assetName, File outputDirectory, - boolean useTempFile) throws IOException, FileNotFoundException { - String timestampToCreate = null; - if (!useTempFile) { - timestampToCreate = checkAssetTimestamp(context, outputDirectory); - if (timestampToCreate != null) { - for (File child : outputDirectory.listFiles()) { - deleteRecursively(child); - } - } - } - - File outputFile; - if (useTempFile) { - // Make the original filename part of the temp file name. - // TODO(ppi): do we need to sanitize the suffix? - String suffix = "-" + assetName; - outputFile = File.createTempFile(TEMP_FILE_PREFIX, suffix, outputDirectory); - } else { - outputFile = new File(outputDirectory, assetName); - if (outputFile.exists()) { - return outputFile; - } - } - - BufferedInputStream inputStream = new BufferedInputStream( - context.getAssets().open(assetName)); - try { - writeStreamToFile(inputStream, outputFile); - } finally { - inputStream.close(); - } - - if (timestampToCreate != null) { - try { - new File(outputDirectory, timestampToCreate).createNewFile(); - } catch (IOException e) { - // In the worst case we don't write a timestamp, so we'll re-extract the asset next - // time. - Log.w(TAG, "Failed to write asset timestamp!"); - } - } - - return outputFile; - } - - /** - * Extracts the file of the given extension from the archive. Throws FileNotFoundException if no - * matching file is found. - */ - static File extractFromArchive(File archive, String suffixToMatch, - File outputDirectory) throws IOException, FileNotFoundException { - ZipInputStream zip = new ZipInputStream(new BufferedInputStream(new FileInputStream( - archive))); - ZipEntry entry; - while ((entry = zip.getNextEntry()) != null) { - if (entry.getName().endsWith(suffixToMatch)) { - // Make the original filename part of the temp file name. - // TODO(ppi): do we need to sanitize the suffix? - String suffix = "-" + new File(entry.getName()).getName(); - File extractedFile = File.createTempFile(TEMP_FILE_PREFIX, suffix, - outputDirectory); - writeStreamToFile(zip, extractedFile); - zip.close(); - return extractedFile; - } - } - zip.close(); - throw new FileNotFoundException(); - } - - /** - * Deletes a file or directory. Directory will be deleted even if not empty. - */ - static void deleteRecursively(File file) { - if (file.isDirectory()) { - for (File child : file.listFiles()) { - deleteRecursively(child); - } - } - if (!file.delete()) { - Log.w(TAG, "Unable to delete file: " + file.getAbsolutePath()); - } - } - - private static void writeStreamToFile(InputStream inputStream, File outputFile) - throws IOException { - byte[] buffer = new byte[BUFFER_SIZE]; - OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); - try { - int read; - while ((read = inputStream.read(buffer, 0, BUFFER_SIZE)) > 0) { - outputStream.write(buffer, 0, read); - } - } finally { - outputStream.close(); - } - } -} diff --git a/mojo/shell/android/apk/src/org/chromium/mojo/shell/MojoShellActivity.java b/mojo/shell/android/apk/src/org/chromium/mojo/shell/MojoShellActivity.java deleted file mode 100644 index a56c43d..0000000 --- a/mojo/shell/android/apk/src/org/chromium/mojo/shell/MojoShellActivity.java +++ /dev/null @@ -1,67 +0,0 @@ -// 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.Intent; -import android.os.Bundle; -import android.util.JsonReader; -import android.util.Log; - -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; - -/** - * Activity for managing the Mojo Shell. - */ -public class MojoShellActivity extends Activity { - private static final String TAG = "MojoShellActivity"; - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // TODO(ppi): Gotcha - the call below will work only once per process lifetime, but the OS - // has no obligation to kill the application process between destroying and restarting the - // activity. If the application process is kept alive, initialization parameters sent with - // the intent will be stale. - // TODO(qsr): We should be passing application context here as required by - // InitApplicationContext on the native side. Currently we can't, as PlatformViewportAndroid - // relies on this being the activity context. - ShellMain.ensureInitialized(this, getParametersFromIntent(getIntent())); - - // TODO(eseidel): ShellMain can fail, but we're ignoring the return. - ShellMain.start(); - } - - private static String[] getParametersFromIntent(Intent intent) { - if (intent == null) { - return null; - } - String[] parameters = intent.getStringArrayExtra("parameters"); - if (parameters != null) { - return parameters; - } - String encodedParameters = intent.getStringExtra("encodedParameters"); - if (encodedParameters != null) { - JsonReader reader = new JsonReader(new StringReader(encodedParameters)); - List<String> parametersList = new ArrayList<String>(); - try { - reader.beginArray(); - while (reader.hasNext()) { - parametersList.add(reader.nextString()); - } - reader.endArray(); - reader.close(); - return parametersList.toArray(new String[parametersList.size()]); - } catch (IOException e) { - Log.w(TAG, e.getMessage(), e); - } - } - return null; - } -} diff --git a/mojo/shell/android/apk/src/org/chromium/mojo/shell/MojoShellApplication.java b/mojo/shell/android/apk/src/org/chromium/mojo/shell/MojoShellApplication.java deleted file mode 100644 index ee39c23..0000000 --- a/mojo/shell/android/apk/src/org/chromium/mojo/shell/MojoShellApplication.java +++ /dev/null @@ -1,57 +0,0 @@ -// 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.util.Log; - -import org.chromium.base.BaseChromiumApplication; -import org.chromium.base.PathUtils; -import org.chromium.base.library_loader.LibraryLoader; -import org.chromium.base.library_loader.LibraryProcessType; -import org.chromium.base.library_loader.ProcessInitException; - -/** - * MojoShell implementation of {@link android.app.Application}, managing application-level global - * state and initializations. - */ -public class MojoShellApplication extends BaseChromiumApplication { - private static final String TAG = "MojoShellApplication"; - private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "mojo_shell"; - - @Override - public void onCreate() { - super.onCreate(); - clearTemporaryFiles(); - initializeJavaUtils(); - initializeNative(); - } - - /** - * Deletes the temporary files and directories created in the previous run of the application. - * This is important regardless of cleanups on exit, as the previous run could have crashed. - */ - private void clearTemporaryFiles() { - AndroidHandler.clearTemporaryFiles(this); - } - - /** - * Initializes Java-side utils. - */ - private void initializeJavaUtils() { - PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, this); - } - - /** - * Loads the native library. - */ - private void initializeNative() { - try { - LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized(); - } catch (ProcessInitException e) { - Log.e(TAG, "libmojo_shell initialization failed.", e); - throw new RuntimeException(e); - } - } -} diff --git a/mojo/shell/android/apk/src/org/chromium/mojo/shell/ShellMain.java b/mojo/shell/android/apk/src/org/chromium/mojo/shell/ShellMain.java deleted file mode 100644 index 1f55fa2..0000000 --- a/mojo/shell/android/apk/src/org/chromium/mojo/shell/ShellMain.java +++ /dev/null @@ -1,105 +0,0 @@ -// 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 java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * A placeholder class to call native functions. - **/ -@JNINamespace("mojo::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"; - // The mojo_shell library is also an executable run in forked processes when running - // multi-process. - private static final String MOJO_SHELL_EXECUTABLE = "libmojo_shell.so"; - - /** - * A guard flag for calling nativeInit() only once. - **/ - private static boolean sInitialized = false; - - /** - * Initializes the native system. - **/ - static void ensureInitialized(Context applicationContext, String[] parameters) { - if (sInitialized) return; - try { - FileHelper.extractFromAssets(applicationContext, NETWORK_LIBRARY_APP, - getLocalAppsDir(applicationContext), false); - File mojoShell = new File(applicationContext.getApplicationInfo().nativeLibraryDir, - MOJO_SHELL_EXECUTABLE); - - List<String> parametersList = new ArrayList<String>(); - // Program name. - if (parameters != null) { - parametersList.addAll(Arrays.asList(parameters)); - } - - nativeInit(applicationContext, mojoShell.getAbsolutePath(), - parametersList.toArray(new String[parametersList.size()]), - getLocalAppsDir(applicationContext).getAbsolutePath(), - getTmpDir(applicationContext).getAbsolutePath()); - sInitialized = true; - } catch (Exception e) { - Log.e(TAG, "ShellMain initialization failed.", e); - throw new RuntimeException(e); - } - } - - /** - * 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); - } - - private static File getLocalAppsDir(Context context) { - return context.getDir(LOCAL_APP_DIRECTORY, Context.MODE_PRIVATE); - } - - private static File getTmpDir(Context context) { - return new File(context.getCacheDir(), "tmp"); - } - - @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 mojoShellPath, - String[] parameters, String bundledAppsDirectory, String tmpDir); - - private static native boolean nativeStart(); - - private static native void nativeAddApplicationURL(String url); -} diff --git a/mojo/shell/android/background_application_loader.cc b/mojo/shell/android/background_application_loader.cc deleted file mode 100644 index cdb175e..0000000 --- a/mojo/shell/android/background_application_loader.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2014 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/shell/android/background_application_loader.h" - -#include "base/bind.h" -#include "base/run_loop.h" -#include "mojo/shell/application_manager/application_manager.h" - -namespace mojo { -namespace shell { - -BackgroundApplicationLoader::BackgroundApplicationLoader( - scoped_ptr<ApplicationLoader> real_loader, - const std::string& thread_name, - base::MessageLoop::Type message_loop_type) - : loader_(real_loader.Pass()), - message_loop_type_(message_loop_type), - thread_name_(thread_name), - message_loop_created_(true, false) { -} - -BackgroundApplicationLoader::~BackgroundApplicationLoader() { - if (thread_) - thread_->Join(); -} - -void BackgroundApplicationLoader::Load( - const GURL& url, - InterfaceRequest<Application> application_request) { - DCHECK(application_request.is_pending()); - if (!thread_) { - // TODO(tim): It'd be nice if we could just have each Load call - // result in a new thread like DynamicService{Loader, Runner}. But some - // loaders are creating multiple ApplicationImpls (NetworkApplicationLoader) - // sharing a delegate (etc). So we have to keep it single threaded, wait - // for the thread to initialize, and post to the TaskRunner for subsequent - // Load calls for now. - thread_.reset(new base::DelegateSimpleThread(this, thread_name_)); - thread_->Start(); - message_loop_created_.Wait(); - DCHECK(task_runner_.get()); - } - - task_runner_->PostTask( - FROM_HERE, - base::Bind(&BackgroundApplicationLoader::LoadOnBackgroundThread, - base::Unretained(this), url, - base::Passed(&application_request))); -} - -void BackgroundApplicationLoader::Run() { - base::MessageLoop message_loop(message_loop_type_); - base::RunLoop loop; - task_runner_ = message_loop.task_runner(); - quit_closure_ = loop.QuitClosure(); - message_loop_created_.Signal(); - loop.Run(); - - // Destroy |loader_| on the thread it's actually used on. - loader_.reset(); -} - -void BackgroundApplicationLoader::LoadOnBackgroundThread( - const GURL& url, - InterfaceRequest<Application> application_request) { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); - loader_->Load(url, application_request.Pass()); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/android/background_application_loader.h b/mojo/shell/android/background_application_loader.h deleted file mode 100644 index 7c549f7..0000000 --- a/mojo/shell/android/background_application_loader.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 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 SHELL_ANDROID_BACKGROUND_APPLICATION_LOADER_H_ -#define SHELL_ANDROID_BACKGROUND_APPLICATION_LOADER_H_ - -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/simple_thread.h" -#include "mojo/shell/application_manager/application_loader.h" - -namespace mojo { -namespace shell { - -class BackgroundApplicationLoader - : public ApplicationLoader, - public base::DelegateSimpleThread::Delegate { - public: - BackgroundApplicationLoader(scoped_ptr<ApplicationLoader> real_loader, - const std::string& thread_name, - base::MessageLoop::Type message_loop_type); - ~BackgroundApplicationLoader() override; - - // ApplicationLoader overrides: - void Load(const GURL& url, - InterfaceRequest<Application> application_request) override; - - private: - // |base::DelegateSimpleThread::Delegate| method: - void Run() override; - - // These functions are exected on the background thread. They call through - // to |background_loader_| to do the actual loading. - void LoadOnBackgroundThread( - const GURL& url, - InterfaceRequest<Application> application_request); - bool quit_on_shutdown_; - scoped_ptr<ApplicationLoader> loader_; - - const base::MessageLoop::Type message_loop_type_; - const std::string thread_name_; - - // Created on |thread_| during construction of |this|. Protected against - // uninitialized use by |message_loop_created_|, and protected against - // use-after-free by holding a reference to the thread-safe object. Note - // that holding a reference won't hold |thread_| from exiting. - scoped_refptr<base::TaskRunner> task_runner_; - base::WaitableEvent message_loop_created_; - - // Lives on |thread_|. - base::Closure quit_closure_; - - scoped_ptr<base::DelegateSimpleThread> thread_; - - DISALLOW_COPY_AND_ASSIGN(BackgroundApplicationLoader); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_ANDROID_BACKGROUND_APPLICATION_LOADER_H_ diff --git a/mojo/shell/android/background_application_loader_unittest.cc b/mojo/shell/android/background_application_loader_unittest.cc deleted file mode 100644 index 4d18073..0000000 --- a/mojo/shell/android/background_application_loader_unittest.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2014 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/shell/android/background_application_loader.h" - -#include "mojo/public/interfaces/application/application.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace shell { -namespace { - -class DummyLoader : public ApplicationLoader { - public: - DummyLoader() : simulate_app_quit_(true) {} - ~DummyLoader() override {} - - // ApplicationLoader overrides: - void Load(const GURL& url, - InterfaceRequest<Application> application_request) override { - if (simulate_app_quit_) - base::MessageLoop::current()->Quit(); - } - - void DontSimulateAppQuit() { simulate_app_quit_ = false; } - - private: - bool simulate_app_quit_; -}; - -// Tests that the loader can start and stop gracefully. -TEST(BackgroundApplicationLoaderTest, StartStop) { - scoped_ptr<ApplicationLoader> real_loader(new DummyLoader()); - BackgroundApplicationLoader loader(real_loader.Pass(), "test", - base::MessageLoop::TYPE_DEFAULT); -} - -// Tests that the loader can load a service that is well behaved (quits -// itself). -TEST(BackgroundApplicationLoaderTest, Load) { - scoped_ptr<ApplicationLoader> real_loader(new DummyLoader()); - BackgroundApplicationLoader loader(real_loader.Pass(), "test", - base::MessageLoop::TYPE_DEFAULT); - ApplicationPtr application; - loader.Load(GURL(), GetProxy(&application)); -} - -} // namespace -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/android/bootstrap.cc b/mojo/shell/android/bootstrap.cc deleted file mode 100644 index 4fcae37..0000000 --- a/mojo/shell/android/bootstrap.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 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/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "jni/Bootstrap_jni.h" -#include "mojo/shell/android/run_android_application_function.h" - -namespace mojo { -namespace shell { - -void Bootstrap(JNIEnv* env, - jobject, - jobject j_context, - jstring j_native_library_path, - jint j_handle, - jlong j_run_application_ptr) { - base::FilePath app_path( - base::android::ConvertJavaStringToUTF8(env, j_native_library_path)); - RunAndroidApplicationFn run_android_application_fn = - reinterpret_cast<RunAndroidApplicationFn>(j_run_application_ptr); - run_android_application_fn(env, j_context, app_path, j_handle); -} - -bool RegisterBootstrapJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace shell -} // namespace mojo - -JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { - base::android::InitVM(vm); - JNIEnv* env = base::android::AttachCurrentThread(); - - if (!mojo::shell::RegisterBootstrapJni(env)) - return -1; - - return JNI_VERSION_1_4; -} diff --git a/mojo/shell/android/library_loader.cc b/mojo/shell/android/library_loader.cc deleted file mode 100644 index c43a4b5..0000000 --- a/mojo/shell/android/library_loader.cc +++ /dev/null @@ -1,44 +0,0 @@ -// 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. - -#include "base/android/base_jni_onload.h" -#include "base/android/base_jni_registrar.h" -#include "base/android/jni_android.h" -#include "base/android/jni_registrar.h" -#include "base/bind.h" -#include "components/native_viewport/platform_viewport_android.h" -#include "mojo/shell/android/android_handler.h" -#include "mojo/shell/android/main.h" - -namespace { - -base::android::RegistrationMethod kMojoRegisteredMethods[] = { - {"AndroidHandler", mojo::shell::RegisterAndroidHandlerJni}, - {"PlatformViewportAndroid", - native_viewport::PlatformViewportAndroid::Register}, - {"ShellMain", mojo::shell::RegisterShellMain}, -}; - -bool RegisterJNI(JNIEnv* env) { - if (!base::android::RegisterJni(env)) - return false; - - return RegisterNativeMethods(env, kMojoRegisteredMethods, - arraysize(kMojoRegisteredMethods)); -} - -} // 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)); - if (!base::android::OnJNIOnLoadRegisterJNI(vm, register_callbacks) || - !base::android::OnJNIOnLoadInit( - std::vector<base::android::InitCallback>())) { - return -1; - } - - return JNI_VERSION_1_4; -} diff --git a/mojo/shell/android/main.cc b/mojo/shell/android/main.cc deleted file mode 100644 index 0e6c917..0000000 --- a/mojo/shell/android/main.cc +++ /dev/null @@ -1,211 +0,0 @@ -// 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. - -#include "mojo/shell/android/main.h" - -#include "base/android/fifo_utils.h" -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/at_exit.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/simple_thread.h" -#include "jni/ShellMain_jni.h" -#include "mojo/common/message_pump_mojo.h" -#include "mojo/shell/android/android_handler_loader.h" -#include "mojo/shell/android/background_application_loader.h" -#include "mojo/shell/android/native_viewport_application_loader.h" -#include "mojo/shell/android/ui_application_loader_android.h" -#include "mojo/shell/application_manager/application_loader.h" -#include "mojo/shell/context.h" -#include "mojo/shell/init.h" -#include "ui/gl/gl_surface_egl.h" - -using base::LazyInstance; - -namespace mojo { -namespace shell { - -namespace { - -// Tag for logging. -const char kLogTag[] = "chromium"; - -// Command line argument for the communication fifo. -const char kFifoPath[] = "fifo-path"; - -class MojoShellRunner : public base::DelegateSimpleThread::Delegate { - public: - MojoShellRunner(const std::vector<std::string>& parameters) {} - ~MojoShellRunner() override {} - - private: - void Run() override; - - DISALLOW_COPY_AND_ASSIGN(MojoShellRunner); -}; - -LazyInstance<scoped_ptr<base::MessageLoop>> g_java_message_loop = - LAZY_INSTANCE_INITIALIZER; - -LazyInstance<scoped_ptr<Context>> g_context = LAZY_INSTANCE_INITIALIZER; - -LazyInstance<scoped_ptr<MojoShellRunner>> g_shell_runner = - LAZY_INSTANCE_INITIALIZER; - -LazyInstance<scoped_ptr<base::DelegateSimpleThread>> g_shell_thread = - LAZY_INSTANCE_INITIALIZER; - -LazyInstance<base::android::ScopedJavaGlobalRef<jobject>> g_main_activiy = - LAZY_INSTANCE_INITIALIZER; - -void ConfigureAndroidServices(Context* context) { - context->application_manager()->SetLoaderForURL( - make_scoped_ptr(new UIApplicationLoader( - make_scoped_ptr(new NativeViewportApplicationLoader()), - g_java_message_loop.Get().get())), - GURL("mojo:native_viewport_service")); - - // Android handler is bundled with the Mojo shell, because it uses the - // MojoShell application as the JNI bridge to bootstrap execution of other - // Android Mojo apps that need JNI. - context->application_manager()->SetLoaderForURL( - make_scoped_ptr(new BackgroundApplicationLoader( - make_scoped_ptr(new AndroidHandlerLoader()), "android_handler", - base::MessageLoop::TYPE_DEFAULT)), - GURL("mojo:android_handler")); -} - -void QuitShellThread() { - g_shell_thread.Get()->Join(); - g_shell_thread.Pointer()->reset(); - Java_ShellMain_finishActivity(base::android::AttachCurrentThread(), - g_main_activiy.Get().obj()); - exit(0); -} - -void MojoShellRunner::Run() { - base::MessageLoop loop(common::MessagePumpMojo::Create()); - Context* context = g_context.Pointer()->get(); - ConfigureAndroidServices(context); - context->Init(); - - context->Run(GURL("mojo:window_manager")); - loop.Run(); - - g_java_message_loop.Pointer()->get()->PostTask(FROM_HERE, - base::Bind(&QuitShellThread)); -} - -// Initialize stdout redirection if the command line switch is present. -void InitializeRedirection() { - if (!base::CommandLine::ForCurrentProcess()->HasSwitch(kFifoPath)) - return; - - base::FilePath fifo_path = - base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(kFifoPath); - base::FilePath directory = fifo_path.DirName(); - CHECK(base::CreateDirectoryAndGetError(directory, nullptr)) - << "Unable to create directory: " << directory.value(); - unlink(fifo_path.value().c_str()); - CHECK(base::android::CreateFIFO(fifo_path, 0666)) - << "Unable to create fifo: " << fifo_path.value(); - CHECK(base::android::RedirectStream(stdout, fifo_path, "w")) - << "Failed to redirect stdout to file: " << fifo_path.value(); - CHECK(dup2(STDOUT_FILENO, STDERR_FILENO) != -1) - << "Unable to redirect stderr to stdout."; -} - -} // namespace - -static void Init(JNIEnv* env, - jclass clazz, - jobject activity, - jstring mojo_shell_path, - jobjectArray jparameters, - jstring j_local_apps_directory, - jstring j_tmp_dir) { - g_main_activiy.Get().Reset(env, activity); - - // Setting the TMPDIR environment variable so that applications can use it. - // TODO(qsr) We will need our subprocesses to inherit this. - int return_value = - setenv("TMPDIR", - base::android::ConvertJavaStringToUTF8(env, j_tmp_dir).c_str(), 1); - DCHECK_EQ(return_value, 0); - - base::android::ScopedJavaLocalRef<jobject> scoped_activity(env, activity); - base::android::InitApplicationContext(env, scoped_activity); - - std::vector<std::string> parameters; - parameters.push_back( - base::android::ConvertJavaStringToUTF8(env, mojo_shell_path)); - base::android::AppendJavaStringArrayToStringVector(env, jparameters, - ¶meters); - base::CommandLine::Init(0, nullptr); - base::CommandLine::ForCurrentProcess()->InitFromArgv(parameters); - g_shell_runner.Get().reset(new MojoShellRunner(parameters)); - - InitializeLogging(); - - InitializeRedirection(); - - // We want ~MessageLoop to happen prior to ~Context. Initializing - // LazyInstances is akin to stack-allocating objects; their destructors - // will be invoked first-in-last-out. - Context* shell_context = new Context(); - shell_context->SetShellFileRoot(base::FilePath( - base::android::ConvertJavaStringToUTF8(env, j_local_apps_directory))); - g_context.Get().reset(shell_context); - - g_java_message_loop.Get().reset(new base::MessageLoopForUI); - base::MessageLoopForUI::current()->Start(); - - // TODO(abarth): At which point should we switch to cross-platform - // initialization? - - gfx::GLSurface::InitializeOneOff(); -} - -static jboolean Start(JNIEnv* env, jclass clazz) { - if (!base::CommandLine::ForCurrentProcess()->GetArgs().size()) - return false; - -#if defined(MOJO_SHELL_DEBUG_URL) - base::CommandLine::ForCurrentProcess()->AppendArg(MOJO_SHELL_DEBUG_URL); - // Sleep for 5 seconds to give the debugger a chance to attach. - sleep(5); -#endif - - g_shell_thread.Get().reset(new base::DelegateSimpleThread( - g_shell_runner.Get().get(), "ShellThread")); - g_shell_thread.Get()->Start(); - return true; -} - -static void AddApplicationURL(JNIEnv* env, jclass clazz, jstring jurl) { - base::CommandLine::ForCurrentProcess()->AppendArg( - base::android::ConvertJavaStringToUTF8(env, jurl)); -} - -bool RegisterShellMain(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace shell -} // namespace mojo - -// TODO(vtl): Even though main() should never be called, mojo_shell fails to -// link without it. Figure out if we can avoid this. -int main(int argc, char** argv) { - NOTREACHED(); -} diff --git a/mojo/shell/android/main.h b/mojo/shell/android/main.h deleted file mode 100644 index 43ea16a..0000000 --- a/mojo/shell/android/main.h +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -#ifndef SHELL_ANDROID_MAIN_H_ -#define SHELL_ANDROID_MAIN_H_ - -#include <jni.h> - -namespace mojo { -namespace shell { - -bool RegisterShellMain(JNIEnv* env); - -} // namespace shell -} // namespace mojo - -#endif // SHELL_ANDROID_MAIN_H_ diff --git a/mojo/shell/android/native_viewport_application_loader.cc b/mojo/shell/android/native_viewport_application_loader.cc deleted file mode 100644 index 3822980..0000000 --- a/mojo/shell/android/native_viewport_application_loader.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2014 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/shell/android/native_viewport_application_loader.h" - -#include "components/gles2/gpu_state.h" -#include "components/native_viewport/native_viewport_impl.h" -#include "mojo/public/cpp/application/application_impl.h" - -namespace mojo { -namespace shell { - -NativeViewportApplicationLoader::NativeViewportApplicationLoader() { -} - -NativeViewportApplicationLoader::~NativeViewportApplicationLoader() { -} - -void NativeViewportApplicationLoader::Load( - const GURL& url, - InterfaceRequest<Application> application_request) { - DCHECK(application_request.is_pending()); - app_.reset(new ApplicationImpl(this, application_request.Pass())); -} - -bool NativeViewportApplicationLoader::ConfigureIncomingConnection( - ApplicationConnection* connection) { - connection->AddService<NativeViewport>(this); - connection->AddService<Gpu>(this); - return true; -} - -void NativeViewportApplicationLoader::Create( - ApplicationConnection* connection, - InterfaceRequest<NativeViewport> request) { - if (!gpu_state_) - gpu_state_ = new gles2::GpuState; - new native_viewport::NativeViewportImpl(false, gpu_state_, request.Pass()); -} - -void NativeViewportApplicationLoader::Create(ApplicationConnection* connection, - InterfaceRequest<Gpu> request) { - if (!gpu_state_) - gpu_state_ = new gles2::GpuState; - new gles2::GpuImpl(request.Pass(), gpu_state_); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/android/native_viewport_application_loader.h b/mojo/shell/android/native_viewport_application_loader.h deleted file mode 100644 index 16bc2aa..0000000 --- a/mojo/shell/android/native_viewport_application_loader.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2014 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_SHELL_ANDROID_NATIVE_VIEWPORT_APPLICATION_LOADER_H_ -#define MOJO_SHELL_ANDROID_NATIVE_VIEWPORT_APPLICATION_LOADER_H_ - -#include "components/gles2/gpu_impl.h" -#include "components/gpu/public/interfaces/gpu.mojom.h" -#include "components/native_viewport/public/interfaces/native_viewport.mojom.h" -#include "mojo/public/cpp/application/application_delegate.h" -#include "mojo/public/cpp/application/interface_factory.h" -#include "mojo/shell/application_manager/application_loader.h" - -namespace gles2 { -class GpuState; -} - -namespace mojo { - -class ApplicationImpl; - -namespace shell { - -class NativeViewportApplicationLoader : public ApplicationLoader, - public ApplicationDelegate, - public InterfaceFactory<NativeViewport>, - public InterfaceFactory<Gpu> { - public: - NativeViewportApplicationLoader(); - ~NativeViewportApplicationLoader(); - - private: - // ApplicationLoader implementation. - void Load(const GURL& url, - InterfaceRequest<Application> application_request) override; - - // ApplicationDelegate implementation. - bool ConfigureIncomingConnection(ApplicationConnection* connection) override; - - // InterfaceFactory<NativeViewport> implementation. - void Create(ApplicationConnection* connection, - InterfaceRequest<NativeViewport> request) override; - - // InterfaceFactory<Gpu> implementation. - void Create(ApplicationConnection* connection, - InterfaceRequest<Gpu> request) override; - - scoped_refptr<gles2::GpuState> gpu_state_; - scoped_ptr<ApplicationImpl> app_; - - DISALLOW_COPY_AND_ASSIGN(NativeViewportApplicationLoader); -}; - -} // namespace shell -} // namespace mojo - -#endif // MOJO_SHELL_ANDROID_NATIVE_VIEWPORT_APPLICATION_LOADER_H_ diff --git a/mojo/shell/android/run_android_application_function.h b/mojo/shell/android/run_android_application_function.h deleted file mode 100644 index 3ed1744..0000000 --- a/mojo/shell/android/run_android_application_function.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 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 SHELL_ANDROID_RUN_ANDROID_APPLICATION_FUNCTION_H_ -#define SHELL_ANDROID_RUN_ANDROID_APPLICATION_FUNCTION_H_ - -#include "base/android/jni_android.h" -#include "base/files/file_path.h" - -namespace mojo { -namespace shell { - -// Type of the function that we inject from the main .so of the Mojo shell to -// the helper libbootstrap.so. This function will set the thunks in the -// application .so and call into application MojoMain. Injecting the function -// from the main .so ensures that the thunks are set correctly. - -typedef void (*RunAndroidApplicationFn)(JNIEnv* env, - jobject j_context, - const base::FilePath& app_path, - jint j_handle); - -} // namespace shell -} // namespace mojo - -#endif // SHELL_ANDROID_RUN_ANDROID_APPLICATION_FUNCTION_H_ diff --git a/mojo/shell/android/tests/src/org/chromium/mojo/shell/ShellTestBase.java b/mojo/shell/android/tests/src/org/chromium/mojo/shell/ShellTestBase.java deleted file mode 100644 index 2aba46f..0000000 --- a/mojo/shell/android/tests/src/org/chromium/mojo/shell/ShellTestBase.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 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.content.Context; -import android.content.res.AssetManager; - -import org.chromium.base.CalledByNative; -import org.chromium.base.JNINamespace; - -import java.io.File; -import java.io.IOException; - -/** - * Helper method for ShellTestBase. - */ -@JNINamespace("mojo::shell::test") -public class ShellTestBase { - // Directory where applications bundled with the tests will be extracted. - private static final String TEST_APP_DIRECTORY = "test_apps"; - - /** - * Extracts the mojo applications from the apk assets and returns the directory where they are. - */ - @CalledByNative - private static String extractMojoApplications(Context context) throws IOException { - final File outputDirectory = context.getDir(TEST_APP_DIRECTORY, Context.MODE_PRIVATE); - - AssetManager manager = context.getResources().getAssets(); - for (String asset : manager.list("")) { - if (asset.endsWith(".mojo")) { - FileHelper.extractFromAssets(context, asset, outputDirectory, false); - } - } - - return outputDirectory.getAbsolutePath(); - } -} diff --git a/mojo/shell/android/ui_application_loader_android.cc b/mojo/shell/android/ui_application_loader_android.cc deleted file mode 100644 index 87f686f..0000000 --- a/mojo/shell/android/ui_application_loader_android.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014 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/shell/android/ui_application_loader_android.h" - -#include "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "mojo/shell/application_manager/application_manager.h" - -namespace mojo { -namespace shell { - -UIApplicationLoader::UIApplicationLoader( - scoped_ptr<ApplicationLoader> real_loader, - base::MessageLoop* ui_message_loop) - : loader_(real_loader.Pass()), ui_message_loop_(ui_message_loop) { -} - -UIApplicationLoader::~UIApplicationLoader() { - ui_message_loop_->PostTask( - FROM_HERE, base::Bind(&UIApplicationLoader::ShutdownOnUIThread, - base::Unretained(this))); -} - -void UIApplicationLoader::Load( - const GURL& url, - InterfaceRequest<Application> application_request) { - DCHECK(application_request.is_pending()); - ui_message_loop_->PostTask( - FROM_HERE, - base::Bind(&UIApplicationLoader::LoadOnUIThread, base::Unretained(this), - url, base::Passed(&application_request))); -} - -void UIApplicationLoader::LoadOnUIThread( - const GURL& url, - InterfaceRequest<Application> application_request) { - loader_->Load(url, application_request.Pass()); -} - -void UIApplicationLoader::ShutdownOnUIThread() { - // Destroy |loader_| on the thread it's actually used on. - loader_.reset(); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/android/ui_application_loader_android.h b/mojo/shell/android/ui_application_loader_android.h deleted file mode 100644 index 37cc063..0000000 --- a/mojo/shell/android/ui_application_loader_android.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 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 SHELL_ANDROID_UI_APPLICATION_LOADER_ANDROID_H_ -#define SHELL_ANDROID_UI_APPLICATION_LOADER_ANDROID_H_ - -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "mojo/shell/application_manager/application_loader.h" - -namespace base { -class MessageLoop; -} - -namespace mojo { -namespace shell { - -class ApplicationManager; - -// ApplicationLoader implementation that creates a background thread and issues -// load -// requests there. -class UIApplicationLoader : public ApplicationLoader { - public: - UIApplicationLoader(scoped_ptr<ApplicationLoader> real_loader, - base::MessageLoop* ui_message_loop); - ~UIApplicationLoader() override; - - // ApplicationLoader overrides: - void Load(const GURL& url, - InterfaceRequest<Application> application_request) override; - - private: - class UILoader; - - // These functions are exected on the background thread. They call through - // to |background_loader_| to do the actual loading. - // TODO: having this code take a |manager| is fragile (as ApplicationManager - // isn't thread safe). - void LoadOnUIThread(const GURL& url, - InterfaceRequest<Application> application_request); - void ShutdownOnUIThread(); - - scoped_ptr<ApplicationLoader> loader_; - base::MessageLoop* ui_message_loop_; - - DISALLOW_COPY_AND_ASSIGN(UIApplicationLoader); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_ANDROID_UI_APPLICATION_LOADER_ANDROID_H_ diff --git a/mojo/shell/application_manager/application_loader.h b/mojo/shell/application_loader.h index 11feb38..11feb38 100644 --- a/mojo/shell/application_manager/application_loader.h +++ b/mojo/shell/application_loader.h diff --git a/mojo/shell/application_manager/application_manager.cc b/mojo/shell/application_manager.cc index 81029d0..4648c1f 100644 --- a/mojo/shell/application_manager/application_manager.cc +++ b/mojo/shell/application_manager.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/application_manager.h" +#include "mojo/shell/application_manager.h" #include "base/bind.h" #include "base/command_line.h" @@ -13,11 +13,11 @@ #include "base/trace_event/trace_event.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/error_handler.h" -#include "mojo/shell/application_manager/fetcher.h" -#include "mojo/shell/application_manager/local_fetcher.h" -#include "mojo/shell/application_manager/network_fetcher.h" -#include "mojo/shell/application_manager/query_util.h" -#include "mojo/shell/application_manager/shell_impl.h" +#include "mojo/shell/fetcher.h" +#include "mojo/shell/local_fetcher.h" +#include "mojo/shell/network_fetcher.h" +#include "mojo/shell/query_util.h" +#include "mojo/shell/shell_impl.h" #include "mojo/shell/switches.h" #include "third_party/mojo_services/src/content_handler/public/interfaces/content_handler.mojom.h" diff --git a/mojo/shell/application_manager/application_manager.h b/mojo/shell/application_manager.h index 3ce1599..8e517f8 100644 --- a/mojo/shell/application_manager/application_manager.h +++ b/mojo/shell/application_manager.h @@ -14,11 +14,11 @@ #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/interfaces/application/application.mojom.h" #include "mojo/public/interfaces/application/service_provider.mojom.h" +#include "mojo/runner/native_application_support.h" #include "mojo/services/network/public/interfaces/network_service.mojom.h" -#include "mojo/shell/application_manager/application_loader.h" -#include "mojo/shell/application_manager/identity.h" -#include "mojo/shell/application_manager/native_runner.h" -#include "mojo/shell/native_application_support.h" +#include "mojo/shell/application_loader.h" +#include "mojo/shell/identity.h" +#include "mojo/shell/native_runner.h" #include "url/gurl.h" namespace base { diff --git a/mojo/shell/application_manager/BUILD.gn b/mojo/shell/application_manager/BUILD.gn deleted file mode 100644 index 9122e7e..0000000 --- a/mojo/shell/application_manager/BUILD.gn +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2014 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. - -import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni") -import("//testing/test.gni") - -source_set("application_manager") { - output_name = "mojo_application_manager" - sources = [ - "application_loader.h", - "application_manager.cc", - "application_manager.h", - "data_pipe_peek.cc", - "data_pipe_peek.h", - "fetcher.cc", - "fetcher.h", - "identity.cc", - "identity.h", - "local_fetcher.cc", - "local_fetcher.h", - "native_runner.h", - "network_fetcher.cc", - "network_fetcher.h", - "query_util.cc", - "query_util.h", - "shell_impl.cc", - "shell_impl.h", - ] - - public_deps = [ - "//base", - "//mojo/common", - "//third_party/mojo/src/mojo/public/interfaces/application:application", - "//mojo/services/network/public/interfaces", - "//url", - ] - deps = [ - "//base/third_party/dynamic_annotations", - "//crypto:crypto", - "//url", - "//third_party/mojo/src/mojo/edk/system", - "//mojo/environment:chromium", - "//third_party/mojo_services/src/content_handler/public/interfaces", - "//mojo/shell:native_application_support", - "//mojo/shell:switches", - ] -} - -test("tests") { - output_name = "mojo_application_manager_unittests" - - sources = [ - "application_manager_unittest.cc", - "query_util_unittest.cc", - ] - - deps = [ - ":application_manager", - ":test_bindings", - "//base", - "//mojo/application", - "//mojo/common", - "//third_party/mojo/src/mojo/edk/test:run_all_unittests", - "//mojo/environment:chromium", - "//third_party/mojo/src/mojo/public/cpp/application", - "//third_party/mojo/src/mojo/public/cpp/bindings", - "//testing/gtest", - "//url", - ] -} - -mojom("test_bindings") { - sources = [ - "test.mojom", - ] -} diff --git a/mojo/shell/application_manager/application_manager_unittest.cc b/mojo/shell/application_manager_unittest.cc index d425f5a..7819e37 100644 --- a/mojo/shell/application_manager/application_manager_unittest.cc +++ b/mojo/shell/application_manager_unittest.cc @@ -13,9 +13,9 @@ #include "mojo/public/cpp/application/interface_factory.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/interfaces/application/service_provider.mojom.h" -#include "mojo/shell/application_manager/application_loader.h" -#include "mojo/shell/application_manager/application_manager.h" -#include "mojo/shell/application_manager/test.mojom.h" +#include "mojo/shell/application_loader.h" +#include "mojo/shell/application_manager.h" +#include "mojo/shell/test.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo { diff --git a/mojo/shell/child_process.cc b/mojo/shell/child_process.cc deleted file mode 100644 index df5eb498..0000000 --- a/mojo/shell/child_process.cc +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright 2014 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/shell/child_process.h" - -#include "base/base_switches.h" -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/command_line.h" -#include "base/debug/debugger.h" -#include "base/files/file_path.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "base/threading/thread_checker.h" -#include "mojo/common/message_pump_mojo.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/platform_channel_pair.h" -#include "mojo/edk/embedder/process_delegate.h" -#include "mojo/edk/embedder/scoped_platform_handle.h" -#include "mojo/edk/embedder/simple_platform_support.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/shell/child_process.mojom.h" -#include "mojo/shell/native_application_support.h" -#include "mojo/shell/switches.h" - -namespace mojo { -namespace shell { - -namespace { - -// Blocker --------------------------------------------------------------------- - -// Blocks a thread until another thread unblocks it, at which point it unblocks -// and runs a closure provided by that thread. -class Blocker { - public: - class Unblocker { - public: - explicit Unblocker(Blocker* blocker = nullptr) : blocker_(blocker) {} - ~Unblocker() {} - - void Unblock(base::Closure run_after) { - DCHECK(blocker_); - DCHECK(blocker_->run_after_.is_null()); - blocker_->run_after_ = run_after; - blocker_->event_.Signal(); - blocker_ = nullptr; - } - - private: - Blocker* blocker_; - - // Copy and assign allowed. - }; - - Blocker() : event_(true, false) {} - ~Blocker() {} - - void Block() { - DCHECK(run_after_.is_null()); - event_.Wait(); - run_after_.Run(); - } - - Unblocker GetUnblocker() { return Unblocker(this); } - - private: - base::WaitableEvent event_; - base::Closure run_after_; - - DISALLOW_COPY_AND_ASSIGN(Blocker); -}; - -// AppContext ------------------------------------------------------------------ - -class ChildControllerImpl; - -// Should be created and initialized on the main thread. -class AppContext : public embedder::ProcessDelegate { - public: - AppContext() - : io_thread_("io_thread"), controller_thread_("controller_thread") {} - ~AppContext() override {} - - void Init() { - // Initialize Mojo before starting any threads. - embedder::Init(make_scoped_ptr(new embedder::SimplePlatformSupport())); - - // Create and start our I/O thread. - base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0); - CHECK(io_thread_.StartWithOptions(io_thread_options)); - io_runner_ = io_thread_.message_loop_proxy().get(); - CHECK(io_runner_.get()); - - // Create and start our controller thread. - base::Thread::Options controller_thread_options; - controller_thread_options.message_loop_type = - base::MessageLoop::TYPE_CUSTOM; - controller_thread_options.message_pump_factory = - base::Bind(&common::MessagePumpMojo::Create); - CHECK(controller_thread_.StartWithOptions(controller_thread_options)); - controller_runner_ = controller_thread_.message_loop_proxy().get(); - CHECK(controller_runner_.get()); - - // TODO(vtl): This should be SLAVE, not NONE. - embedder::InitIPCSupport(embedder::ProcessType::NONE, controller_runner_, - this, io_runner_, - embedder::ScopedPlatformHandle()); - } - - void Shutdown() { - Blocker blocker; - shutdown_unblocker_ = blocker.GetUnblocker(); - controller_runner_->PostTask( - FROM_HERE, base::Bind(&AppContext::ShutdownOnControllerThread, - base::Unretained(this))); - blocker.Block(); - } - - base::SingleThreadTaskRunner* io_runner() const { return io_runner_.get(); } - - base::SingleThreadTaskRunner* controller_runner() const { - return controller_runner_.get(); - } - - ChildControllerImpl* controller() const { return controller_.get(); } - - void set_controller(scoped_ptr<ChildControllerImpl> controller) { - controller_ = controller.Pass(); - } - - private: - void ShutdownOnControllerThread() { - // First, destroy the controller. - controller_.reset(); - - // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete(). - embedder::ShutdownIPCSupport(); - } - - // ProcessDelegate implementation. - void OnShutdownComplete() override { - shutdown_unblocker_.Unblock(base::Closure()); - } - - base::Thread io_thread_; - scoped_refptr<base::SingleThreadTaskRunner> io_runner_; - - base::Thread controller_thread_; - scoped_refptr<base::SingleThreadTaskRunner> controller_runner_; - - // Accessed only on the controller thread. - scoped_ptr<ChildControllerImpl> controller_; - - // Used to unblock the main thread on shutdown. - Blocker::Unblocker shutdown_unblocker_; - - DISALLOW_COPY_AND_ASSIGN(AppContext); -}; - -// ChildControllerImpl ------------------------------------------------------ - -class ChildControllerImpl : public ChildController, public ErrorHandler { - public: - ~ChildControllerImpl() override { - DCHECK(thread_checker_.CalledOnValidThread()); - - // TODO(vtl): Pass in the result from |MainMain()|. - on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED); - } - - // To be executed on the controller thread. Creates the |ChildController|, - // etc. - static void Init(AppContext* app_context, - embedder::ScopedPlatformHandle platform_channel, - const Blocker::Unblocker& unblocker) { - DCHECK(app_context); - DCHECK(platform_channel.is_valid()); - - DCHECK(!app_context->controller()); - - scoped_ptr<ChildControllerImpl> impl( - new ChildControllerImpl(app_context, unblocker)); - - ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel( - platform_channel.Pass(), app_context->io_runner(), - base::Bind(&ChildControllerImpl::DidCreateChannel, - base::Unretained(impl.get())), - base::MessageLoopProxy::current())); - - impl->Bind(host_message_pipe.Pass()); - - app_context->set_controller(impl.Pass()); - } - - void Bind(ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); } - - // |ErrorHandler| methods: - void OnConnectionError() override { - // A connection error means the connection to the shell is lost. This is not - // recoverable. - LOG(ERROR) << "Connection error to the shell."; - _exit(1); - } - - // |ChildController| methods: - void StartApp(const String& app_path, - bool clean_app_path, - InterfaceRequest<Application> application_request, - const StartAppCallback& on_app_complete) override { - DVLOG(2) << "ChildControllerImpl::StartApp(" << app_path << ", ...)"; - DCHECK(thread_checker_.CalledOnValidThread()); - - on_app_complete_ = on_app_complete; - unblocker_.Unblock(base::Bind(&ChildControllerImpl::StartAppOnMainThread, - base::FilePath::FromUTF8Unsafe(app_path), - clean_app_path - ? NativeApplicationCleanup::DELETE - : NativeApplicationCleanup::DONT_DELETE, - base::Passed(&application_request))); - } - - void ExitNow(int32_t exit_code) override { - DVLOG(2) << "ChildControllerImpl::ExitNow(" << exit_code << ")"; - _exit(exit_code); - } - - private: - ChildControllerImpl(AppContext* app_context, - const Blocker::Unblocker& unblocker) - : app_context_(app_context), - unblocker_(unblocker), - channel_info_(nullptr), - binding_(this) { - binding_.set_error_handler(this); - } - - // Callback for |embedder::CreateChannel()|. - void DidCreateChannel(embedder::ChannelInfo* channel_info) { - DVLOG(2) << "ChildControllerImpl::DidCreateChannel()"; - DCHECK(thread_checker_.CalledOnValidThread()); - channel_info_ = channel_info; - } - - static void StartAppOnMainThread( - const base::FilePath& app_path, - NativeApplicationCleanup cleanup, - InterfaceRequest<Application> application_request) { - // TODO(vtl): This is copied from in_process_native_runner.cc. - DVLOG(2) << "Loading/running Mojo app from " << app_path.value() - << " out of process"; - - // We intentionally don't unload the native library as its lifetime is the - // same as that of the process. - base::NativeLibrary app_library = LoadNativeApplication(app_path, cleanup); - RunNativeApplication(app_library, application_request.Pass()); - } - - base::ThreadChecker thread_checker_; - AppContext* const app_context_; - Blocker::Unblocker unblocker_; - StartAppCallback on_app_complete_; - - embedder::ChannelInfo* channel_info_; - Binding<ChildController> binding_; - - DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); -}; - -} // namespace - -int ChildProcessMain() { - DVLOG(2) << "ChildProcessMain()"; - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kWaitForDebugger)) { - std::string app = command_line.GetSwitchValueASCII(switches::kApp); -#if defined(OS_WIN) - MessageBox(NULL, command_line.GetSwitchValueNative(switches::kApp).c_str(), - command_line.GetSwitchValueNative(switches::kApp).c_str(), - MB_OK | MB_SETFOREGROUND); -#else - LOG(ERROR) << command_line.GetSwitchValueASCII(switches::kApp) - << " waiting for GDB. pid: " << getpid(); - base::debug::WaitForDebugger(60, true); -#endif - } - - embedder::ScopedPlatformHandle platform_channel = - embedder::PlatformChannelPair::PassClientHandleFromParentProcess( - command_line); - CHECK(platform_channel.is_valid()); - - DCHECK(!base::MessageLoop::current()); - - AppContext app_context; - app_context.Init(); - - Blocker blocker; - app_context.controller_runner()->PostTask( - FROM_HERE, - base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), - base::Passed(&platform_channel), blocker.GetUnblocker())); - // This will block, then run whatever the controller wants. - blocker.Block(); - - app_context.Shutdown(); - - return 0; -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/child_process.h b/mojo/shell/child_process.h deleted file mode 100644 index c0cc431..0000000 --- a/mojo/shell/child_process.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2014 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_SHELL_CHILD_PROCESS_H_ -#define MOJO_SHELL_CHILD_PROCESS_H_ - -namespace mojo { -namespace shell { - -// Main method for a child process. -int ChildProcessMain(); - -} // namespace shell -} // namespace mojo - -#endif // MOJO_SHELL_CHILD_PROCESS_H_ diff --git a/mojo/shell/child_process.mojom b/mojo/shell/child_process.mojom deleted file mode 100644 index dd423e2..0000000 --- a/mojo/shell/child_process.mojom +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2014 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. - -module mojo.shell; - -import "mojo/public/interfaces/application/application.mojom"; - -interface ChildController { - // Starts the app at the given path (deleting it if |clean_app_path| is true). - StartApp(string app_path, - bool clean_app_path, - mojo.Application& application_request) => (int32 result); - - // Exits the child process now (with no cleanup), with the given exit code. - ExitNow(int32 exit_code); -}; diff --git a/mojo/shell/child_process_host.cc b/mojo/shell/child_process_host.cc deleted file mode 100644 index 787233c..0000000 --- a/mojo/shell/child_process_host.cc +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2014 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/shell/child_process_host.h" - -#include "base/base_switches.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/process/kill.h" -#include "base/process/launch.h" -#include "base/stl_util.h" -#include "base/strings/string_split.h" -#include "base/task_runner.h" -#include "base/task_runner_util.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/shell/context.h" -#include "mojo/shell/switches.h" -#include "mojo/shell/task_runners.h" -#include "ui/gl/gl_switches.h" - -namespace mojo { -namespace shell { - -ChildProcessHost::ChildProcessHost(Context* context, const std::string& name) - : context_(context), name_(name), channel_info_(nullptr) { - platform_channel_ = platform_channel_pair_.PassServerHandle(); - DCHECK(!name.empty()); - CHECK(platform_channel_.is_valid()); -} - -ChildProcessHost::~ChildProcessHost() { - if (child_process_.IsValid()) { - LOG(WARNING) << "Destroying ChildProcessHost with unjoined child"; - child_process_.Close(); - } -} - -void ChildProcessHost::Start() { - DCHECK(!child_process_.IsValid()); - DCHECK(platform_channel_.is_valid()); - - ScopedMessagePipeHandle handle(embedder::CreateChannel( - platform_channel_.Pass(), context_->task_runners()->io_runner(), - base::Bind(&ChildProcessHost::DidCreateChannel, base::Unretained(this)), - base::MessageLoop::current()->message_loop_proxy())); - - controller_.Bind(handle.Pass()); - - CHECK(base::PostTaskAndReplyWithResult( - context_->task_runners()->blocking_pool(), FROM_HERE, - base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)), - base::Bind(&ChildProcessHost::DidStart, base::Unretained(this)))); -} - -int ChildProcessHost::Join() { - DCHECK(child_process_.IsValid()); - int rv = -1; - LOG_IF(ERROR, !child_process_.WaitForExit(&rv)) - << "Failed to wait for child process"; - child_process_.Close(); - return rv; -} - -void ChildProcessHost::StartApp( - const String& app_path, - bool clean_app_path, - InterfaceRequest<Application> application_request, - const ChildController::StartAppCallback& on_app_complete) { - DCHECK(controller_); - - on_app_complete_ = on_app_complete; - controller_->StartApp( - app_path, clean_app_path, application_request.Pass(), - base::Bind(&ChildProcessHost::AppCompleted, base::Unretained(this))); -} - -void ChildProcessHost::ExitNow(int32_t exit_code) { - DCHECK(controller_); - - controller_->ExitNow(exit_code); -} - -void ChildProcessHost::DidStart(bool success) { - DVLOG(2) << "ChildProcessHost::DidStart()"; - - if (!success) { - LOG(ERROR) << "Failed to start child process"; - AppCompleted(MOJO_RESULT_UNKNOWN); - return; - } -} - -bool ChildProcessHost::DoLaunch() { - static const char* kForwardSwitches[] = { - switches::kOverrideUseGLWithOSMesaForTests, - switches::kTraceToConsole, - switches::kV, - switches::kVModule, - }; - - const base::CommandLine* parent_command_line = - base::CommandLine::ForCurrentProcess(); - base::CommandLine child_command_line(parent_command_line->GetProgram()); - child_command_line.CopySwitchesFrom(*parent_command_line, kForwardSwitches, - arraysize(kForwardSwitches)); - child_command_line.AppendSwitchASCII(switches::kApp, name_); - child_command_line.AppendSwitch(switches::kChildProcess); - if (parent_command_line->HasSwitch(switches::kWaitForDebugger)) { - std::vector<std::string> apps_to_debug; - base::SplitString( - parent_command_line->GetSwitchValueASCII(switches::kWaitForDebugger), - ',', &apps_to_debug); - if (apps_to_debug.empty() || ContainsValue(apps_to_debug, name_)) - child_command_line.AppendSwitch(switches::kWaitForDebugger); - } - - auto args = parent_command_line->GetArgs(); - for (const auto& arg : args) - child_command_line.AppendArgNative(arg); - - embedder::HandlePassingInformation handle_passing_info; - platform_channel_pair_.PrepareToPassClientHandleToChildProcess( - &child_command_line, &handle_passing_info); - - base::LaunchOptions options; -#if defined(OS_WIN) - options.handles_to_inherit = &handle_passing_info; -#elif defined(OS_POSIX) - options.fds_to_remap = &handle_passing_info; -#endif - DVLOG(2) << "Launching child with command line: " - << child_command_line.GetCommandLineString(); - child_process_ = base::LaunchProcess(child_command_line, options); - if (!child_process_.IsValid()) - return false; - - platform_channel_pair_.ChildProcessLaunched(); - return true; -} - -void ChildProcessHost::AppCompleted(int32_t result) { - if (!on_app_complete_.is_null()) { - auto on_app_complete = on_app_complete_; - on_app_complete_.reset(); - on_app_complete.Run(result); - } -} - -void ChildProcessHost::DidCreateChannel(embedder::ChannelInfo* channel_info) { - DVLOG(2) << "AppChildProcessHost::DidCreateChannel()"; - - CHECK(channel_info); - channel_info_ = channel_info; -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/child_process_host.h b/mojo/shell/child_process_host.h deleted file mode 100644 index bc30206..0000000 --- a/mojo/shell/child_process_host.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2014 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 SHELL_CHILD_PROCESS_HOST_H_ -#define SHELL_CHILD_PROCESS_HOST_H_ - -#include "base/macros.h" -#include "base/process/process.h" -#include "mojo/edk/embedder/channel_info_forward.h" -#include "mojo/edk/embedder/platform_channel_pair.h" -#include "mojo/edk/embedder/scoped_platform_handle.h" -#include "mojo/shell/child_process.mojom.h" -#include "mojo/shell/child_process_host.h" - -namespace mojo { -namespace shell { - -class Context; - -// This class represents a "child process host". Handles launching and -// connecting a platform-specific "pipe" to the child, and supports joining the -// child process. Currently runs a single app (loaded from the file system). -// -// This class is not thread-safe. It should be created/used/destroyed on a -// single thread. -// -// Note: Does not currently work on Windows before Vista. -// Note: After |Start()|, |StartApp| must be called and this object must -// remained alive until the |on_app_complete| callback is called. -class ChildProcessHost { - public: - // |name| is just for debugging ease. - ChildProcessHost(Context* context, const std::string& name); - virtual ~ChildProcessHost(); - - // |Start()|s the child process; calls |DidStart()| (on the thread on which - // |Start()| was called) when the child has been started (or failed to start). - // After calling |Start()|, this object must not be destroyed until - // |DidStart()| has been called. - // TODO(vtl): Consider using weak pointers and removing this requirement. - void Start(); - - // Waits for the child process to terminate, and returns its exit code. - // Note: If |Start()| has been called, this must not be called until the - // callback has been called. - int Join(); - - // See |ChildController|: - void StartApp(const String& app_path, - bool clean_app_path, - InterfaceRequest<Application> application_request, - const ChildController::StartAppCallback& on_app_complete); - void ExitNow(int32_t exit_code); - - protected: - // virtual for testing. - virtual void DidStart(bool success); - - private: - bool DoLaunch(); - - void AppCompleted(int32_t result); - - // Callback for |embedder::CreateChannel()|. - void DidCreateChannel(embedder::ChannelInfo* channel_info); - - Context* const context_; - const std::string name_; - base::Process child_process_; - embedder::PlatformChannelPair platform_channel_pair_; - ChildControllerPtr controller_; - embedder::ChannelInfo* channel_info_; - ChildController::StartAppCallback on_app_complete_; - - // Platform-specific "pipe" to the child process. Valid immediately after - // creation. - embedder::ScopedPlatformHandle platform_channel_; - - DISALLOW_COPY_AND_ASSIGN(ChildProcessHost); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_CHILD_PROCESS_HOST_H_ diff --git a/mojo/shell/child_process_host_unittest.cc b/mojo/shell/child_process_host_unittest.cc deleted file mode 100644 index 8798130..0000000 --- a/mojo/shell/child_process_host_unittest.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2014 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. - -// Note: This file also tests child_process.*. - -#include "mojo/shell/child_process_host.h" - -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "mojo/common/message_pump_mojo.h" -#include "mojo/shell/context.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace shell { -namespace { - -// Subclass just so we can observe |DidStart()|. -class TestChildProcessHost : public ChildProcessHost { - public: - explicit TestChildProcessHost(Context* context) - : ChildProcessHost(context, "test") {} - ~TestChildProcessHost() override {} - - void DidStart(bool success) override { - EXPECT_TRUE(success); - ChildProcessHost::DidStart(success); - base::MessageLoop::current()->QuitWhenIdle(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(TestChildProcessHost); -}; - -#if defined(OS_ANDROID) -// TODO(qsr): Multiprocess shell tests are not supported on android. -#define MAYBE_StartJoin DISABLED_StartJoin -#else -#define MAYBE_StartJoin StartJoin -#endif // defined(OS_ANDROID) -// Just tests starting the child process and joining it (without starting an -// app). -TEST(ChildProcessHostTest, MAYBE_StartJoin) { - Context context; - base::MessageLoop message_loop( - scoped_ptr<base::MessagePump>(new common::MessagePumpMojo())); - context.Init(); - TestChildProcessHost child_process_host(&context); - child_process_host.Start(); - message_loop.Run(); - child_process_host.ExitNow(123); - int exit_code = child_process_host.Join(); - VLOG(2) << "Joined child: exit_code = " << exit_code; - EXPECT_EQ(123, exit_code); - - context.Shutdown(); -} - -} // namespace -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/context.cc b/mojo/shell/context.cc deleted file mode 100644 index 593dd1d..0000000 --- a/mojo/shell/context.cc +++ /dev/null @@ -1,324 +0,0 @@ -// 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. - -#include "mojo/shell/context.h" - -#include <vector> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/lazy_instance.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/trace_event/trace_event.h" -#include "build/build_config.h" -#include "mojo/common/trace_controller_impl.h" -#include "mojo/common/tracing_impl.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/simple_platform_support.h" -#include "mojo/public/cpp/application/application_connection.h" -#include "mojo/public/cpp/application/application_delegate.h" -#include "mojo/public/cpp/application/application_impl.h" -#include "mojo/services/tracing/tracing.mojom.h" -#include "mojo/shell/application_manager/application_loader.h" -#include "mojo/shell/application_manager/application_manager.h" -#include "mojo/shell/filename_util.h" -#include "mojo/shell/in_process_native_runner.h" -#include "mojo/shell/out_of_process_native_runner.h" -#include "mojo/shell/switches.h" -#include "url/gurl.h" - -namespace mojo { -namespace shell { -namespace { - -// Used to ensure we only init once. -class Setup { - public: - Setup() { - embedder::Init(make_scoped_ptr(new embedder::SimplePlatformSupport())); - } - - ~Setup() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Setup); -}; - -bool ConfigureURLMappings(const base::CommandLine& command_line, - Context* context) { - URLResolver* resolver = context->url_resolver(); - - // Configure the resolution of unknown mojo: URLs. - GURL base_url; - if (command_line.HasSwitch(switches::kOrigin)) - base_url = GURL(command_line.GetSwitchValueASCII(switches::kOrigin)); - else - // Use the shell's file root if the base was not specified. - base_url = context->ResolveShellFileURL(""); - - if (!base_url.is_valid()) - return false; - - resolver->SetMojoBaseURL(base_url); - - // The network service must be loaded from the filesystem. - // This mapping is done before the command line URL mapping are processed, so - // that it can be overridden. - resolver->AddURLMapping( - GURL("mojo:network_service"), - context->ResolveShellFileURL("file:network_service.mojo")); - - // Command line URL mapping. - std::vector<URLResolver::OriginMapping> origin_mappings = - URLResolver::GetOriginMappings(command_line.argv()); - for (const auto& origin_mapping : origin_mappings) - resolver->AddOriginMapping(GURL(origin_mapping.origin), - GURL(origin_mapping.base_url)); - - if (command_line.HasSwitch(switches::kURLMappings)) { - const std::string mappings = - command_line.GetSwitchValueASCII(switches::kURLMappings); - - base::StringPairs pairs; - if (!base::SplitStringIntoKeyValuePairs(mappings, '=', ',', &pairs)) - return false; - using StringPair = std::pair<std::string, std::string>; - for (const StringPair& pair : pairs) { - const GURL from(pair.first); - const GURL to = context->ResolveCommandLineURL(pair.second); - if (!from.is_valid() || !to.is_valid()) - return false; - resolver->AddURLMapping(from, to); - } - } - - return true; -} - -void InitContentHandlers(ApplicationManager* manager, - const base::CommandLine& command_line) { - // Default content handlers. - manager->RegisterContentHandler("application/pdf", GURL("mojo:pdf_viewer")); - manager->RegisterContentHandler("image/png", GURL("mojo:png_viewer")); - manager->RegisterContentHandler("text/html", GURL("mojo:html_viewer")); - - // Command-line-specified content handlers. - std::string handlers_spec = - command_line.GetSwitchValueASCII(switches::kContentHandlers); - if (handlers_spec.empty()) - return; - -#if defined(OS_ANDROID) - // TODO(eseidel): On Android we pass command line arguments is via the - // 'parameters' key on the intent, which we specify during 'am shell start' - // via --esa, however that expects comma-separated values and says: - // am shell --help: - // [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]] - // (to embed a comma into a string escape it using "\,") - // Whatever takes 'parameters' and constructs a CommandLine is failing to - // un-escape the commas, we need to move this fix to that file. - ReplaceSubstringsAfterOffset(&handlers_spec, 0, "\\,", ","); -#endif - - std::vector<std::string> parts; - base::SplitString(handlers_spec, ',', &parts); - if (parts.size() % 2 != 0) { - LOG(ERROR) << "Invalid value for switch " << switches::kContentHandlers - << ": must be a comma-separated list of mimetype/url pairs." - << handlers_spec; - return; - } - - for (size_t i = 0; i < parts.size(); i += 2) { - GURL url(parts[i + 1]); - if (!url.is_valid()) { - LOG(ERROR) << "Invalid value for switch " << switches::kContentHandlers - << ": '" << parts[i + 1] << "' is not a valid URL."; - return; - } - // TODO(eseidel): We should also validate that the mimetype is valid - // net/base/mime_util.h could do this, but we don't want to depend on net. - manager->RegisterContentHandler(parts[i], url); - } -} - -void InitNativeOptions(ApplicationManager* manager, - const base::CommandLine& command_line) { - std::vector<std::string> force_in_process_url_list; - base::SplitString(command_line.GetSwitchValueASCII(switches::kForceInProcess), - ',', &force_in_process_url_list); - for (const auto& force_in_process_url : force_in_process_url_list) { - GURL gurl(force_in_process_url); - if (!gurl.is_valid()) { - LOG(ERROR) << "Invalid value for switch " << switches::kForceInProcess - << ": '" << force_in_process_url << "'is not a valid URL."; - return; - } - - NativeRunnerFactory::Options options; - options.force_in_process = true; - manager->SetNativeOptionsForURL(options, gurl); - } -} - -class TracingServiceProvider : public ServiceProvider { - public: - explicit TracingServiceProvider(InterfaceRequest<ServiceProvider> request) - : binding_(this, request.Pass()) {} - ~TracingServiceProvider() override {} - - void ConnectToService(const String& service_name, - ScopedMessagePipeHandle client_handle) override { - if (service_name == tracing::TraceController::Name_) { - new TraceControllerImpl( - MakeRequest<tracing::TraceController>(client_handle.Pass())); - } - } - - private: - StrongBinding<ServiceProvider> binding_; - - DISALLOW_COPY_AND_ASSIGN(TracingServiceProvider); -}; - -} // namespace - -Context::Context() : application_manager_(this) { - DCHECK(!base::MessageLoop::current()); - - // By default assume that the local apps reside alongside the shell. - // TODO(ncbray): really, this should be passed in rather than defaulting. - // This default makes sense for desktop but not Android. - base::FilePath shell_dir; - PathService::Get(base::DIR_MODULE, &shell_dir); - SetShellFileRoot(shell_dir); - - base::FilePath cwd; - PathService::Get(base::DIR_CURRENT, &cwd); - SetCommandLineCWD(cwd); -} - -Context::~Context() { - DCHECK(!base::MessageLoop::current()); -} - -// static -void Context::EnsureEmbedderIsInitialized() { - static base::LazyInstance<Setup>::Leaky setup = LAZY_INSTANCE_INITIALIZER; - setup.Get(); -} - -void Context::SetShellFileRoot(const base::FilePath& path) { - shell_file_root_ = AddTrailingSlashIfNeeded(FilePathToFileURL(path)); -} - -GURL Context::ResolveShellFileURL(const std::string& path) { - return shell_file_root_.Resolve(path); -} - -void Context::SetCommandLineCWD(const base::FilePath& path) { - command_line_cwd_ = AddTrailingSlashIfNeeded(FilePathToFileURL(path)); -} - -GURL Context::ResolveCommandLineURL(const std::string& path) { - return command_line_cwd_.Resolve(path); -} - -bool Context::Init() { - TRACE_EVENT0("mojo_shell", "Context::Init"); - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - - EnsureEmbedderIsInitialized(); - task_runners_.reset( - new TaskRunners(base::MessageLoop::current()->message_loop_proxy())); - - // TODO(vtl): Probably these failures should be checked before |Init()|, and - // this function simply shouldn't fail. - if (!shell_file_root_.is_valid()) - return false; - if (!ConfigureURLMappings(command_line, this)) - return false; - - // TODO(vtl): This should be MASTER, not NONE. - embedder::InitIPCSupport( - embedder::ProcessType::NONE, task_runners_->shell_runner(), this, - task_runners_->io_runner(), embedder::ScopedPlatformHandle()); - - scoped_ptr<NativeRunnerFactory> runner_factory; - if (command_line.HasSwitch(switches::kEnableMultiprocess)) - runner_factory.reset(new OutOfProcessNativeRunnerFactory(this)); - else - runner_factory.reset(new InProcessNativeRunnerFactory(this)); - application_manager_.set_blocking_pool(task_runners_->blocking_pool()); - application_manager_.set_native_runner_factory(runner_factory.Pass()); - application_manager_.set_disable_cache( - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableCache)); - - InitContentHandlers(&application_manager_, command_line); - InitNativeOptions(&application_manager_, command_line); - - ServiceProviderPtr tracing_service_provider_ptr; - new TracingServiceProvider(GetProxy(&tracing_service_provider_ptr)); - application_manager_.ConnectToApplication( - GURL("mojo:tracing"), GURL(""), nullptr, - tracing_service_provider_ptr.Pass(), base::Closure()); - - return true; -} - -void Context::Shutdown() { - TRACE_EVENT0("mojo_shell", "Context::Shutdown"); - DCHECK_EQ(base::MessageLoop::current()->task_runner(), - task_runners_->shell_runner()); - embedder::ShutdownIPCSupport(); - // We'll quit when we get OnShutdownComplete(). - base::MessageLoop::current()->Run(); -} - -GURL Context::ResolveMappings(const GURL& url) { - return url_resolver_.ApplyMappings(url); -} - -GURL Context::ResolveMojoURL(const GURL& url) { - return url_resolver_.ResolveMojoURL(url); -} - -void Context::OnShutdownComplete() { - DCHECK_EQ(base::MessageLoop::current()->task_runner(), - task_runners_->shell_runner()); - base::MessageLoop::current()->Quit(); -} - -void Context::Run(const GURL& url) { - ServiceProviderPtr services; - ServiceProviderPtr exposed_services; - - app_urls_.insert(url); - application_manager_.ConnectToApplication( - url, GURL(), GetProxy(&services), exposed_services.Pass(), - base::Bind(&Context::OnApplicationEnd, base::Unretained(this), url)); -} - -void Context::OnApplicationEnd(const GURL& url) { - if (app_urls_.find(url) != app_urls_.end()) { - app_urls_.erase(url); - if (app_urls_.empty() && base::MessageLoop::current()->is_running()) { - DCHECK_EQ(base::MessageLoop::current()->task_runner(), - task_runners_->shell_runner()); - base::MessageLoop::current()->Quit(); - } - } -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/context.h b/mojo/shell/context.h deleted file mode 100644 index e1073f3..0000000 --- a/mojo/shell/context.h +++ /dev/null @@ -1,87 +0,0 @@ -// 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. - -#ifndef SHELL_CONTEXT_H_ -#define SHELL_CONTEXT_H_ - -#include <string> - -#include "base/macros.h" -#include "mojo/edk/embedder/process_delegate.h" -#include "mojo/shell/application_manager/application_manager.h" -#include "mojo/shell/task_runners.h" -#include "mojo/shell/url_resolver.h" - -namespace mojo { -namespace shell { - -class NativeApplicationLoader; - -// The "global" context for the shell's main process. -class Context : public ApplicationManager::Delegate, - public embedder::ProcessDelegate { - public: - Context(); - ~Context() override; - - static void EnsureEmbedderIsInitialized(); - - // Point to the directory containing installed services, such as the network - // service. By default this directory is used as the base URL for resolving - // unknown mojo: URLs. The network service will be loaded from this directory, - // even when the base URL for unknown mojo: URLs is overridden. - void SetShellFileRoot(const base::FilePath& path); - - // Resolve an URL relative to the shell file root. This is a nop for - // everything but relative file URLs or URLs without a scheme. - GURL ResolveShellFileURL(const std::string& path); - - // Override the CWD, which is used for resolving file URLs passed in from the - // command line. - void SetCommandLineCWD(const base::FilePath& path); - - // Resolve an URL relative to the CWD mojo_shell was invoked from. This is a - // nop for everything but relative file URLs or URLs without a scheme. - GURL ResolveCommandLineURL(const std::string& path); - - // This must be called with a message loop set up for the current thread, - // which must remain alive until after Shutdown() is called. Returns true on - // success. - bool Init(); - - // If Init() was called and succeeded, this must be called before destruction. - void Shutdown(); - - void Run(const GURL& url); - - TaskRunners* task_runners() { return task_runners_.get(); } - ApplicationManager* application_manager() { return &application_manager_; } - URLResolver* url_resolver() { return &url_resolver_; } - - private: - class NativeViewportApplicationLoader; - - // ApplicationManager::Delegate overrides. - GURL ResolveMappings(const GURL& url) override; - GURL ResolveMojoURL(const GURL& url) override; - - // ProcessDelegate implementation. - void OnShutdownComplete() override; - - void OnApplicationEnd(const GURL& url); - - std::set<GURL> app_urls_; - scoped_ptr<TaskRunners> task_runners_; - ApplicationManager application_manager_; - URLResolver url_resolver_; - GURL shell_file_root_; - GURL command_line_cwd_; - - DISALLOW_COPY_AND_ASSIGN(Context); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_CONTEXT_H_ diff --git a/mojo/shell/application_manager/data_pipe_peek.cc b/mojo/shell/data_pipe_peek.cc index 9109b51..4c74c55 100644 --- a/mojo/shell/application_manager/data_pipe_peek.cc +++ b/mojo/shell/data_pipe_peek.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/data_pipe_peek.h" +#include "mojo/shell/data_pipe_peek.h" #include <stdint.h> diff --git a/mojo/shell/application_manager/data_pipe_peek.h b/mojo/shell/data_pipe_peek.h index 5ffbc5b..0bcf1dd 100644 --- a/mojo/shell/application_manager/data_pipe_peek.h +++ b/mojo/shell/data_pipe_peek.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_DATA_PIPE_SEEK_H_ -#define SHELL_APPLICATION_MANAGER_DATA_PIPE_SEEK_H_ +#ifndef MOJO_SHELL_DATA_PIPE_PEEK_H_ +#define MOJO_SHELL_DATA_PIPE_PEEK_H_ #include <string> @@ -35,4 +35,4 @@ bool BlockingPeekNBytes(DataPipeConsumerHandle source, } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_DATA_PIPE_SEEK_H_ +#endif // MOJO_SHELL_DATA_PIPE_PEEK_H_ diff --git a/mojo/shell/data_pipe_peek_unittest.cc b/mojo/shell/data_pipe_peek_unittest.cc deleted file mode 100644 index 126901b..0000000 --- a/mojo/shell/data_pipe_peek_unittest.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2014 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/shell/application_manager/data_pipe_peek.h" - -#include "mojo/shell/context.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace shell { -namespace { - -TEST(DataPipePeek, PeekNBytes) { - Context::EnsureEmbedderIsInitialized(); - - DataPipe data_pipe; - DataPipeConsumerHandle consumer(data_pipe.consumer_handle.get()); - DataPipeProducerHandle producer(data_pipe.producer_handle.get()); - - // Inialize the pipe with 4 bytes. - - const char* s4 = "1234"; - uint32_t num_bytes4 = 4; - EXPECT_EQ(MOJO_RESULT_OK, - WriteDataRaw(producer, s4, &num_bytes4, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(4u, num_bytes4); - - // We're not consuming data, so peeking for 4 bytes should always succeed. - - std::string bytes; - MojoDeadline timeout = 0; - EXPECT_TRUE(BlockingPeekNBytes(consumer, &bytes, num_bytes4, timeout)); - EXPECT_EQ(bytes, std::string(s4)); - - timeout = 1000; // 1ms - EXPECT_TRUE(BlockingPeekNBytes(consumer, &bytes, num_bytes4, timeout)); - EXPECT_EQ(bytes, std::string(s4)); - - timeout = MOJO_DEADLINE_INDEFINITE; - EXPECT_TRUE(BlockingPeekNBytes(consumer, &bytes, num_bytes4, timeout)); - EXPECT_EQ(bytes, std::string(s4)); - - // Peeking for 5 bytes should fail, until another byte is written. - - uint32_t bytes1 = 1; - uint32_t num_bytes5 = 5; - const char* s1 = "5"; - const char* s5 = "12345"; - - timeout = 0; - EXPECT_FALSE(BlockingPeekNBytes(consumer, &bytes, num_bytes5, timeout)); - - timeout = 500; // Should cause peek to timeout after about 0.5ms. - EXPECT_FALSE(BlockingPeekNBytes(consumer, &bytes, num_bytes5, timeout)); - - EXPECT_EQ(MOJO_RESULT_OK, - WriteDataRaw(producer, s1, &bytes1, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(1u, bytes1); - - EXPECT_TRUE(BlockingPeekNBytes(consumer, &bytes, num_bytes5, timeout)); - EXPECT_EQ(bytes, std::string(s5)); - - // If the consumer side of the pipe is closed, peek should fail. - - data_pipe.consumer_handle.reset(); - timeout = 0; - EXPECT_FALSE(BlockingPeekNBytes(consumer, &bytes, num_bytes5, timeout)); -} - -TEST(DataPipePeek, PeekLine) { - Context::EnsureEmbedderIsInitialized(); - - DataPipe data_pipe; - DataPipeConsumerHandle consumer(data_pipe.consumer_handle.get()); - DataPipeProducerHandle producer(data_pipe.producer_handle.get()); - - // Inialize the pipe with 4 bytes and no newline. - - const char* s4 = "1234"; - uint32_t num_bytes4 = 4; - EXPECT_EQ(MOJO_RESULT_OK, - WriteDataRaw(producer, s4, &num_bytes4, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(4u, num_bytes4); - - // Peeking for a line should fail. - - std::string str; - size_t max_str_length = 5; - MojoDeadline timeout = 0; - EXPECT_FALSE(BlockingPeekLine(consumer, &str, max_str_length, timeout)); - - // Writing a newline should cause PeekLine to succeed. - - uint32_t bytes1 = 1; - const char* s1 = "\n"; - EXPECT_EQ(MOJO_RESULT_OK, - WriteDataRaw(producer, s1, &bytes1, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(1u, bytes1); - - EXPECT_TRUE(BlockingPeekLine(consumer, &str, max_str_length, timeout)); - EXPECT_EQ(str, std::string(s4) + "\n"); - - // If the max_line_length parameter is less than the length of the - // newline terminated string, then peek should fail. - - max_str_length = 3; - EXPECT_FALSE(BlockingPeekLine(consumer, &str, max_str_length, timeout)); -} - -} // namespace -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/desktop/launcher_process.cc b/mojo/shell/desktop/launcher_process.cc deleted file mode 100644 index 1b47cc8..0000000 --- a/mojo/shell/desktop/launcher_process.cc +++ /dev/null @@ -1,136 +0,0 @@ -// 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. - -#include <stdio.h> -#include <string.h> - -#include <algorithm> -#include <iostream> - -#include "base/base_switches.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_util.h" -#include "base/message_loop/message_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/trace_event/trace_event.h" -#include "mojo/shell/context.h" -#include "mojo/shell/switches.h" - -namespace mojo { -namespace shell { -namespace { - -// Whether we're currently tracing. -bool g_tracing = false; - -// Number of tracing blocks written. -uint32_t g_blocks = 0; - -// Trace file, if open. -FILE* g_trace_file = nullptr; - -void WriteTraceDataCollected( - base::WaitableEvent* event, - const scoped_refptr<base::RefCountedString>& events_str, - bool has_more_events) { - if (g_blocks) { - fwrite(",", 1, 1, g_trace_file); - } - - ++g_blocks; - fwrite(events_str->data().c_str(), 1, events_str->data().length(), - g_trace_file); - if (!has_more_events) { - static const char kEnd[] = "]}"; - fwrite(kEnd, 1, strlen(kEnd), g_trace_file); - PCHECK(fclose(g_trace_file) == 0); - g_trace_file = nullptr; - event->Signal(); - } -} - -void EndTraceAndFlush(base::WaitableEvent* event) { - g_trace_file = fopen("mojo_shell.trace", "w+"); - PCHECK(g_trace_file); - static const char kStart[] = "{\"traceEvents\":["; - fwrite(kStart, 1, strlen(kStart), g_trace_file); - base::trace_event::TraceLog::GetInstance()->SetDisabled(); - base::trace_event::TraceLog::GetInstance()->Flush( - base::Bind(&WriteTraceDataCollected, base::Unretained(event))); -} - -void StopTracingAndFlushToDisk() { - g_tracing = false; - base::trace_event::TraceLog::GetInstance()->SetDisabled(); - base::WaitableEvent flush_complete_event(false, false); - // TraceLog::Flush requires a message loop but we've already shut ours down. - // Spin up a new thread to flush things out. - base::Thread flush_thread("mojo_shell_trace_event_flush"); - flush_thread.Start(); - flush_thread.message_loop()->PostTask( - FROM_HERE, - base::Bind(EndTraceAndFlush, base::Unretained(&flush_complete_event))); - flush_complete_event.Wait(); -} - -void StartApp(mojo::shell::Context* context) { - // If a mojo app isn't specified (i.e. for an apptest), run the mojo shell's - // window manager. - GURL app_url(GURL("mojo:window_manager")); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - base::CommandLine::StringVector args = command_line->GetArgs(); - for (size_t i = 0; i < args.size(); ++i) { - GURL possible_app(args[i]); - if (possible_app.SchemeIs("mojo")) { - app_url = possible_app; - break; - } - } - - context->Run(app_url); -} - -} // namespace - -int LauncherProcessMain(int argc, char** argv) { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kTraceStartup)) { - g_tracing = true; - base::trace_event::CategoryFilter category_filter( - command_line.GetSwitchValueASCII(switches::kTraceStartup)); - base::trace_event::TraceLog::GetInstance()->SetEnabled( - category_filter, base::trace_event::TraceLog::RECORDING_MODE, - base::trace_event::TraceOptions(base::trace_event::RECORD_UNTIL_FULL)); - } - - // We want the shell::Context to outlive the MessageLoop so that pipes are - // all gracefully closed / error-out before we try to shut the Context down. - mojo::shell::Context shell_context; - { - base::MessageLoop message_loop; - if (!shell_context.Init()) { - return 0; - } - if (g_tracing) { - message_loop.PostDelayedTask(FROM_HERE, - base::Bind(StopTracingAndFlushToDisk), - base::TimeDelta::FromSeconds(5)); - } - - message_loop.PostTask(FROM_HERE, base::Bind(&StartApp, &shell_context)); - message_loop.Run(); - - // Must be called before |message_loop| is destroyed. - shell_context.Shutdown(); - } - - if (g_tracing) - StopTracingAndFlushToDisk(); - return 0; -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/desktop/launcher_process.h b/mojo/shell/desktop/launcher_process.h deleted file mode 100644 index caed878..0000000 --- a/mojo/shell/desktop/launcher_process.h +++ /dev/null @@ -1,17 +0,0 @@ -// 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_SHELL_LAUNCHER_PROCESS_H_ -#define MOJO_SHELL_LAUNCHER_PROCESS_H_ - -namespace mojo { -namespace shell { - -// Main method for the launcher process. -int LauncherProcessMain(int argc, char** argv); - -} // namespace shell -} // namespace mojo - -#endif // MOJO_SHELL_LAUNCHER_PROCESS_H_ diff --git a/mojo/shell/desktop/main.cc b/mojo/shell/desktop/main.cc deleted file mode 100644 index ca89c5d..0000000 --- a/mojo/shell/desktop/main.cc +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "mojo/shell/child_process.h" -#include "mojo/shell/desktop/launcher_process.h" -#include "mojo/shell/init.h" -#include "mojo/shell/switches.h" - -int main(int argc, char** argv) { - base::AtExitManager at_exit; - base::CommandLine::Init(argc, argv); - - mojo::shell::InitializeLogging(); - - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kChildProcess)) - return mojo::shell::ChildProcessMain(); - - return mojo::shell::LauncherProcessMain(argc, argv); -} diff --git a/mojo/shell/application_manager/fetcher.cc b/mojo/shell/fetcher.cc index 78fd125..d9a4e60 100644 --- a/mojo/shell/application_manager/fetcher.cc +++ b/mojo/shell/fetcher.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/fetcher.h" +#include "mojo/shell/fetcher.h" #include "url/gurl.h" diff --git a/mojo/shell/application_manager/fetcher.h b/mojo/shell/fetcher.h index 2257f75..21cad3f 100644 --- a/mojo/shell/application_manager/fetcher.h +++ b/mojo/shell/fetcher.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_FETCHER_H_ -#define SHELL_APPLICATION_MANAGER_FETCHER_H_ +#ifndef MOJO_SHELL_FETCHER_H_ +#define MOJO_SHELL_FETCHER_H_ #include "base/callback.h" #include "base/memory/scoped_ptr.h" @@ -73,4 +73,4 @@ class Fetcher { } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_FETCHER_H_ +#endif // MOJO_SHELL_FETCHER_H_ diff --git a/mojo/shell/filename_util.cc b/mojo/shell/filename_util.cc deleted file mode 100644 index 073bdda..0000000 --- a/mojo/shell/filename_util.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 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/shell/filename_util.h" - -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "url/gurl.h" -#include "url/url_canon_internal.h" -#include "url/url_util.h" - -namespace mojo { -namespace shell { - -// Prefix to prepend to get a file URL. -static const base::FilePath::CharType kFileURLPrefix[] = - FILE_PATH_LITERAL("file://"); - -GURL FilePathToFileURL(const base::FilePath& path) { - // Produce a URL like "file:///C:/foo" for a regular file, or - // "file://///server/path" for UNC. The URL canonicalizer will fix up the - // latter case to be the canonical UNC form: "file://server/path" - base::FilePath::StringType url_string(kFileURLPrefix); - if (!path.IsAbsolute()) { - base::FilePath current_dir; - PathService::Get(base::DIR_CURRENT, ¤t_dir); - url_string.append(current_dir.value()); - url_string.push_back(base::FilePath::kSeparators[0]); - } - url_string.append(path.value()); - - // Now do replacement of some characters. Since we assume the input is a - // literal filename, anything the URL parser might consider special should - // be escaped here. - - // This must be the first substitution since others will introduce percents as - // the escape character - ReplaceSubstringsAfterOffset(&url_string, 0, FILE_PATH_LITERAL("%"), - FILE_PATH_LITERAL("%25")); - - // A semicolon is supposed to be some kind of separator according to RFC 2396. - ReplaceSubstringsAfterOffset(&url_string, 0, FILE_PATH_LITERAL(";"), - FILE_PATH_LITERAL("%3B")); - - ReplaceSubstringsAfterOffset(&url_string, 0, FILE_PATH_LITERAL("#"), - FILE_PATH_LITERAL("%23")); - - ReplaceSubstringsAfterOffset(&url_string, 0, FILE_PATH_LITERAL("?"), - FILE_PATH_LITERAL("%3F")); - -#if defined(OS_POSIX) - ReplaceSubstringsAfterOffset(&url_string, 0, FILE_PATH_LITERAL("\\"), - FILE_PATH_LITERAL("%5C")); -#endif - - return GURL(url_string); -} - -GURL AddTrailingSlashIfNeeded(const GURL& url) { - if (!url.has_path() || *url.path().rbegin() == '/') - return url; - - std::string path(url.path() + '/'); - GURL::Replacements replacements; - replacements.SetPathStr(path); - return url.ReplaceComponents(replacements); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/filename_util.h b/mojo/shell/filename_util.h deleted file mode 100644 index 28d0e78..0000000 --- a/mojo/shell/filename_util.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 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 SHELL_FILENAME_UTIL_H_ -#define SHELL_FILENAME_UTIL_H_ - -class GURL; - -namespace base { -class FilePath; -} - -namespace mojo { -namespace shell { - -// Given the full path to a file name, creates a file: URL. The returned URL -// may not be valid if the input is malformed. -GURL FilePathToFileURL(const base::FilePath& path); - -// This URL is going to be treated as a directory. Ensure there is a trailing -// slash so that GURL.Resolve(...) works correctly. -GURL AddTrailingSlashIfNeeded(const GURL& url); - -} // namespace shell -} // namespace mojo - -#endif // SHELL_FILENAME_UTIL_H_ diff --git a/mojo/shell/application_manager/identity.cc b/mojo/shell/identity.cc index c54f5d8..7eb88c7 100644 --- a/mojo/shell/application_manager/identity.cc +++ b/mojo/shell/identity.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/identity.h" +#include "mojo/shell/identity.h" -#include "mojo/shell/application_manager/query_util.h" +#include "mojo/shell/query_util.h" namespace mojo { namespace shell { diff --git a/mojo/shell/application_manager/identity.h b/mojo/shell/identity.h index 3d7e1d6..ac897a1 100644 --- a/mojo/shell/application_manager/identity.h +++ b/mojo/shell/identity.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_IDENTITY_H_ -#define SHELL_APPLICATION_MANAGER_IDENTITY_H_ +#ifndef MOJO_SHELL_IDENTITY_H_ +#define MOJO_SHELL_IDENTITY_H_ #include "url/gurl.h" @@ -28,4 +28,4 @@ struct Identity { } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_IDENTITY_H_ +#endif // MOJO_SHELL_IDENTITY_H_ diff --git a/mojo/shell/in_process_native_runner.cc b/mojo/shell/in_process_native_runner.cc deleted file mode 100644 index 7431fe0..0000000 --- a/mojo/shell/in_process_native_runner.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 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/shell/in_process_native_runner.h" - -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/location.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/threading/platform_thread.h" -#include "mojo/shell/native_application_support.h" - -namespace mojo { -namespace shell { - -InProcessNativeRunner::InProcessNativeRunner(Context* context) - : cleanup_(NativeApplicationCleanup::DONT_DELETE), app_library_(nullptr) { -} - -InProcessNativeRunner::~InProcessNativeRunner() { - // It is important to let the thread exit before unloading the DSO (when - // app_library_ is destructed), because the library may have registered - // thread-local data and destructors to run on thread termination. - if (thread_) { - DCHECK(thread_->HasBeenStarted()); - DCHECK(!thread_->HasBeenJoined()); - thread_->Join(); - } -} - -void InProcessNativeRunner::Start( - const base::FilePath& app_path, - NativeApplicationCleanup cleanup, - InterfaceRequest<Application> application_request, - const base::Closure& app_completed_callback) { - app_path_ = app_path; - cleanup_ = cleanup; - - DCHECK(!application_request_.is_pending()); - application_request_ = application_request.Pass(); - - DCHECK(app_completed_callback_runner_.is_null()); - app_completed_callback_runner_ = - base::Bind(&base::TaskRunner::PostTask, base::MessageLoopProxy::current(), - FROM_HERE, app_completed_callback); - - DCHECK(!thread_); - thread_.reset(new base::DelegateSimpleThread(this, "app_thread")); - thread_->Start(); -} - -void InProcessNativeRunner::Run() { - DVLOG(2) << "Loading/running Mojo app in process from library: " - << app_path_.value() - << " thread id=" << base::PlatformThread::CurrentId(); - - // TODO(vtl): ScopedNativeLibrary doesn't have a .get() method! - base::NativeLibrary app_library = LoadNativeApplication(app_path_, cleanup_); - app_library_.Reset(app_library); - RunNativeApplication(app_library, application_request_.Pass()); - app_completed_callback_runner_.Run(); - app_completed_callback_runner_.Reset(); -} - -scoped_ptr<NativeRunner> InProcessNativeRunnerFactory::Create( - const Options& options) { - return make_scoped_ptr(new InProcessNativeRunner(context_)); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/in_process_native_runner.h b/mojo/shell/in_process_native_runner.h deleted file mode 100644 index a5639f4..0000000 --- a/mojo/shell/in_process_native_runner.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2014 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 SHELL_IN_PROCESS_NATIVE_RUNNER_H_ -#define SHELL_IN_PROCESS_NATIVE_RUNNER_H_ - -#include "base/callback.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "base/scoped_native_library.h" -#include "base/threading/simple_thread.h" -#include "mojo/shell/application_manager/native_runner.h" -#include "mojo/shell/native_application_support.h" - -namespace mojo { -namespace shell { - -class Context; - -// An implementation of |NativeRunner| that loads/runs the given app (from the -// file system) on a separate thread (in the current process). -class InProcessNativeRunner : public NativeRunner, - public base::DelegateSimpleThread::Delegate { - public: - explicit InProcessNativeRunner(Context* context); - ~InProcessNativeRunner() override; - - // |NativeRunner| method: - void Start(const base::FilePath& app_path, - NativeApplicationCleanup cleanup, - InterfaceRequest<Application> application_request, - const base::Closure& app_completed_callback) override; - - private: - // |base::DelegateSimpleThread::Delegate| method: - void Run() override; - - base::FilePath app_path_; - NativeApplicationCleanup cleanup_; - InterfaceRequest<Application> application_request_; - base::Callback<bool(void)> app_completed_callback_runner_; - - base::ScopedNativeLibrary app_library_; - scoped_ptr<base::DelegateSimpleThread> thread_; - - DISALLOW_COPY_AND_ASSIGN(InProcessNativeRunner); -}; - -class InProcessNativeRunnerFactory : public NativeRunnerFactory { - public: - explicit InProcessNativeRunnerFactory(Context* context) : context_(context) {} - ~InProcessNativeRunnerFactory() override {} - - scoped_ptr<NativeRunner> Create(const Options& options) override; - - private: - Context* const context_; - - DISALLOW_COPY_AND_ASSIGN(InProcessNativeRunnerFactory); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_IN_PROCESS_NATIVE_RUNNER_H_ diff --git a/mojo/shell/in_process_native_runner_unittest.cc b/mojo/shell/in_process_native_runner_unittest.cc deleted file mode 100644 index 28608c8..0000000 --- a/mojo/shell/in_process_native_runner_unittest.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2014 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/shell/in_process_native_runner.h" - -#include "mojo/shell/context.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace shell { - -TEST(InProcessNativeRunnerTest, NotStarted) { - Context context; - base::MessageLoop loop; - context.Init(); - InProcessNativeRunner runner(&context); - context.Shutdown(); - // Shouldn't crash or DCHECK on destruction. -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/init.cc b/mojo/shell/init.cc deleted file mode 100644 index 71aec63..0000000 --- a/mojo/shell/init.cc +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -#include "mojo/shell/init.h" - -#include "base/logging.h" - -namespace mojo { -namespace shell { - -void InitializeLogging() { - logging::LoggingSettings settings; - settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; - logging::InitLogging(settings); - // To view log output with IDs and timestamps use "adb logcat -v threadtime". - logging::SetLogItems(false, // Process ID - false, // Thread ID - false, // Timestamp - false); // Tick count -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/init.h b/mojo/shell/init.h deleted file mode 100644 index 23a5140..0000000 --- a/mojo/shell/init.h +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -#ifndef SHELL_INIT_H_ -#define SHELL_INIT_H_ - -namespace mojo { -namespace shell { - -// Initialization routines shared by desktop and Android main functions. - -void InitializeLogging(); - -} // namespace shell -} // namespace mojo - -#endif // SHELL_INIT_H_ diff --git a/mojo/shell/application_manager/local_fetcher.cc b/mojo/shell/local_fetcher.cc index a8b889d..a945dc2 100644 --- a/mojo/shell/application_manager/local_fetcher.cc +++ b/mojo/shell/local_fetcher.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/local_fetcher.h" +#include "mojo/shell/local_fetcher.h" #include "base/bind.h" #include "base/files/file_util.h" diff --git a/mojo/shell/application_manager/local_fetcher.h b/mojo/shell/local_fetcher.h index 843108f..774fdfb 100644 --- a/mojo/shell/application_manager/local_fetcher.h +++ b/mojo/shell/local_fetcher.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_LOCAL_FETCHER_H_ -#define SHELL_APPLICATION_MANAGER_LOCAL_FETCHER_H_ +#ifndef MOJO_SHELL_LOCAL_FETCHER_H_ +#define MOJO_SHELL_LOCAL_FETCHER_H_ #include "base/files/file_path.h" #include "mojo/services/network/public/interfaces/url_loader.mojom.h" -#include "mojo/shell/application_manager/fetcher.h" +#include "mojo/shell/fetcher.h" #include "url/gurl.h" namespace mojo { @@ -48,4 +48,4 @@ class LocalFetcher : public Fetcher { } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_LOCAL_FETCHER_H_ +#endif // MOJO_SHELL_LOCAL_FETCHER_H_ diff --git a/mojo/shell/native_application_support.cc b/mojo/shell/native_application_support.cc deleted file mode 100644 index f4ca638..0000000 --- a/mojo/shell/native_application_support.cc +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2014 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/shell/native_application_support.h" - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "mojo/public/platform/native/gles2_impl_chromium_miscellaneous_thunks.h" -#include "mojo/public/platform/native/gles2_impl_chromium_sub_image_thunks.h" -#include "mojo/public/platform/native/gles2_impl_chromium_sync_point_thunks.h" -#include "mojo/public/platform/native/gles2_impl_chromium_texture_mailbox_thunks.h" -#include "mojo/public/platform/native/gles2_impl_occlusion_query_ext_thunks.h" -#include "mojo/public/platform/native/gles2_impl_thunks.h" -#include "mojo/public/platform/native/gles2_thunks.h" -#include "mojo/public/platform/native/system_thunks.h" - -namespace mojo { -namespace shell { - -namespace { - -template <typename Thunks> -bool SetThunks(Thunks (*make_thunks)(), - const char* function_name, - base::NativeLibrary library) { - typedef size_t (*SetThunksFn)(const Thunks* thunks); - SetThunksFn set_thunks = reinterpret_cast<SetThunksFn>( - base::GetFunctionPointerFromNativeLibrary(library, function_name)); - if (!set_thunks) - return false; - Thunks thunks = make_thunks(); - size_t expected_size = set_thunks(&thunks); - if (expected_size > sizeof(Thunks)) { - LOG(ERROR) << "Invalid app library: expected " << function_name - << " to return thunks of size: " << expected_size; - return false; - } - return true; -} - -} // namespace - -base::NativeLibrary LoadNativeApplication(const base::FilePath& app_path, - NativeApplicationCleanup cleanup) { - DVLOG(2) << "Loading Mojo app in process from library: " << app_path.value(); - - base::NativeLibraryLoadError error; - base::NativeLibrary app_library = base::LoadNativeLibrary(app_path, &error); - if (cleanup == NativeApplicationCleanup::DELETE) - DeleteFile(app_path, false); - LOG_IF(ERROR, !app_library) - << "Failed to load app library (error: " << error.ToString() << ")"; - return app_library; -} - -bool RunNativeApplication(base::NativeLibrary app_library, - InterfaceRequest<Application> application_request) { - // Tolerate |app_library| being null, to make life easier for callers. - if (!app_library) - return false; - - if (!SetThunks(&MojoMakeSystemThunks, "MojoSetSystemThunks", app_library)) { - LOG(ERROR) << "MojoSetSystemThunks not found"; - return false; - } - - if (SetThunks(&MojoMakeGLES2ControlThunks, "MojoSetGLES2ControlThunks", - app_library)) { - // If we have the control thunks, we should also have the GLES2 - // implementation thunks. - if (!SetThunks(&MojoMakeGLES2ImplThunks, "MojoSetGLES2ImplThunks", - app_library)) { - LOG(ERROR) - << "MojoSetGLES2ControlThunks found, but not MojoSetGLES2ImplThunks"; - return false; - } - - // If the application is using GLES2 extension points, register those - // thunks. Applications may use or not use any of these, so don't warn if - // they are missing. - SetThunks(MojoMakeGLES2ImplChromiumMiscellaneousThunks, - "MojoSetGLES2ImplChromiumMiscellaneousThunks", app_library); - SetThunks(MojoMakeGLES2ImplChromiumSubImageThunks, - "MojoSetGLES2ImplChromiumSubImageThunks", app_library); - SetThunks(MojoMakeGLES2ImplChromiumTextureMailboxThunks, - "MojoSetGLES2ImplChromiumTextureMailboxThunks", app_library); - SetThunks(MojoMakeGLES2ImplChromiumSyncPointThunks, - "MojoSetGLES2ImplChromiumSyncPointThunks", app_library); - SetThunks(MojoMakeGLES2ImplOcclusionQueryExtThunks, - "MojoSetGLES2ImplOcclusionQueryExtThunks", app_library); - } - // Unlike system thunks, we don't warn on a lack of GLES2 thunks because - // not everything is a visual app. - - // Go shared library support requires us to initialize the runtime before we - // start running any go code. This is a temporary patch. - typedef void (*InitGoRuntimeFn)(); - InitGoRuntimeFn init_go_runtime = reinterpret_cast<InitGoRuntimeFn>( - base::GetFunctionPointerFromNativeLibrary(app_library, "InitGoRuntime")); - if (init_go_runtime) { - DVLOG(2) << "InitGoRuntime: Initializing Go Runtime found in app"; - init_go_runtime(); - } - -#if !defined(OS_WIN) - // On Windows, initializing base::CommandLine with null parameters gets the - // process's command line from the OS. Other platforms need it to be passed - // in. This needs to be passed in before the app initializes the command line, - // which is done as soon as it loads. - typedef void (*InitCommandLineArgs)(int, const char* const*); - InitCommandLineArgs init_command_line_args = - reinterpret_cast<InitCommandLineArgs>( - base::GetFunctionPointerFromNativeLibrary(app_library, - "InitCommandLineArgs")); - if (init_command_line_args) { - int argc = 0; - base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); - const char** argv = new const char* [cmd_line->argv().size()]; - for (auto& arg : cmd_line->argv()) - argv[argc++] = arg.c_str(); - init_command_line_args(argc, argv); - } -#endif - - typedef MojoResult (*MojoMainFunction)(MojoHandle); - MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( - base::GetFunctionPointerFromNativeLibrary(app_library, "MojoMain")); - if (!main_function) { - LOG(ERROR) << "MojoMain not found"; - return false; - } - // |MojoMain()| takes ownership of the service handle. - MojoHandle handle = application_request.PassMessagePipe().release().value(); - MojoResult result = main_function(handle); - if (result != MOJO_RESULT_OK) { - LOG(ERROR) << "MojoMain returned error (result: " << result << ")"; - } - return true; -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/native_application_support.h b/mojo/shell/native_application_support.h deleted file mode 100644 index 572c089..0000000 --- a/mojo/shell/native_application_support.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2014 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 SHELL_NATIVE_APPLICATION_SUPPORT_H_ -#define SHELL_NATIVE_APPLICATION_SUPPORT_H_ - -#include "base/native_library.h" -#include "mojo/public/cpp/bindings/interface_request.h" - -#if defined(OS_WIN) -#undef DELETE -#endif - -namespace base { -class FilePath; -} - -namespace mojo { - -class Application; - -namespace shell { - -enum class NativeApplicationCleanup { DELETE, DONT_DELETE }; - -// Loads the native Mojo application from the DSO specified by |app_path|. -// Returns the |base::NativeLibrary| for the application on success (or null on -// failure). If |cleanup| is |DELETE|, it will delete |app_path| (regardless of -// sucess or failure). -// -// Note: The caller may choose to eventually unload the returned DSO. If so, -// this should be done only after the thread on which |LoadNativeApplication()| -// and |RunNativeApplication()| were called has terminated, so that any -// thread-local destructors have been executed. -base::NativeLibrary LoadNativeApplication(const base::FilePath& app_path, - NativeApplicationCleanup cleanup); - -// Runs the native Mojo application from the DSO that was loaded using -// |LoadNativeApplication()|; this tolerates |app_library| being null. This -// should be called on the same thread as |LoadNativeApplication()|. Returns -// true if |MojoMain()| was called (even if it returns an error), and false -// otherwise. -// TODO(vtl): Maybe this should also have a |MojoResult| as an out parameter? -bool RunNativeApplication(base::NativeLibrary app_library, - InterfaceRequest<Application> application_request); - -} // namespace shell -} // namespace mojo - -#endif // SHELL_NATIVE_APPLICATION_SUPPORT_H_ diff --git a/mojo/shell/application_manager/native_runner.h b/mojo/shell/native_runner.h index bc62b77..cc2ffb8 100644 --- a/mojo/shell/application_manager/native_runner.h +++ b/mojo/shell/native_runner.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_NATIVE_RUNNER_H_ -#define SHELL_APPLICATION_MANAGER_NATIVE_RUNNER_H_ +#ifndef MOJO_SHELL_NATIVE_RUNNER_H_ +#define MOJO_SHELL_NATIVE_RUNNER_H_ #include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/interfaces/application/application.mojom.h" -#include "mojo/shell/native_application_support.h" +#include "mojo/runner/native_application_support.h" namespace base { class FilePath; @@ -55,4 +55,4 @@ class NativeRunnerFactory { } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_NATIVE_RUNNER_H_ +#endif // MOJO_SHELL_NATIVE_RUNNER_H_ diff --git a/mojo/shell/native_runner_unittest.cc b/mojo/shell/native_runner_unittest.cc deleted file mode 100644 index 4cbb4f5..0000000 --- a/mojo/shell/native_runner_unittest.cc +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2014 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/files/scoped_temp_dir.h" -#include "mojo/shell/application_manager/application_manager.h" -#include "mojo/shell/context.h" -#include "mojo/shell/filename_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace shell { -namespace { - -struct TestState { - TestState() - : runner_was_created(false), - runner_was_started(false), - runner_was_destroyed(false) {} - - bool runner_was_created; - bool runner_was_started; - bool runner_was_destroyed; -}; - -class TestNativeRunner : public NativeRunner { - public: - explicit TestNativeRunner(TestState* state) : state_(state) { - state_->runner_was_created = true; - } - ~TestNativeRunner() override { - state_->runner_was_destroyed = true; - base::MessageLoop::current()->Quit(); - } - void Start(const base::FilePath& app_path, - NativeApplicationCleanup cleanup, - InterfaceRequest<Application> application_request, - const base::Closure& app_completed_callback) override { - state_->runner_was_started = true; - } - - private: - TestState* state_; -}; - -class TestNativeRunnerFactory : public NativeRunnerFactory { - public: - explicit TestNativeRunnerFactory(TestState* state) : state_(state) {} - ~TestNativeRunnerFactory() override {} - scoped_ptr<NativeRunner> Create(const Options& options) override { - return scoped_ptr<NativeRunner>(new TestNativeRunner(state_)); - } - - private: - TestState* state_; -}; - -class NativeApplicationLoaderTest : public testing::Test, - public ApplicationManager::Delegate { - public: - NativeApplicationLoaderTest() : application_manager_(this) {} - ~NativeApplicationLoaderTest() override {} - void SetUp() override { - context_.Init(); - scoped_ptr<NativeRunnerFactory> factory( - new TestNativeRunnerFactory(&state_)); - application_manager_.set_native_runner_factory(factory.Pass()); - application_manager_.set_blocking_pool( - context_.task_runners()->blocking_pool()); - } - void TearDown() override { context_.Shutdown(); } - - protected: - shell::Context context_; - base::MessageLoop loop_; - ApplicationManager application_manager_; - TestState state_; - - private: - // ApplicationManager::Delegate - GURL ResolveMappings(const GURL& url) override { return url; } - GURL ResolveMojoURL(const GURL& url) override { return url; } -}; - -TEST_F(NativeApplicationLoaderTest, DoesNotExist) { - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - base::FilePath nonexistent_file(FILE_PATH_LITERAL("nonexistent.txt")); - GURL url(FilePathToFileURL(temp_dir.path().Append(nonexistent_file))); - InterfaceRequest<ServiceProvider> services; - ServiceProviderPtr service_provider; - application_manager_.ConnectToApplication( - url, GURL(), services.Pass(), service_provider.Pass(), base::Closure()); - EXPECT_FALSE(state_.runner_was_created); - EXPECT_FALSE(state_.runner_was_started); - EXPECT_FALSE(state_.runner_was_destroyed); -} - -} // namespace -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/application_manager/network_fetcher.cc b/mojo/shell/network_fetcher.cc index 5accc91..4de4d5d 100644 --- a/mojo/shell/application_manager/network_fetcher.cc +++ b/mojo/shell/network_fetcher.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/network_fetcher.h" +#include "mojo/shell/network_fetcher.h" #include "base/bind.h" #include "base/command_line.h" @@ -23,7 +23,7 @@ #include "mojo/common/data_pipe_utils.h" #include "mojo/common/url_type_converters.h" #include "mojo/services/network/public/interfaces/network_service.mojom.h" -#include "mojo/shell/application_manager/data_pipe_peek.h" +#include "mojo/shell/data_pipe_peek.h" #include "mojo/shell/switches.h" namespace mojo { diff --git a/mojo/shell/application_manager/network_fetcher.h b/mojo/shell/network_fetcher.h index 3ee90a9..028ec5b 100644 --- a/mojo/shell/application_manager/network_fetcher.h +++ b/mojo/shell/network_fetcher.h @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_NETWORK_FETCHER_H_ -#define SHELL_APPLICATION_MANAGER_NETWORK_FETCHER_H_ +#ifndef MOJO_SHELL_NETWORK_FETCHER_H_ +#define MOJO_SHELL_NETWORK_FETCHER_H_ -#include "mojo/shell/application_manager/fetcher.h" +#include "mojo/shell/fetcher.h" #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" @@ -80,4 +80,4 @@ class NetworkFetcher : public Fetcher { } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_NETWORK_FETCHER_H_ +#endif // MOJO_SHELL_NETWORK_FETCHER_H_ diff --git a/mojo/shell/out_of_process_native_runner.cc b/mojo/shell/out_of_process_native_runner.cc deleted file mode 100644 index f09ea82..0000000 --- a/mojo/shell/out_of_process_native_runner.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 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/shell/out_of_process_native_runner.h" - -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "mojo/shell/child_process.mojom.h" -#include "mojo/shell/child_process_host.h" -#include "mojo/shell/in_process_native_runner.h" - -namespace mojo { -namespace shell { - -OutOfProcessNativeRunner::OutOfProcessNativeRunner(Context* context) - : context_(context) { -} - -OutOfProcessNativeRunner::~OutOfProcessNativeRunner() { - if (child_process_host_) { - // TODO(vtl): Race condition: If |ChildProcessHost::DidStart()| hasn't been - // called yet, we shouldn't call |Join()| here. (Until |DidStart()|, we may - // not have a child process to wait on.) Probably we should fix |Join()|. - child_process_host_->Join(); - } -} - -void OutOfProcessNativeRunner::Start( - const base::FilePath& app_path, - NativeApplicationCleanup cleanup, - InterfaceRequest<Application> application_request, - const base::Closure& app_completed_callback) { - app_path_ = app_path; - - DCHECK(app_completed_callback_.is_null()); - app_completed_callback_ = app_completed_callback; - - std::string name = app_path.BaseName().RemoveExtension().MaybeAsASCII(); - child_process_host_.reset(new ChildProcessHost(context_, name)); - child_process_host_->Start(); - - // TODO(vtl): |app_path.AsUTF8Unsafe()| is unsafe. - child_process_host_->StartApp( - app_path.AsUTF8Unsafe(), cleanup == NativeApplicationCleanup::DELETE, - application_request.Pass(), - base::Bind(&OutOfProcessNativeRunner::AppCompleted, - base::Unretained(this))); -} - -void OutOfProcessNativeRunner::AppCompleted(int32_t result) { - DVLOG(2) << "OutOfProcessNativeRunner::AppCompleted(" << result << ")"; - - child_process_host_.reset(); - // This object may be deleted by this callback. - base::Closure app_completed_callback = app_completed_callback_; - app_completed_callback_.Reset(); - app_completed_callback.Run(); -} - -scoped_ptr<NativeRunner> OutOfProcessNativeRunnerFactory::Create( - const Options& options) { - if (options.force_in_process) - return make_scoped_ptr(new InProcessNativeRunner(context_)); - - return make_scoped_ptr(new OutOfProcessNativeRunner(context_)); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/out_of_process_native_runner.h b/mojo/shell/out_of_process_native_runner.h deleted file mode 100644 index 23bba66..0000000 --- a/mojo/shell/out_of_process_native_runner.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2014 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 SHELL_OUT_OF_PROCESS_NATIVE_RUNNER_H_ -#define SHELL_OUT_OF_PROCESS_NATIVE_RUNNER_H_ - -#include "base/callback.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "mojo/public/cpp/bindings/error_handler.h" -#include "mojo/shell/application_manager/native_runner.h" - -namespace mojo { -namespace shell { - -class ChildProcessHost; -class Context; - -// An implementation of |NativeRunner| that loads/runs the given app (from the -// file system) in a separate process (of its own). -class OutOfProcessNativeRunner : public NativeRunner { - public: - explicit OutOfProcessNativeRunner(Context* context); - ~OutOfProcessNativeRunner() override; - - // |NativeRunner| method: - void Start(const base::FilePath& app_path, - NativeApplicationCleanup cleanup, - InterfaceRequest<Application> application_request, - const base::Closure& app_completed_callback) override; - - private: - // |ChildController::StartApp()| callback: - void AppCompleted(int32_t result); - - Context* const context_; - - base::FilePath app_path_; - base::Closure app_completed_callback_; - - scoped_ptr<ChildProcessHost> child_process_host_; - - DISALLOW_COPY_AND_ASSIGN(OutOfProcessNativeRunner); -}; - -class OutOfProcessNativeRunnerFactory : public NativeRunnerFactory { - public: - explicit OutOfProcessNativeRunnerFactory(Context* context) - : context_(context) {} - ~OutOfProcessNativeRunnerFactory() override {} - - scoped_ptr<NativeRunner> Create(const Options& options) override; - - private: - Context* const context_; - - DISALLOW_COPY_AND_ASSIGN(OutOfProcessNativeRunnerFactory); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_OUT_OF_PROCESS_NATIVE_RUNNER_H_ diff --git a/mojo/shell/application_manager/query_util.cc b/mojo/shell/query_util.cc index 252dcb6..fbe4c56 100644 --- a/mojo/shell/application_manager/query_util.cc +++ b/mojo/shell/query_util.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/query_util.h" +#include "mojo/shell/query_util.h" #include "base/strings/string_util.h" diff --git a/mojo/shell/application_manager/query_util.h b/mojo/shell/query_util.h index a4ca3f7e..a1f0ac7 100644 --- a/mojo/shell/application_manager/query_util.h +++ b/mojo/shell/query_util.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_QUERY_UTIL_H_ -#define SHELL_APPLICATION_MANAGER_QUERY_UTIL_H_ +#ifndef MOJO_SHELL_QUERY_UTIL_H_ +#define MOJO_SHELL_QUERY_UTIL_H_ #include <utility> @@ -20,4 +20,4 @@ GURL GetBaseURLAndQuery(const GURL& url, std::string* query); } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_QUERY_UTIL_H_ +#endif // MOJO_SHELL_QUERY_UTIL_H_ diff --git a/mojo/shell/application_manager/query_util_unittest.cc b/mojo/shell/query_util_unittest.cc index 8a995c4..9b28bc5 100644 --- a/mojo/shell/application_manager/query_util_unittest.cc +++ b/mojo/shell/query_util_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/query_util.h" +#include "mojo/shell/query_util.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/shell/shell_apptest.cc b/mojo/shell/shell_apptest.cc deleted file mode 100644 index 66b6889..0000000 --- a/mojo/shell/shell_apptest.cc +++ /dev/null @@ -1,197 +0,0 @@ -// 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/base_paths.h" -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "mojo/application/application_test_base_chromium.h" -#include "mojo/common/data_pipe_utils.h" -#include "mojo/public/cpp/application/application_impl.h" -#include "mojo/public/cpp/system/macros.h" -#include "mojo/services/http_server/public/cpp/http_server_util.h" -#include "mojo/services/http_server/public/interfaces/http_server.mojom.h" -#include "mojo/services/http_server/public/interfaces/http_server_factory.mojom.h" -#include "mojo/services/network/public/interfaces/net_address.mojom.h" -#include "mojo/shell/kPingable.h" -#include "mojo/shell/test/pingable.mojom.h" - -namespace mojo { -namespace { - -std::string GetURL(uint16_t port, const std::string& path) { - return base::StringPrintf("http://127.0.0.1:%u/%s", - static_cast<unsigned>(port), path.c_str()); -} - -class GetHandler : public http_server::HttpHandler { - public: - GetHandler(InterfaceRequest<http_server::HttpHandler> request, uint16_t port) - : binding_(this, request.Pass()), port_(port) { - } - ~GetHandler() override {} - - private: - // http_server::HttpHandler: - void HandleRequest( - http_server::HttpRequestPtr request, - const Callback<void(http_server::HttpResponsePtr)>& callback) override { - http_server::HttpResponsePtr response; - if (StartsWithASCII(request->relative_url, "/app", true)) { - response = http_server::CreateHttpResponse( - 200, std::string(kPingable.data, kPingable.size)); - response->content_type = "application/octet-stream"; - } else if (request->relative_url == "/redirect") { - response = http_server::HttpResponse::New(); - response->status_code = 302; - response->custom_headers.insert("Location", GetURL(port_, "app")); - } else { - NOTREACHED(); - } - - callback.Run(response.Pass()); - } - - Binding<http_server::HttpHandler> binding_; - uint16_t port_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(GetHandler); -}; - -typedef test::ApplicationTestBase ShellAppTest; - -class ShellHTTPAppTest : public test::ApplicationTestBase { - public: - ShellHTTPAppTest() : ApplicationTestBase() {} - ~ShellHTTPAppTest() override {} - - protected: - // ApplicationTestBase: - void SetUp() override { - ApplicationTestBase::SetUp(); - - application_impl()->ConnectToService("mojo:http_server", - &http_server_factory_); - - NetAddressPtr local_address(NetAddress::New()); - local_address->family = NET_ADDRESS_FAMILY_IPV4; - local_address->ipv4 = NetAddressIPv4::New(); - local_address->ipv4->addr.resize(4); - local_address->ipv4->addr[0] = 127; - local_address->ipv4->addr[1] = 0; - local_address->ipv4->addr[2] = 0; - local_address->ipv4->addr[3] = 1; - local_address->ipv4->port = 0; - http_server_factory_->CreateHttpServer(GetProxy(&http_server_), - local_address.Pass()); - - http_server_->GetPort([this](uint16_t p) { port_ = p; }); - EXPECT_TRUE(http_server_.WaitForIncomingMethodCall()); - - InterfacePtr<http_server::HttpHandler> http_handler; - handler_.reset(new GetHandler(GetProxy(&http_handler).Pass(), port_)); - http_server_->SetHandler(".*", http_handler.Pass(), - [](bool result) { EXPECT_TRUE(result); }); - EXPECT_TRUE(http_server_.WaitForIncomingMethodCall()); - } - - std::string GetURL(const std::string& path) { - return ::mojo::GetURL(port_, path); - } - - http_server::HttpServerFactoryPtr http_server_factory_; - http_server::HttpServerPtr http_server_; - scoped_ptr<GetHandler> handler_; - uint16_t port_; - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(ShellHTTPAppTest); -}; - -// Test that we can load apps over http. -TEST_F(ShellHTTPAppTest, Http) { - InterfacePtr<Pingable> pingable; - application_impl()->ConnectToService(GetURL("app"), &pingable); - pingable->Ping("hello", - [this](const String& app_url, const String& connection_url, - const String& message) { - EXPECT_EQ(GetURL("app"), app_url); - EXPECT_EQ(GetURL("app"), connection_url); - EXPECT_EQ("hello", message); - base::MessageLoop::current()->Quit(); - }); - base::RunLoop().Run(); -} - -// Test that redirects work. -// TODO(aa): Test that apps receive the correct URL parameters. -TEST_F(ShellHTTPAppTest, Redirect) { - InterfacePtr<Pingable> pingable; - application_impl()->ConnectToService(GetURL("redirect"), &pingable); - pingable->Ping("hello", - [this](const String& app_url, const String& connection_url, - const String& message) { - EXPECT_EQ(GetURL("app"), app_url); - EXPECT_EQ(GetURL("app"), connection_url); - EXPECT_EQ("hello", message); - base::MessageLoop::current()->Quit(); - }); - base::RunLoop().Run(); -} - -// Test that querystring is not considered when resolving http applications. -// TODO(aa|qsr): Fix this test on Linux ASAN http://crbug.com/463662 -#if defined(ADDRESS_SANITIZER) -#define MAYBE_QueryHandling DISABLED_QueryHandling -#else -#define MAYBE_QueryHandling QueryHandling -#endif // ADDRESS_SANITIZER -TEST_F(ShellHTTPAppTest, MAYBE_QueryHandling) { - InterfacePtr<Pingable> pingable1; - InterfacePtr<Pingable> pingable2; - application_impl()->ConnectToService(GetURL("app?foo"), &pingable1); - application_impl()->ConnectToService(GetURL("app?bar"), &pingable2); - - int num_responses = 0; - auto callback = [this, &num_responses](const String& app_url, - const String& connection_url, - const String& message) { - EXPECT_EQ(GetURL("app"), app_url); - EXPECT_EQ("hello", message); - ++num_responses; - if (num_responses == 1) { - EXPECT_EQ(GetURL("app?foo"), connection_url); - } else if (num_responses == 2) { - EXPECT_EQ(GetURL("app?bar"), connection_url); - base::MessageLoop::current()->Quit(); - } else { - CHECK(false); - } - }; - pingable1->Ping("hello", callback); - pingable2->Ping("hello", callback); - base::RunLoop().Run(); -} - -// mojo: URLs can have querystrings too -TEST_F(ShellAppTest, MojoURLQueryHandling) { - InterfacePtr<Pingable> pingable; - application_impl()->ConnectToService("mojo:pingable_app?foo", &pingable); - auto callback = [this](const String& app_url, const String& connection_url, - const String& message) { - EXPECT_TRUE(EndsWith(app_url, "/pingable_app.mojo", true)); - EXPECT_EQ(app_url.To<std::string>() + "?foo", connection_url); - EXPECT_EQ("hello", message); - base::MessageLoop::current()->Quit(); - }; - pingable->Ping("hello", callback); - base::RunLoop().Run(); -} - -} // namespace -} // namespace mojo diff --git a/mojo/shell/application_manager/shell_impl.cc b/mojo/shell/shell_impl.cc index ed8c5ea..c516686 100644 --- a/mojo/shell/application_manager/shell_impl.cc +++ b/mojo/shell/shell_impl.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/shell/application_manager/shell_impl.h" +#include "mojo/shell/shell_impl.h" #include "mojo/common/common_type_converters.h" #include "mojo/common/url_type_converters.h" -#include "mojo/shell/application_manager/application_manager.h" +#include "mojo/shell/application_manager.h" #include "third_party/mojo_services/src/content_handler/public/interfaces/content_handler.mojom.h" namespace mojo { diff --git a/mojo/shell/application_manager/shell_impl.h b/mojo/shell/shell_impl.h index ef557a6..cf8be59 100644 --- a/mojo/shell/application_manager/shell_impl.h +++ b/mojo/shell/shell_impl.h @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_APPLICATION_MANAGER_SHELL_IMPL_H_ -#define SHELL_APPLICATION_MANAGER_SHELL_IMPL_H_ +#ifndef MOJO_SHELL_SHELL_IMPL_H_ +#define MOJO_SHELL_SHELL_IMPL_H_ #include "base/callback.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/error_handler.h" #include "mojo/public/interfaces/application/application.mojom.h" #include "mojo/public/interfaces/application/shell.mojom.h" -#include "mojo/shell/application_manager/identity.h" +#include "mojo/shell/identity.h" #include "url/gurl.h" namespace mojo { @@ -59,4 +59,4 @@ class ShellImpl : public Shell, public ErrorHandler { } // namespace shell } // namespace mojo -#endif // SHELL_APPLICATION_MANAGER_SHELL_IMPL_H_ +#endif // MOJO_SHELL_SHELL_IMPL_H_ diff --git a/mojo/shell/shell_test_base.cc b/mojo/shell/shell_test_base.cc deleted file mode 100644 index da9a7d9..0000000 --- a/mojo/shell/shell_test_base.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2014 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/shell/shell_test_base.h" - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "build/build_config.h" -#include "mojo/shell/filename_util.h" -#include "url/gurl.h" - -namespace mojo { -namespace shell { -namespace test { - -namespace { - -void QuitIfRunning() { - if (base::MessageLoop::current() && - base::MessageLoop::current()->is_running()) { - base::MessageLoop::current()->QuitWhenIdle(); - } -} - -} // namespace - -ShellTestBase::ShellTestBase() { -} - -ShellTestBase::~ShellTestBase() { -} - -void ShellTestBase::SetUp() { - CHECK(shell_context_.Init()); - SetUpTestApplications(); -} - -void ShellTestBase::TearDown() { - shell_context_.Shutdown(); -} - -ScopedMessagePipeHandle ShellTestBase::ConnectToService( - const GURL& application_url, - const std::string& service_name) { - ServiceProviderPtr services; - shell_context_.application_manager()->ConnectToApplication( - application_url, GURL(), GetProxy(&services), nullptr, - base::Bind(&QuitIfRunning)); - MessagePipe pipe; - services->ConnectToService(service_name, pipe.handle1.Pass()); - return pipe.handle0.Pass(); -} - -#if !defined(OS_ANDROID) -void ShellTestBase::SetUpTestApplications() { - // Set the URLResolver origin to be the same as the base file path for - // local files. This is primarily for test convenience, so that references - // to unknown mojo: urls that do not have specific local file or custom - // mappings registered on the URL resolver are treated as shared libraries. - base::FilePath service_dir; - CHECK(PathService::Get(base::DIR_MODULE, &service_dir)); - shell_context_.url_resolver()->SetMojoBaseURL(FilePathToFileURL(service_dir)); -} -#endif - -} // namespace test -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/shell_test_base.h b/mojo/shell/shell_test_base.h deleted file mode 100644 index e119a0a..0000000 --- a/mojo/shell/shell_test_base.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2014 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 SHELL_SHELL_TEST_BASE_H_ -#define SHELL_SHELL_TEST_BASE_H_ - -#include <string> - -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/shell/context.h" -#include "testing/gtest/include/gtest/gtest.h" - -class GURL; - -namespace mojo { -namespace shell { -namespace test { - -class ShellTestBase : public testing::Test { - public: - ShellTestBase(); - ~ShellTestBase() override; - - void SetUp() override; - void TearDown() override; - - // |application_url| should typically be a mojo: URL (the origin will be set - // to an "appropriate" file: URL). - // TODO(tim): Should the test base be a ServiceProvider? - ScopedMessagePipeHandle ConnectToService(const GURL& application_url, - const std::string& service_name); - - template <typename Interface> - void ConnectToService(const GURL& application_url, - InterfacePtr<Interface>* ptr) { - ptr->Bind(ConnectToService(application_url, Interface::Name_).Pass()); - } - - base::MessageLoop* message_loop() { return &message_loop_; } - Context* shell_context() { return &shell_context_; } - - private: - // Set up the test applications so that mojo: URL resolves to those. - void SetUpTestApplications(); - - Context shell_context_; - base::MessageLoop message_loop_; - - DISALLOW_COPY_AND_ASSIGN(ShellTestBase); -}; - -} // namespace test -} // namespace shell -} // namespace mojo - -#endif // SHELL_SHELL_TEST_BASE_H_ diff --git a/mojo/shell/shell_test_base_android.cc b/mojo/shell/shell_test_base_android.cc deleted file mode 100644 index 4b3b736..0000000 --- a/mojo/shell/shell_test_base_android.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 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/shell/shell_test_base.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "jni/ShellTestBase_jni.h" -#include "mojo/shell/filename_util.h" -#include "url/gurl.h" - -namespace mojo { -namespace shell { -namespace test { - -namespace { - -JNIEnv* InitEnv() { - JNIEnv* env = base::android::AttachCurrentThread(); - static bool initialized = false; - if (!initialized) { - RegisterNativesImpl(env); - initialized = true; - } - return env; -} - -} // namespace - -void ShellTestBase::SetUpTestApplications() { - // Extract mojo applications, and set the resolve base URL to the directory - // containing those. - JNIEnv* env = InitEnv(); - base::android::ScopedJavaLocalRef<jstring> service_dir( - Java_ShellTestBase_extractMojoApplications( - env, base::android::GetApplicationContext())); - shell_context_.url_resolver()->SetMojoBaseURL( - FilePathToFileURL(base::FilePath( - base::android::ConvertJavaStringToUTF8(env, service_dir.obj())))); -} - -} // namespace test -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/shell_test_base_unittest.cc b/mojo/shell/shell_test_base_unittest.cc deleted file mode 100644 index 4e94511..0000000 --- a/mojo/shell/shell_test_base_unittest.cc +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright 2014 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/shell/shell_test_base.h" - -#include "base/bind.h" -#include "base/i18n/time_formatting.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "mojo/public/cpp/bindings/error_handler.h" -#include "mojo/public/cpp/bindings/interface_ptr.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/services/test_service/test_request_tracker.mojom.h" -#include "mojo/services/test_service/test_service.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -using mojo::test::ServiceReport; -using mojo::test::ServiceReportPtr; -using mojo::test::TestService; -using mojo::test::TestTimeService; -using mojo::test::TestServicePtr; -using mojo::test::TestTimeServicePtr; -using mojo::test::TestTrackedRequestService; -using mojo::test::TestTrackedRequestServicePtr; - -namespace mojo { -namespace shell { -namespace test { -namespace { - -void GetReportCallback(base::MessageLoop* loop, - std::vector<ServiceReport>* reports_out, - Array<ServiceReportPtr> report) { - for (size_t i = 0; i < report.size(); i++) - reports_out->push_back(*report[i]); - loop->QuitWhenIdle(); -} - -class ShellTestBaseTest : public ShellTestBase { - public: - // Convenience helpers for use as callbacks in tests. - template <typename T> - base::Callback<void()> SetAndQuit(T* val, T result) { - return base::Bind(&ShellTestBaseTest::SetAndQuitImpl<T>, - base::Unretained(this), val, result); - } - template <typename T> - base::Callback<void(T result)> SetAndQuit(T* val) { - return base::Bind(&ShellTestBaseTest::SetAndQuitImpl<T>, - base::Unretained(this), val); - } - static GURL test_app_url() { return GURL("mojo:test_app"); } - - void GetReport(std::vector<ServiceReport>* report) { - ConnectToService(GURL("mojo:test_request_tracker_app"), &request_tracking_); - request_tracking_->GetReport(base::Bind(&GetReportCallback, - base::Unretained(message_loop()), - base::Unretained(report))); - message_loop()->Run(); - } - - private: - template <typename T> - void SetAndQuitImpl(T* val, T result) { - *val = result; - message_loop()->QuitWhenIdle(); - } - TestTrackedRequestServicePtr request_tracking_; -}; - -class QuitMessageLoopErrorHandler : public ErrorHandler { - public: - QuitMessageLoopErrorHandler() {} - ~QuitMessageLoopErrorHandler() override {} - - // |ErrorHandler| implementation: - void OnConnectionError() override { - base::MessageLoop::current()->QuitWhenIdle(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler); -}; - -// Tests that we can connect to a single service within a single app. -TEST_F(ShellTestBaseTest, ConnectBasic) { - InterfacePtr<TestService> service; - ConnectToService(test_app_url(), &service); - - bool was_run = false; - service->Ping(SetAndQuit<bool>(&was_run, true)); - message_loop()->Run(); - EXPECT_TRUE(was_run); - EXPECT_FALSE(service.encountered_error()); - - service.reset(); - - // This will run until the test app has actually quit (which it will, - // since we killed the only connection to it). - message_loop()->Run(); -} - -// Tests that trying to connect to a service fails properly if the service -// doesn't exist. Implicit in this test is verification that the shell -// terminates if no services are running. -TEST_F(ShellTestBaseTest, ConnectInvalidService) { - InterfacePtr<TestService> test_service; - ConnectToService(GURL("mojo:non_existent_service"), &test_service); - - bool was_run = false; - test_service->Ping(SetAndQuit<bool>(&was_run, true)); - - // This will quit because there's nothing running. - message_loop()->Run(); - EXPECT_FALSE(was_run); - - // It may have quit before an error was processed. - if (!test_service.encountered_error()) { - QuitMessageLoopErrorHandler quitter; - test_service.set_error_handler(&quitter); - message_loop()->Run(); - EXPECT_TRUE(test_service.encountered_error()); - } - - test_service.reset(); -} - -// Tests that we can connect to a single service within a single app using -// a network based loader instead of local files. -// TODO(tim): Disabled because network service leaks NSS at exit, meaning -// subsequent tests can't init properly. -TEST_F(ShellTestBaseTest, DISABLED_ConnectBasicNetwork) { - InterfacePtr<TestService> service; - ConnectToService(test_app_url(), &service); - - bool was_run = false; - service->Ping(SetAndQuit<bool>(&was_run, true)); - message_loop()->Run(); - EXPECT_TRUE(was_run); - EXPECT_FALSE(service.encountered_error()); - - // Note that use of the network service is implicit in this test. - // Since TestService is not the only service in use, the shell won't auto - // magically exit when TestService is destroyed (unlike ConnectBasic). - // Tearing down the shell context will kill connections. The shell loop will - // exit as soon as no more apps are connected. - // TODO(tim): crbug.com/392685. Calling this explicitly shouldn't be - // necessary once the shell terminates if the primordial app exits, which - // we could enforce here by resetting |service|. - shell_context()->application_manager()->TerminateShellConnections(); - message_loop()->Run(); // Waits for all connections to die. -} - -// Tests that trying to connect to a service over network fails preoprly -// if the service doesn't exist. -// TODO(tim): Disabled because network service leaks NSS at exit, meaning -// subsequent tests can't init properly. -TEST_F(ShellTestBaseTest, DISABLED_ConnectInvalidServiceNetwork) { - InterfacePtr<TestService> test_service; - ConnectToService(GURL("http://example.com/non_existent_service"), - &test_service); - QuitMessageLoopErrorHandler quitter; - test_service.set_error_handler(&quitter); - bool was_run = false; - test_service->Ping(SetAndQuit<bool>(&was_run, true)); - message_loop()->Run(); - EXPECT_TRUE(test_service.encountered_error()); - - // TODO(tim): crbug.com/392685. Calling this explicitly shouldn't be - // necessary once the shell terminates if the primordial app exits, which - // we could enforce here by resetting |service|. - shell_context()->application_manager()->TerminateShellConnections(); - message_loop()->Run(); // Waits for all connections to die. -} - -// Similar to ConnectBasic, but causes the app to instantiate multiple -// service implementation objects and verifies the shell can reach both. -TEST_F(ShellTestBaseTest, ConnectMultipleInstancesPerApp) { - { - TestServicePtr service1, service2; - ConnectToService(test_app_url(), &service1); - ConnectToService(test_app_url(), &service2); - - bool was_run1 = false; - bool was_run2 = false; - service1->Ping(SetAndQuit<bool>(&was_run1, true)); - message_loop()->Run(); - service2->Ping(SetAndQuit<bool>(&was_run2, true)); - message_loop()->Run(); - EXPECT_TRUE(was_run1); - EXPECT_TRUE(was_run2); - EXPECT_FALSE(service1.encountered_error()); - EXPECT_FALSE(service2.encountered_error()); - } - message_loop()->Run(); -} - -// Tests that service A and service B, both in App 1, can talk to each other -// and parameters are passed around properly. -TEST_F(ShellTestBaseTest, ConnectDifferentServicesInSingleApp) { - // Have a TestService GetPartyTime on a TestTimeService in the same app. - int64 time_message; - TestServicePtr service; - ConnectToService(test_app_url(), &service); - service->ConnectToAppAndGetTime(test_app_url().spec(), - SetAndQuit<int64>(&time_message)); - message_loop()->Run(); - - // Verify by hitting the TimeService directly. - TestTimeServicePtr time_service; - ConnectToService(test_app_url(), &time_service); - int64 party_time; - time_service->GetPartyTime(SetAndQuit<int64>(&party_time)); - message_loop()->Run(); - - EXPECT_EQ(time_message, party_time); -} - -// Tests that a service A in App 1 can talk to service B in App 2 and -// parameters are passed around properly. -TEST_F(ShellTestBaseTest, ConnectDifferentServicesInDifferentApps) { - int64 time_message; - TestServicePtr service; - ConnectToService(test_app_url(), &service); - service->ConnectToAppAndGetTime("mojo:test_request_tracker_app", - SetAndQuit<int64>(&time_message)); - message_loop()->Run(); - - // Verify by hitting the TimeService in the request tracker app directly. - TestTimeServicePtr time_service; - ConnectToService(GURL("mojo:test_request_tracker_app"), &time_service); - int64 party_time; - time_service->GetPartyTime(SetAndQuit<int64>(&party_time)); - message_loop()->Run(); - - EXPECT_EQ(time_message, party_time); -} - -// Tests that service A in App 1 can be a client of service B in App 2. -TEST_F(ShellTestBaseTest, ConnectServiceAsClientOfSeparateApp) { - TestServicePtr service; - ConnectToService(test_app_url(), &service); - service->StartTrackingRequests(message_loop()->QuitWhenIdleClosure()); - service->Ping(Callback<void()>()); - message_loop()->Run(); - - for (int i = 0; i < 8; i++) - service->Ping(Callback<void()>()); - service->Ping(message_loop()->QuitWhenIdleClosure()); - message_loop()->Run(); - - // If everything worked properly, the tracking service should report - // 10 pings to TestService. - std::vector<ServiceReport> reports; - GetReport(&reports); - ASSERT_EQ(1U, reports.size()); - EXPECT_EQ(TestService::Name_, reports[0].service_name); - EXPECT_EQ(10U, reports[0].total_requests); -} - -// Connect several services together and use the tracking service to verify -// communication. -TEST_F(ShellTestBaseTest, ConnectManyClientsAndServices) { - TestServicePtr service; - TestTimeServicePtr time_service; - - // Make a request to the TestService and have it contact TimeService in the - // tracking app. Do all this with tracking enabled, meaning both services - // are connected as clients of the TrackedRequestService. - ConnectToService(test_app_url(), &service); - service->StartTrackingRequests(message_loop()->QuitWhenIdleClosure()); - message_loop()->Run(); - for (int i = 0; i < 5; i++) - service->Ping(Callback<void()>()); - int64 time_result; - service->ConnectToAppAndGetTime("mojo:test_request_tracker_app", - SetAndQuit<int64>(&time_result)); - message_loop()->Run(); - - // Also make a few requests to the TimeService in the test_app. - ConnectToService(test_app_url(), &time_service); - time_service->StartTrackingRequests(message_loop()->QuitWhenIdleClosure()); - time_service->GetPartyTime(Callback<void(uint64_t)>()); - message_loop()->Run(); - for (int i = 0; i < 18; i++) - time_service->GetPartyTime(Callback<void(uint64_t)>()); - // Flush the tasks with one more to quit. - int64 party_time = 0; - time_service->GetPartyTime(SetAndQuit<int64>(&party_time)); - message_loop()->Run(); - - std::vector<ServiceReport> reports; - GetReport(&reports); - ASSERT_EQ(3U, reports.size()); - EXPECT_EQ(TestService::Name_, reports[0].service_name); - EXPECT_EQ(6U, reports[0].total_requests); - EXPECT_EQ(TestTimeService::Name_, reports[1].service_name); - EXPECT_EQ(1U, reports[1].total_requests); - EXPECT_EQ(TestTimeService::Name_, reports[2].service_name); - EXPECT_EQ(20U, reports[2].total_requests); -} - -} // namespace -} // namespace test -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/shell_test_main.cc b/mojo/shell/shell_test_main.cc deleted file mode 100644 index 47b6c09..0000000 --- a/mojo/shell/shell_test_main.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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/at_exit.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/test/launcher/unit_test_launcher.h" -#include "base/test/test_suite.h" -#include "mojo/shell/child_process.h" -#include "mojo/shell/switches.h" -#include "testing/gtest/include/gtest/gtest.h" - -int main(int argc, char** argv) { - base::CommandLine::Init(argc, argv); - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - - if (command_line.HasSwitch(switches::kChildProcess)) { - base::AtExitManager at_exit; - - return mojo::shell::ChildProcessMain(); - } - - base::TestSuite test_suite(argc, argv); - return base::LaunchUnitTests( - argc, argv, - base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); -} diff --git a/mojo/shell/switches.cc b/mojo/shell/switches.cc index e5c9d34..c6df370 100644 --- a/mojo/shell/switches.cc +++ b/mojo/shell/switches.cc @@ -8,46 +8,9 @@ namespace switches { -// Used just for debugging to make it easier to attach debuggers. The actual app -// path that is used is sent over IPC. -const char kApp[] = "app"; - -// Used internally by the main process to indicate that a new process should be -// a child process. Not for user use. -const char kChildProcess[] = "child-process"; - -// Comma separated list like: -// text/html,mojo:html_viewer,application/bravo,https://abarth.com/bravo -const char kContentHandlers[] = "content-handlers"; - -// Force dynamically loaded apps / services to be loaded irrespective of cache -// instructions. -const char kDisableCache[] = "disable-cache"; - // If set apps downloaded are not deleted. const char kDontDeleteOnDownload[] = "dont-delete-on-download"; -// Load apps in separate processes. -// TODO(vtl): Work in progress; doesn't work. Flip this to "disable" (or maybe -// change it to "single-process") when it works. -const char kEnableMultiprocess[] = "enable-multiprocess"; - -// In multiprocess mode, force these apps to be loaded in the main process. -// Comma-separate list of URLs. Example: -// --force-in-process=mojo:native_viewport_service,mojo:network_service -const char kForceInProcess[] = "force-in-process"; - -// Print the usage message and exit. -const char kHelp[] = "help"; - -// Specify origin to map to base url. See url_resolver.cc for details. -// Can be used multiple times. -const char kMapOrigin[] = "map-origin"; - -// Map mojo: URLs to a shared library of similar name at this origin. See -// url_resolver.cc for details. -const char kOrigin[] = "origin"; - // If set apps downloaded are saved in with a predictable filename, to help // remote debugging: when gdb is used through gdbserver, it needs to be able to // find locally any loaded library. For this, gdb use the filename of the @@ -55,14 +18,4 @@ const char kOrigin[] = "origin"; // their content. const char kPredictableAppFilenames[] = "predictable-app-filenames"; -// Starts tracing when the shell starts up, saving a trace file on disk after 5 -// seconds or when the shell exits. -const char kTraceStartup[] = "trace-startup"; - -// Specifies a set of mappings to apply when resolving urls. The value is a set -// of ',' separated mappings, where each mapping consists of a pair of urls -// giving the to/from url to map. For example, 'a=b,c=d' contains two mappings, -// the first maps 'a' to 'b' and the second 'c' to 'd'. -const char kURLMappings[] = "url-mappings"; - } // namespace switches diff --git a/mojo/shell/switches.h b/mojo/shell/switches.h index b7d9a37..90cece0 100644 --- a/mojo/shell/switches.h +++ b/mojo/shell/switches.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_SWITCHES_H_ -#define SHELL_SWITCHES_H_ +#ifndef MOJO_SHELL_SWITCHES_H_ +#define MOJO_SHELL_SWITCHES_H_ #include <set> #include <string> @@ -12,20 +12,9 @@ namespace switches { // All switches in alphabetical order. The switches should be documented // alongside the definition of their values in the .cc file. -extern const char kApp[]; -extern const char kChildProcess[]; -extern const char kContentHandlers[]; -extern const char kDisableCache[]; extern const char kDontDeleteOnDownload[]; -extern const char kEnableMultiprocess[]; -extern const char kForceInProcess[]; -extern const char kHelp[]; -extern const char kMapOrigin[]; -extern const char kOrigin[]; extern const char kPredictableAppFilenames[]; -extern const char kTraceStartup[]; -extern const char kURLMappings[]; } // namespace switches -#endif // SHELL_SWITCHES_H_ +#endif // MOJO_SHELL_SWITCHES_H_ diff --git a/mojo/shell/task_runners.cc b/mojo/shell/task_runners.cc deleted file mode 100644 index cb157ee..0000000 --- a/mojo/shell/task_runners.cc +++ /dev/null @@ -1,39 +0,0 @@ -// 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. - -#include "mojo/shell/task_runners.h" - -#include "base/threading/sequenced_worker_pool.h" - -namespace mojo { -namespace shell { - -namespace { - -const size_t kMaxBlockingPoolThreads = 3; - -scoped_ptr<base::Thread> CreateIOThread(const char* name) { - scoped_ptr<base::Thread> thread(new base::Thread(name)); - base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; - thread->StartWithOptions(options); - return thread.Pass(); -} - -} // namespace - -TaskRunners::TaskRunners( - const scoped_refptr<base::SingleThreadTaskRunner>& shell_runner) - : shell_runner_(shell_runner), - io_thread_(CreateIOThread("io_thread")), - blocking_pool_(new base::SequencedWorkerPool(kMaxBlockingPoolThreads, - "blocking_pool")) { -} - -TaskRunners::~TaskRunners() { - blocking_pool_->Shutdown(); -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/task_runners.h b/mojo/shell/task_runners.h deleted file mode 100644 index 891d3e1b..0000000 --- a/mojo/shell/task_runners.h +++ /dev/null @@ -1,53 +0,0 @@ -// 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. - -#ifndef SHELL_TASK_RUNNERS_H_ -#define SHELL_TASK_RUNNERS_H_ - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/threading/thread.h" - -namespace base { -class SequencedWorkerPool; -} - -namespace mojo { -namespace shell { - -// A context object that contains the common task runners for the shell's main -// process. -class TaskRunners { - public: - explicit TaskRunners( - const scoped_refptr<base::SingleThreadTaskRunner>& shell_runner); - ~TaskRunners(); - - base::SingleThreadTaskRunner* shell_runner() const { - return shell_runner_.get(); - } - - base::SingleThreadTaskRunner* io_runner() const { - return io_thread_->message_loop_proxy().get(); - } - - base::SequencedWorkerPool* blocking_pool() const { - return blocking_pool_.get(); - } - - private: - scoped_refptr<base::SingleThreadTaskRunner> shell_runner_; - scoped_ptr<base::Thread> io_thread_; - - scoped_refptr<base::SequencedWorkerPool> blocking_pool_; - - DISALLOW_COPY_AND_ASSIGN(TaskRunners); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_TASK_RUNNERS_H_ diff --git a/mojo/shell/application_manager/test.mojom b/mojo/shell/test.mojom index 25700b5..25700b5 100644 --- a/mojo/shell/application_manager/test.mojom +++ b/mojo/shell/test.mojom diff --git a/mojo/shell/test/BUILD.gn b/mojo/shell/test/BUILD.gn deleted file mode 100644 index 7ca52ff..0000000 --- a/mojo/shell/test/BUILD.gn +++ /dev/null @@ -1,28 +0,0 @@ -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") -import("//testing/test.gni") - -mojom("bindings") { - sources = [ - "pingable.mojom", - ] -} - -mojo_native_application("pingable_app") { - output_name = "pingable_app" - - testonly = true - - sources = [ - "pingable_app.cc", - ] - - deps = [ - ":bindings", - "//third_party/mojo/src/mojo/public/cpp/application:standalone", - "//third_party/mojo/src/mojo/public/cpp/bindings:callback", - "//third_party/mojo/src/mojo/public/cpp/environment", - "//third_party/mojo/src/mojo/public/cpp/system", - ] -} diff --git a/mojo/shell/test/pingable.mojom b/mojo/shell/test/pingable.mojom deleted file mode 100644 index 74ed38d..0000000 --- a/mojo/shell/test/pingable.mojom +++ /dev/null @@ -1,9 +0,0 @@ -// 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. - -module mojo; - -interface Pingable { - Ping(string message) => (string app_url, string connection_url, string message); -}; diff --git a/mojo/shell/test/pingable_app.cc b/mojo/shell/test/pingable_app.cc deleted file mode 100644 index 1849f71..0000000 --- a/mojo/shell/test/pingable_app.cc +++ /dev/null @@ -1,69 +0,0 @@ -// 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/public/c/system/main.h" -#include "mojo/public/cpp/application/application_delegate.h" -#include "mojo/public/cpp/application/application_impl.h" -#include "mojo/public/cpp/application/application_runner.h" -#include "mojo/public/cpp/application/interface_factory.h" -#include "mojo/public/cpp/bindings/callback.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/shell/test/pingable.mojom.h" - -namespace mojo { - -class PingableImpl : public Pingable { - public: - PingableImpl(InterfaceRequest<Pingable> request, - const std::string& app_url, - const std::string& connection_url) - : binding_(this, request.Pass()), - app_url_(app_url), - connection_url_(connection_url) {} - - ~PingableImpl() override {} - - private: - void Ping(const String& message, - const Callback<void(String, String, String)>& callback) override { - callback.Run(app_url_, connection_url_, message); - } - - StrongBinding<Pingable> binding_; - std::string app_url_; - std::string connection_url_; -}; - -class PingableApp : public mojo::ApplicationDelegate, - public mojo::InterfaceFactory<Pingable> { - public: - PingableApp() {} - ~PingableApp() override {} - - private: - // ApplicationDelegate: - void Initialize(ApplicationImpl* impl) override { app_url_ = impl->url(); } - - bool ConfigureIncomingConnection( - mojo::ApplicationConnection* connection) override { - connection->AddService(this); - return true; - } - - // InterfaceFactory<Pingable>: - void Create(mojo::ApplicationConnection* connection, - mojo::InterfaceRequest<Pingable> request) override { - new PingableImpl(request.Pass(), app_url_, connection->GetConnectionURL()); - } - - std::string app_url_; -}; - -} // namespace mojo - -MojoResult MojoMain(MojoHandle shell_handle) { - mojo::ApplicationRunner runner(new mojo::PingableApp); - return runner.Run(shell_handle); -} diff --git a/mojo/shell/url_resolver.cc b/mojo/shell/url_resolver.cc deleted file mode 100644 index 20cb000..0000000 --- a/mojo/shell/url_resolver.cc +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2014 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/shell/url_resolver.h" - -#include "base/base_paths.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/strings/utf_string_conversions.h" -#include "mojo/shell/application_manager/query_util.h" -#include "mojo/shell/filename_util.h" -#include "mojo/shell/switches.h" -#include "url/url_util.h" - -namespace mojo { -namespace shell { - -URLResolver::URLResolver() { - // Needed to treat first component of mojo URLs as host, not path. - url::AddStandardScheme("mojo"); -} - -URLResolver::~URLResolver() { -} - -// static -std::vector<URLResolver::OriginMapping> URLResolver::GetOriginMappings( - const base::CommandLine::StringVector& args) { - std::vector<OriginMapping> origin_mappings; - const std::string kArgsForSwitches[] = { - "-" + std::string(switches::kMapOrigin) + "=", - "--" + std::string(switches::kMapOrigin) + "=", - }; - for (auto& arg : args) { - for (size_t i = 0; i < arraysize(kArgsForSwitches); i++) { - const std::string& argsfor_switch = kArgsForSwitches[i]; - std::string arg_string; -#if defined(OS_WIN) - arg_string = base::UTF16ToUTF8(arg); -#else - arg_string = arg; -#endif - if (arg_string.compare(0, argsfor_switch.size(), argsfor_switch) == 0) { - std::string value = - arg_string.substr(argsfor_switch.size(), std::string::npos); - size_t delim = value.find('='); - if (delim <= 0 || delim >= value.size()) - continue; - origin_mappings.push_back( - OriginMapping(value.substr(0, delim), - value.substr(delim + 1, std::string::npos))); - } - } - } - return origin_mappings; -} - -void URLResolver::AddURLMapping(const GURL& url, const GURL& mapped_url) { - url_map_[url] = mapped_url; -} - -void URLResolver::AddOriginMapping(const GURL& origin, const GURL& base_url) { - if (!origin.is_valid() || !base_url.is_valid() || - origin != origin.GetOrigin()) { - // Disallow invalid mappings. - LOG(ERROR) << "Invalid origin for mapping: " << origin; - return; - } - // Force both origin and base_url to have trailing slashes. - origin_map_[origin] = AddTrailingSlashIfNeeded(base_url); -} - -GURL URLResolver::ApplyMappings(const GURL& url) const { - std::string query; - GURL mapped_url = GetBaseURLAndQuery(url, &query); - for (;;) { - const auto& url_it = url_map_.find(mapped_url); - if (url_it != url_map_.end()) { - mapped_url = url_it->second; - continue; - } - - GURL origin = mapped_url.GetOrigin(); - const auto& origin_it = origin_map_.find(origin); - if (origin_it == origin_map_.end()) - break; - mapped_url = GURL(origin_it->second.spec() + - mapped_url.spec().substr(origin.spec().length())); - } - - if (query.length()) - mapped_url = GURL(mapped_url.spec() + query); - return mapped_url; -} - -void URLResolver::SetMojoBaseURL(const GURL& mojo_base_url) { - DCHECK(mojo_base_url.is_valid()); - // Force a trailing slash on the base_url to simplify resolving - // relative files and URLs below. - mojo_base_url_ = AddTrailingSlashIfNeeded(mojo_base_url); -} - -GURL URLResolver::ResolveMojoURL(const GURL& mojo_url) const { - if (mojo_url.scheme() != "mojo") { - // The mapping has produced some sort of non-mojo: URL - file:, http:, etc. - return mojo_url; - } else { - // It's still a mojo: URL, use the default mapping scheme. - std::string query; - GURL base_url = GetBaseURLAndQuery(mojo_url, &query); - std::string lib = base_url.host() + ".mojo" + query; - return mojo_base_url_.Resolve(lib); - } -} - -} // namespace shell -} // namespace mojo diff --git a/mojo/shell/url_resolver.h b/mojo/shell/url_resolver.h deleted file mode 100644 index 03f9076..0000000 --- a/mojo/shell/url_resolver.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2014 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 SHELL_URL_RESOLVER_H_ -#define SHELL_URL_RESOLVER_H_ - -#include <map> -#include <set> - -#include "base/basictypes.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "url/gurl.h" - -namespace mojo { -namespace shell { - -// This class supports the mapping of URLs to other URLs. -// It's commonly used with mojo: URL, to provide a physical location (i.e. -// file: or https:) but works with any URL. -// By default, "mojo:" URLs resolve to a file location, with ".mojo" appended, -// but that resolution can be customized via the AddCustomMapping method. -class URLResolver { - public: - URLResolver(); - ~URLResolver(); - - // Used for the return value of GetOriginMappings(). - struct OriginMapping { - OriginMapping(const std::string& origin, const std::string& base_url) - : origin(origin), base_url(base_url) {} - - std::string origin; - std::string base_url; - }; - - // Returns a list of origin mappings based on command line args. - // The switch --map-origin can be specified multiple times. Each occurance - // has the format of --map-origin={origin}={base_url} - // For example: - // --map-origin=http://domokit.org=file:///source/out - static std::vector<OriginMapping> GetOriginMappings( - const base::CommandLine::StringVector& argv); - - // Add a custom mapping for a particular URL. If |mapped_url| is - // itself a mojo url normal resolution rules apply. - void AddURLMapping(const GURL& url, const GURL& mapped_url); - - // Add a custom mapping for all urls rooted at |origin|. - void AddOriginMapping(const GURL& origin, const GURL& base_url); - - // Applies all custom mappings for |url|, returning the last non-mapped url. - // For example, if 'a' maps to 'b' and 'b' maps to 'c' calling this with 'a' - // returns 'c'. - GURL ApplyMappings(const GURL& url) const; - - // If specified, then "mojo:" URLs will be resolved relative to this - // URL. That is, the portion after the colon will be appeneded to - // |mojo_base_url| with .mojo appended. - void SetMojoBaseURL(const GURL& mojo_base_url); - - // Resolve the given "mojo:" URL to the URL that should be used to fetch the - // code for the corresponding Mojo App. - GURL ResolveMojoURL(const GURL& mojo_url) const; - - private: - using GURLToGURLMap = std::map<GURL, GURL>; - GURLToGURLMap url_map_; - GURLToGURLMap origin_map_; - GURL mojo_base_url_; - - DISALLOW_COPY_AND_ASSIGN(URLResolver); -}; - -} // namespace shell -} // namespace mojo - -#endif // SHELL_URL_RESOLVER_H_ diff --git a/mojo/shell/url_resolver_unittest.cc b/mojo/shell/url_resolver_unittest.cc deleted file mode 100644 index dd8da75..0000000 --- a/mojo/shell/url_resolver_unittest.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2014 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/shell/url_resolver.h" - -#include "base/logging.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace shell { -namespace test { -namespace { - -typedef testing::Test URLResolverTest; - -TEST_F(URLResolverTest, MojoURLsFallThrough) { - URLResolver resolver; - resolver.AddURLMapping(GURL("mojo:test"), GURL("mojo:foo")); - const GURL base_url("file:/base"); - resolver.SetMojoBaseURL(base_url); - GURL mapped_url = resolver.ApplyMappings(GURL("mojo:test")); - std::string resolved(resolver.ResolveMojoURL(mapped_url).spec()); - // Resolved must start with |base_url|. - EXPECT_EQ(base_url.spec(), resolved.substr(0, base_url.spec().size())); - // And must contain foo. - EXPECT_NE(std::string::npos, resolved.find("foo")); -} - -TEST_F(URLResolverTest, MapURL) { - URLResolver resolver; - resolver.AddURLMapping(GURL("https://domokit.org/test.mojo"), - GURL("file:///mojo/src/out/Debug/test.mojo")); - GURL mapped_url = - resolver.ApplyMappings(GURL("https://domokit.org/test.mojo")); - EXPECT_EQ("file:///mojo/src/out/Debug/test.mojo", mapped_url.spec()); -} - -TEST_F(URLResolverTest, MultipleMapURL) { - URLResolver resolver; - resolver.AddURLMapping(GURL("https://a.org/foo"), - GURL("https://b.org/a/foo")); - resolver.AddURLMapping(GURL("https://b.org/a/foo"), - GURL("https://c.org/b/a/foo")); - GURL mapped_url = resolver.ApplyMappings(GURL("https://a.org/foo")); - EXPECT_EQ("https://c.org/b/a/foo", mapped_url.spec()); -} - -TEST_F(URLResolverTest, MapOrigin) { - URLResolver resolver; - resolver.AddOriginMapping(GURL("https://domokit.org"), - GURL("file:///mojo/src/out/Debug")); - GURL mapped_url = - resolver.ApplyMappings(GURL("https://domokit.org/test.mojo")); - EXPECT_EQ("file:///mojo/src/out/Debug/test.mojo", mapped_url.spec()); -} - -TEST_F(URLResolverTest, MultipleMapOrigin) { - URLResolver resolver; - resolver.AddOriginMapping(GURL("https://a.org"), GURL("https://b.org/a")); - resolver.AddOriginMapping(GURL("https://b.org"), GURL("https://c.org/b")); - GURL mapped_url = resolver.ApplyMappings(GURL("https://a.org/foo")); - EXPECT_EQ("https://c.org/b/a/foo", mapped_url.spec()); -} - -TEST_F(URLResolverTest, MapOriginThenURL) { - URLResolver resolver; - resolver.AddOriginMapping(GURL("https://a.org"), GURL("https://b.org/a")); - resolver.AddURLMapping(GURL("https://b.org/a/foo"), - GURL("https://c.org/b/a/foo")); - GURL mapped_url = resolver.ApplyMappings(GURL("https://a.org/foo")); - EXPECT_EQ("https://c.org/b/a/foo", mapped_url.spec()); -} - -TEST_F(URLResolverTest, MapURLThenOrigin) { - URLResolver resolver; - resolver.AddURLMapping(GURL("https://a.org/foo"), - GURL("https://b.org/a/foo")); - resolver.AddOriginMapping(GURL("https://b.org"), GURL("https://c.org/b")); - GURL mapped_url = resolver.ApplyMappings(GURL("https://a.org/foo")); - EXPECT_EQ("https://c.org/b/a/foo", mapped_url.spec()); -} - -#if defined(OS_POSIX) -#define ARG_LITERAL(x) x -#elif defined(OS_WIN) -#define ARG_LITERAL(x) L ## x -#endif - -TEST_F(URLResolverTest, GetOriginMappings) { - base::CommandLine::StringVector args; - args.push_back(ARG_LITERAL("--map-origin=https://a.org=https://b.org/a")); - std::vector<URLResolver::OriginMapping> mappings = - URLResolver::GetOriginMappings(args); - ASSERT_EQ(1U, mappings.size()); - EXPECT_EQ("https://a.org", mappings[0].origin); - EXPECT_EQ("https://b.org/a", mappings[0].base_url); - - args.clear(); - args.push_back(ARG_LITERAL("-map-origin=https://a.org=https://b.org/a")); - mappings = URLResolver::GetOriginMappings(args); - ASSERT_EQ(1U, mappings.size()); - EXPECT_EQ("https://a.org", mappings[0].origin); - EXPECT_EQ("https://b.org/a", mappings[0].base_url); - - args.clear(); - args.push_back(ARG_LITERAL("--map-origin")); - mappings = URLResolver::GetOriginMappings(args); - EXPECT_EQ(0U, mappings.size()); - - args.clear(); - args.push_back(ARG_LITERAL("--map-origin=")); - mappings = URLResolver::GetOriginMappings(args); - EXPECT_EQ(0U, mappings.size()); - - args.clear(); - args.push_back(ARG_LITERAL("mojo_shell")); - args.push_back(ARG_LITERAL("--map-origin=https://a.org=https://b.org/a")); - args.push_back(ARG_LITERAL("--map-origin=https://b.org=https://c.org/b")); - args.push_back(ARG_LITERAL("https://a.org/foo")); - mappings = URLResolver::GetOriginMappings(args); - ASSERT_EQ(2U, mappings.size()); - EXPECT_EQ("https://a.org", mappings[0].origin); - EXPECT_EQ("https://b.org/a", mappings[0].base_url); - EXPECT_EQ("https://b.org", mappings[1].origin); - EXPECT_EQ("https://c.org/b", mappings[1].base_url); -} - -TEST_F(URLResolverTest, TestQueryForURLMapping) { - URLResolver resolver; - resolver.SetMojoBaseURL(GURL("file:/base")); - resolver.AddURLMapping(GURL("https://a.org/foo"), - GURL("https://b.org/a/foo")); - resolver.AddURLMapping(GURL("https://b.org/a/foo"), - GURL("https://c.org/b/a/foo")); - GURL mapped_url = resolver.ApplyMappings(GURL("https://a.org/foo?a=b")); - EXPECT_EQ("https://c.org/b/a/foo?a=b", mapped_url.spec()); -} - -TEST_F(URLResolverTest, TestQueryForBaseURL) { - URLResolver resolver; - resolver.SetMojoBaseURL(GURL("file:///base")); - GURL mapped_url = resolver.ResolveMojoURL(GURL("mojo:foo?a=b")); - EXPECT_EQ("file:///base/foo.mojo?a=b", mapped_url.spec()); -} - -} // namespace -} // namespace test -} // namespace shell -} // namespace mojo |