summaryrefslogtreecommitdiff
path: root/mojo
diff options
context:
space:
mode:
Diffstat (limited to 'mojo')
-rw-r--r--mojo/android/DEPS3
-rw-r--r--mojo/android/javatests/AndroidManifest.xml21
-rw-r--r--mojo/android/javatests/apk/EMPTY (renamed from mojo/public/tools/bindings/pylib/generate/__init__.py)0
-rw-r--r--mojo/android/javatests/core_test.cc26
-rw-r--r--mojo/android/javatests/core_test.h20
-rw-r--r--mojo/android/javatests/init_library.cc40
-rw-r--r--mojo/android/javatests/src/org/chromium/mojo/system/CoreTest.java471
-rw-r--r--mojo/android/system/core_impl.cc293
-rw-r--r--mojo/android/system/core_impl.h20
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/CoreImpl.java584
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/CoreSingleton.java18
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/DataPipeConsumerHandleImpl.java63
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/DataPipeProducerHandleImpl.java55
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/HandleImpl.java112
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/MessagePipeHandleImpl.java47
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/SharedBufferHandleImpl.java52
-rw-r--r--mojo/android/system/src/org/chromium/mojo/system/UntypedHandleImpl.java54
-rw-r--r--mojo/apps/js/bindings/connection_unittests.js6
-rw-r--r--mojo/apps/js/bindings/sample_service_unittests.js6
-rw-r--r--mojo/apps/js/main.js2
-rw-r--r--mojo/apps/js/test/run_apps_js_tests.cc2
-rw-r--r--mojo/bindings/js/codec_unittests.js39
-rw-r--r--mojo/bindings/js/core.cc2
-rw-r--r--mojo/bindings/js/core_unittests.js2
-rw-r--r--mojo/bindings/js/run_js_tests.cc2
-rw-r--r--mojo/bindings/js/support.cc2
-rw-r--r--mojo/bindings/js/unicode.cc69
-rw-r--r--mojo/bindings/js/unicode.h22
-rw-r--r--mojo/bindings/js/waiting_callback.h2
-rw-r--r--mojo/common/DEPS1
-rw-r--r--mojo/common/message_pump_mojo.cc92
-rw-r--r--mojo/common/message_pump_mojo.h17
-rw-r--r--mojo/common/mojo_channel_init.cc59
-rw-r--r--mojo/common/mojo_channel_init.h66
-rw-r--r--mojo/embedder/embedder.cc2
-rw-r--r--mojo/environment/default_async_waiter_impl.h2
-rw-r--r--mojo/examples/sample_view_manager_app/sample_view_manager_app.cc74
-rw-r--r--mojo/examples/view_manager/view_manager.cc150
-rw-r--r--mojo/examples/view_manager/view_manager.mojom26
-rw-r--r--mojo/mojo.gyp107
-rw-r--r--mojo/mojo_apps.gypi2
-rw-r--r--mojo/mojo_bindings.target.darwin-arm.mk1
-rw-r--r--mojo/mojo_bindings.target.darwin-mips.mk1
-rw-r--r--mojo/mojo_bindings.target.darwin-x86.mk1
-rw-r--r--mojo/mojo_bindings.target.darwin-x86_64.mk1
-rw-r--r--mojo/mojo_bindings.target.linux-arm.mk1
-rw-r--r--mojo/mojo_bindings.target.linux-mips.mk1
-rw-r--r--mojo/mojo_bindings.target.linux-x86.mk1
-rw-r--r--mojo/mojo_bindings.target.linux-x86_64.mk1
-rw-r--r--mojo/mojo_common_lib.target.darwin-arm.mk2
-rw-r--r--mojo/mojo_common_lib.target.darwin-mips.mk2
-rw-r--r--mojo/mojo_common_lib.target.darwin-x86.mk2
-rw-r--r--mojo/mojo_common_lib.target.darwin-x86_64.mk2
-rw-r--r--mojo/mojo_common_lib.target.linux-arm.mk2
-rw-r--r--mojo/mojo_common_lib.target.linux-mips.mk2
-rw-r--r--mojo/mojo_common_lib.target.linux-x86.mk2
-rw-r--r--mojo/mojo_common_lib.target.linux-x86_64.mk2
-rw-r--r--mojo/mojo_environment_chromium.target.darwin-arm.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.darwin-mips.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.darwin-x86.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.darwin-x86_64.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.linux-arm.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.linux-mips.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.linux-x86.mk1
-rw-r--r--mojo/mojo_environment_chromium.target.linux-x86_64.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.darwin-arm.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.darwin-mips.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.darwin-x86.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.linux-arm.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.linux-mips.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.linux-x86.mk1
-rw-r--r--mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk1
-rw-r--r--mojo/mojo_examples.gypi45
-rw-r--r--mojo/mojo_js_bindings_lib.target.darwin-arm.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.darwin-mips.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.darwin-x86.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.linux-arm.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.linux-mips.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.linux-x86.mk2
-rw-r--r--mojo/mojo_js_bindings_lib.target.linux-x86_64.mk2
-rw-r--r--mojo/mojo_public.gypi44
-rw-r--r--mojo/mojo_service_manager.target.darwin-arm.mk1
-rw-r--r--mojo/mojo_service_manager.target.darwin-mips.mk1
-rw-r--r--mojo/mojo_service_manager.target.darwin-x86.mk1
-rw-r--r--mojo/mojo_service_manager.target.darwin-x86_64.mk1
-rw-r--r--mojo/mojo_service_manager.target.linux-arm.mk1
-rw-r--r--mojo/mojo_service_manager.target.linux-mips.mk1
-rw-r--r--mojo/mojo_service_manager.target.linux-x86.mk1
-rw-r--r--mojo/mojo_service_manager.target.linux-x86_64.mk1
-rw-r--r--mojo/mojo_services.gypi122
-rw-r--r--mojo/mojo_shell_bindings.target.darwin-arm.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.darwin-mips.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.darwin-x86.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.darwin-x86_64.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.linux-arm.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.linux-mips.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.linux-x86.mk5
-rw-r--r--mojo/mojo_shell_bindings.target.linux-x86_64.mk5
-rw-r--r--mojo/mojo_system_impl.target.darwin-arm.mk1
-rw-r--r--mojo/mojo_system_impl.target.darwin-mips.mk1
-rw-r--r--mojo/mojo_system_impl.target.darwin-x86.mk1
-rw-r--r--mojo/mojo_system_impl.target.darwin-x86_64.mk1
-rw-r--r--mojo/mojo_system_impl.target.linux-arm.mk1
-rw-r--r--mojo/mojo_system_impl.target.linux-mips.mk1
-rw-r--r--mojo/mojo_system_impl.target.linux-x86.mk1
-rw-r--r--mojo/mojo_system_impl.target.linux-x86_64.mk1
-rw-r--r--mojo/public/README.md75
-rw-r--r--mojo/public/c/README.md45
-rw-r--r--mojo/public/c/environment/async_waiter.h (renamed from mojo/public/c/system/async_waiter.h)6
-rw-r--r--mojo/public/c/gles2/DEPS3
-rw-r--r--mojo/public/c/gles2/gles2.h2
-rw-r--r--mojo/public/c/system/tests/core_unittest_pure_c.c2
-rw-r--r--mojo/public/cpp/README.md71
-rw-r--r--mojo/public/cpp/bindings/array.h6
-rw-r--r--mojo/public/cpp/bindings/lib/array_internal.cc22
-rw-r--r--mojo/public/cpp/bindings/lib/array_internal.h185
-rw-r--r--mojo/public/cpp/bindings/lib/bindings_internal.h23
-rw-r--r--mojo/public/cpp/bindings/lib/bindings_serialization.cc2
-rw-r--r--mojo/public/cpp/bindings/lib/shared_data.h1
-rw-r--r--mojo/public/cpp/bindings/tests/array_unittest.cc82
-rw-r--r--mojo/public/cpp/bindings/tests/handle_passing_unittest.cc33
-rw-r--r--mojo/public/cpp/bindings/tests/request_response_unittest.cc38
-rw-r--r--mojo/public/cpp/bindings/tests/sample_service_unittest.cc19
-rw-r--r--mojo/public/cpp/environment/DEPS3
-rw-r--r--mojo/public/cpp/environment/default_async_waiter.h2
-rw-r--r--mojo/public/cpp/shell/application.h18
-rw-r--r--mojo/public/cpp/shell/lib/application.cc42
-rw-r--r--mojo/public/cpp/shell/lib/service.cc6
-rw-r--r--mojo/public/cpp/shell/service.h81
-rw-r--r--mojo/public/gles2/gles2_private.h2
-rw-r--r--mojo/public/interfaces/bindings/tests/sample_factory.mojom1
-rw-r--r--mojo/public/interfaces/bindings/tests/sample_interfaces.mojom5
-rw-r--r--mojo/public/interfaces/bindings/tests/sample_service.mojom11
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/Core.java178
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/DataPipe.java308
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/Flags.java48
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/Handle.java36
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/MessagePipeHandle.java181
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/MojoException.java36
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/MojoResult.java82
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/Pair.java61
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java139
-rw-r--r--mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java41
-rw-r--r--mojo/public/js/bindings/codec.js434
-rw-r--r--mojo/public/js/bindings/connector.js17
-rw-r--r--mojo/public/js/bindings/core.js215
-rw-r--r--mojo/public/js/bindings/support.js30
-rw-r--r--mojo/public/js/bindings/unicode.js33
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl5
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl8
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl6
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl8
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl8
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl8
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl26
-rw-r--r--mojo/public/tools/bindings/generators/js_templates/module.js.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl12
-rw-r--r--mojo/public/tools/bindings/generators/mojom_cpp_generator.py43
-rw-r--r--mojo/public/tools/bindings/generators/mojom_js_generator.py59
-rwxr-xr-xmojo/public/tools/bindings/generators/run_cpp_generator.py4
-rw-r--r--mojo/public/tools/bindings/mojom_bindings_generator.gypi21
-rwxr-xr-xmojo/public/tools/bindings/mojom_bindings_generator.py41
-rw-r--r--mojo/public/tools/bindings/mojom_bindings_generator_unittest.py23
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/__init__.py (renamed from mojo/public/tools/bindings/pylib/parse/__init__.py)0
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/__init__.py0
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/data.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_data.py)30
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/data_tests.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_data_tests.py)27
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/generator.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_generator.py)15
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/module.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom.py)7
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/module_tests.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_tests.py)15
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/pack.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_pack.py)6
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/pack_tests.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_pack_tests.py)26
-rwxr-xr-xmojo/public/tools/bindings/pylib/mojom/generate/run_tests.py (renamed from mojo/public/tools/bindings/pylib/generate/run_mojom_tests.py)6
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py (renamed from mojo/public/tools/bindings/pylib/generate/template_expander.py)16
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/test_support.py (renamed from mojo/public/tools/bindings/pylib/generate/mojom_test.py)3
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/parse/__init__.py0
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/parse/ast.py25
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/parse/lexer.py (renamed from mojo/public/tools/bindings/pylib/parse/mojo_lexer.py)17
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/parse/lexer_unittest.py (renamed from mojo/public/tools/bindings/pylib/parse/mojo_lexer_unittest.py)26
-rwxr-xr-xmojo/public/tools/bindings/pylib/mojom/parse/parser.py (renamed from mojo/public/tools/bindings/pylib/parse/mojo_parser.py)64
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/parse/parser_unittest.py (renamed from mojo/public/tools/bindings/pylib/parse/mojo_parser_unittest.py)114
-rwxr-xr-xmojo/public/tools/bindings/pylib/mojom/parse/translate.py (renamed from mojo/public/tools/bindings/pylib/parse/mojo_translate.py)22
-rw-r--r--mojo/service_manager/service_manager.cc31
-rw-r--r--mojo/service_manager/service_manager.h22
-rw-r--r--mojo/service_manager/service_manager_unittest.cc192
-rw-r--r--mojo/services/native_viewport/native_viewport_android.h2
-rw-r--r--mojo/services/native_viewport/native_viewport_export.h6
-rw-r--r--mojo/services/native_viewport/native_viewport_service.cc10
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view.cc0
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager.cc0
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_host.cc0
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node.cc144
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node_observer.cc26
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node_private.cc20
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h37
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc0
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_tree_host_unittest.cc0
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc330
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_unittest.cc0
-rw-r--r--mojo/services/public/cpp/view_manager/view.h24
-rw-r--r--mojo/services/public/cpp/view_manager/view_manager.h24
-rw-r--r--mojo/services/public/cpp/view_manager/view_tree_host.h24
-rw-r--r--mojo/services/public/cpp/view_manager/view_tree_node.h61
-rw-r--r--mojo/services/public/cpp/view_manager/view_tree_node_observer.h44
-rw-r--r--mojo/services/public/interfaces/view_manager/view_manager.mojom54
-rw-r--r--mojo/services/view_manager/DEPS (renamed from mojo/examples/view_manager/DEPS)2
-rw-r--r--mojo/services/view_manager/ids.h71
-rw-r--r--mojo/services/view_manager/node.cc60
-rw-r--r--mojo/services/view_manager/node.h53
-rw-r--r--mojo/services/view_manager/node_delegate.h31
-rw-r--r--mojo/services/view_manager/root_node_manager.cc106
-rw-r--r--mojo/services/view_manager/root_node_manager.h117
-rw-r--r--mojo/services/view_manager/view_manager.cc32
-rw-r--r--mojo/services/view_manager/view_manager_connection.cc101
-rw-r--r--mojo/services/view_manager/view_manager_connection.h81
-rw-r--r--mojo/services/view_manager/view_manager_connection_unittest.cc307
-rw-r--r--mojo/services/view_manager/view_manager_export.h31
-rw-r--r--mojo/shell/android/mojo_main.cc31
-rw-r--r--mojo/shell/context.cc14
-rw-r--r--mojo/shell/context.h2
-rw-r--r--mojo/system/channel.cc300
-rw-r--r--mojo/system/channel.h58
-rw-r--r--mojo/system/local_message_pipe_endpoint.cc16
-rw-r--r--mojo/system/local_message_pipe_endpoint.h4
-rw-r--r--mojo/system/message_in_transit.cc6
-rw-r--r--mojo/system/message_in_transit.h4
-rw-r--r--mojo/system/message_pipe.cc54
-rw-r--r--mojo/system/message_pipe.h3
-rw-r--r--mojo/system/message_pipe_dispatcher.cc20
-rw-r--r--mojo/system/message_pipe_endpoint.cc11
-rw-r--r--mojo/system/message_pipe_endpoint.h9
-rw-r--r--mojo/system/proxy_message_pipe_endpoint.cc64
-rw-r--r--mojo/system/proxy_message_pipe_endpoint.h21
-rw-r--r--mojo/system/raw_channel.h17
-rw-r--r--mojo/system/remote_message_pipe_unittest.cc12
-rw-r--r--mojo/tools/data/unittests1
-rwxr-xr-xmojo/tools/mojob.sh4
-rwxr-xr-xmojo/tools/run_mojo_python_tests.py40
241 files changed, 7701 insertions, 1309 deletions
diff --git a/mojo/android/DEPS b/mojo/android/DEPS
new file mode 100644
index 0000000000..c80012b562
--- /dev/null
+++ b/mojo/android/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+jni",
+]
diff --git a/mojo/android/javatests/AndroidManifest.xml b/mojo/android/javatests/AndroidManifest.xml
new file mode 100644
index 0000000000..8968941f5b
--- /dev/null
+++ b/mojo/android/javatests/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <!-- Copyright (c) 2012 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 name must be unique so suffix with "tests" so package loader
+ doesn't ignore this. -->
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.chromium.mojo.tests">
+ <!-- We add an application tag here just so that we can indicate that this
+ package needs to link against the android.test library, which is
+ needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="org.chromium.mojo.tests"
+ android:label="Tests for org.chromium.mojo"/>
+ <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
+ <uses-permission android:name="android.permission.INJECT_EVENTS" />
+</manifest>
diff --git a/mojo/public/tools/bindings/pylib/generate/__init__.py b/mojo/android/javatests/apk/EMPTY
index e69de29bb2..e69de29bb2 100644
--- a/mojo/public/tools/bindings/pylib/generate/__init__.py
+++ b/mojo/android/javatests/apk/EMPTY
diff --git a/mojo/android/javatests/core_test.cc b/mojo/android/javatests/core_test.cc
new file mode 100644
index 0000000000..3d4032fc52
--- /dev/null
+++ b/mojo/android/javatests/core_test.cc
@@ -0,0 +1,26 @@
+// 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/android/javatests/core_test.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+#include "jni/CoreTest_jni.h"
+
+namespace mojo {
+namespace android {
+
+static void InitApplicationContext(JNIEnv* env,
+ jobject jcaller,
+ jobject context) {
+ base::android::ScopedJavaLocalRef<jobject> scoped_context(env, context);
+ base::android::InitApplicationContext(env, scoped_context);
+}
+
+bool RegisterCoreTest(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace mojo
diff --git a/mojo/android/javatests/core_test.h b/mojo/android/javatests/core_test.h
new file mode 100644
index 0000000000..96c8878ced
--- /dev/null
+++ b/mojo/android/javatests/core_test.h
@@ -0,0 +1,20 @@
+// 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_ANDROID_JAVATESTS_CORE_TEST_H_
+#define MOJO_ANDROID_JAVATESTS_CORE_TEST_H_
+
+#include <jni.h>
+
+#include "base/android/jni_android.h"
+
+namespace mojo {
+namespace android {
+
+JNI_EXPORT bool RegisterCoreTest(JNIEnv* env);
+
+} // namespace android
+} // namespace mojo
+
+#endif // MOJO_SYSTEM_ANDROID_JAVATESTS_CORE_TEST_H_
diff --git a/mojo/android/javatests/init_library.cc b/mojo/android/javatests/init_library.cc
new file mode 100644
index 0000000000..7b4cbe3517
--- /dev/null
+++ b/mojo/android/javatests/init_library.cc
@@ -0,0 +1,40 @@
+// 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/base_jni_registrar.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "base/android/library_loader/library_loader_hooks.h"
+#include "mojo/android/javatests/core_test.h"
+#include "mojo/android/system/core_impl.h"
+
+namespace {
+
+base::android::RegistrationMethod kMojoRegisteredMethods[] = {
+ { "CoreImpl", mojo::android::RegisterCoreImpl },
+ { "CoreTest", mojo::android::RegisterCoreTest },
+};
+
+bool RegisterMojoJni(JNIEnv* env) {
+ return RegisterNativeMethods(env, kMojoRegisteredMethods,
+ arraysize(kMojoRegisteredMethods));
+}
+
+} // namespace
+
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ base::android::InitVM(vm);
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ if (!base::android::RegisterLibraryLoaderEntryHook(env))
+ return -1;
+
+ if (!base::android::RegisterJni(env))
+ return -1;
+
+ if (!RegisterMojoJni(env))
+ return -1;
+
+ return JNI_VERSION_1_4;
+}
diff --git a/mojo/android/javatests/src/org/chromium/mojo/system/CoreTest.java b/mojo/android/javatests/src/org/chromium/mojo/system/CoreTest.java
new file mode 100644
index 0000000000..97f091245d
--- /dev/null
+++ b/mojo/android/javatests/src/org/chromium/mojo/system/CoreTest.java
@@ -0,0 +1,471 @@
+// 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.system;
+
+import android.content.Context;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.JNINamespace;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.mojo.system.Core.WaitFlags;
+import org.chromium.mojo.system.Core.WaitManyResult;
+import org.chromium.mojo.system.MessagePipeHandle.ReadFlags;
+import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
+import org.chromium.mojo.system.MessagePipeHandle.WriteFlags;
+import org.chromium.mojo.system.SharedBufferHandle.MapFlags;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Testing the core API.
+ */
+@JNINamespace("mojo::android")
+public class CoreTest extends InstrumentationTestCase {
+
+ private static final ScheduledExecutorService WORKER =
+ Executors.newSingleThreadScheduledExecutor();
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ LibraryLoader.ensureInitialized();
+ nativeInitApplicationContext(getInstrumentation().getTargetContext());
+ }
+
+ /**
+ * Runnable that will close the given handle.
+ */
+ private static class CloseHandle implements Runnable {
+ private Handle mHandle;
+
+ CloseHandle(Handle handle) {
+ mHandle = handle;
+ }
+
+ @Override
+ public void run() {
+ mHandle.close();
+ }
+ }
+
+ private static void checkSendingMessage(MessagePipeHandle in, MessagePipeHandle out) {
+ Random random = new Random();
+
+ // Writing a random 8 bytes message.
+ byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+ ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
+ buffer.put(bytes);
+ in.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.none());
+
+ // Try to read into a small buffer.
+ ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length / 2);
+ MessagePipeHandle.ReadMessageResult result = out.readMessage(receiveBuffer, 0,
+ MessagePipeHandle.ReadFlags.none());
+ assertFalse(result.getWasMessageRead());
+ assertEquals(bytes.length, result.getMessageSize());
+ assertEquals(0, result.getHandlesCount());
+
+ // Read into a correct buffer.
+ receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
+ result = out.readMessage(receiveBuffer, 0,
+ MessagePipeHandle.ReadFlags.none());
+ assertTrue(result.getWasMessageRead());
+ assertEquals(bytes.length, result.getMessageSize());
+ assertEquals(0, result.getHandlesCount());
+ assertEquals(0, receiveBuffer.position());
+ assertEquals(result.getMessageSize(), receiveBuffer.limit());
+ byte[] receivedBytes = new byte[result.getMessageSize()];
+ receiveBuffer.get(receivedBytes);
+ assertTrue(Arrays.equals(bytes, receivedBytes));
+
+ }
+
+ /**
+ * Testing {@link Core#waitMany(List, long)}.
+ */
+ @SmallTest
+ public void testWaitMany() {
+ Core core = CoreSingleton.getInstance();
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
+
+ try {
+ List<Pair<Handle, WaitFlags>> handlesToWaitOn = new ArrayList<
+ Pair<Handle, WaitFlags>>();
+
+ handlesToWaitOn.add(
+ new Pair<Handle, WaitFlags>(handles.second,
+ WaitFlags.none().setReadable(true)));
+ handlesToWaitOn.add(
+ new Pair<Handle, WaitFlags>(handles.first, WaitFlags.none().setWritable(true)));
+ WaitManyResult result = core.waitMany(handlesToWaitOn, 0);
+ assertEquals(MojoResult.OK, result.getMojoResult());
+ assertEquals(1, result.getHandleIndex());
+
+ handlesToWaitOn.clear();
+ handlesToWaitOn.add(
+ new Pair<Handle, WaitFlags>(handles.first, WaitFlags.none().setWritable(true)));
+ handlesToWaitOn.add(
+ new Pair<Handle, WaitFlags>(handles.second,
+ WaitFlags.none().setReadable(true)));
+ result = core.waitMany(handlesToWaitOn, 0);
+ assertEquals(MojoResult.OK, result.getMojoResult());
+ assertEquals(0, result.getHandleIndex());
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+ }
+
+ /**
+ * Testing {@link MessagePipeHandle}.
+ */
+ @SmallTest
+ public void testMessagePipeEmpty() {
+ Core core = CoreSingleton.getInstance();
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
+
+ try {
+ // Testing wait.
+ assertEquals(MojoResult.OK, handles.first.wait(WaitFlags.all(), 0));
+ assertEquals(MojoResult.OK, handles.first.wait(WaitFlags.none().setWritable(true), 0));
+ assertEquals(MojoResult.DEADLINE_EXCEEDED,
+ handles.first.wait(WaitFlags.none().setReadable(true), 0));
+
+ // Testing read on an empty pipe.
+ boolean exception = false;
+ try {
+ handles.first.readMessage(null, 0, MessagePipeHandle.ReadFlags.none());
+ } catch (MojoException e) {
+ assertEquals(MojoResult.SHOULD_WAIT, e.getMojoResult());
+ exception = true;
+ }
+ assertTrue(exception);
+
+ // Closing a pipe while waiting.
+ WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
+ assertEquals(MojoResult.CANCELLED,
+ handles.first.wait(WaitFlags.none().setReadable(true), 1000000L));
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+
+ handles = core.createMessagePipe();
+
+ try {
+ // Closing the other pipe while waiting.
+ WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
+ assertEquals(MojoResult.FAILED_PRECONDITION,
+ handles.second.wait(WaitFlags.none().setReadable(true), 1000000L));
+
+ // Waiting on a closed pipe.
+ assertEquals(MojoResult.FAILED_PRECONDITION,
+ handles.second.wait(WaitFlags.none().setReadable(true), 0));
+ assertEquals(MojoResult.FAILED_PRECONDITION,
+ handles.second.wait(WaitFlags.none().setWritable(true), 0));
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+
+ }
+
+ /**
+ * Testing {@link MessagePipeHandle}.
+ */
+ @SmallTest
+ public void testMessagePipeSend() {
+ Core core = CoreSingleton.getInstance();
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
+
+ try {
+ checkSendingMessage(handles.first, handles.second);
+ checkSendingMessage(handles.second, handles.first);
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+ }
+
+ /**
+ * Testing {@link MessagePipeHandle}.
+ */
+ @SmallTest
+ public void testMessagePipeReceiveOnSmallBuffer() {
+ Random random = new Random();
+ Core core = CoreSingleton.getInstance();
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
+
+ try {
+ // Writing a random 8 bytes message.
+ byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+ ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
+ buffer.put(bytes);
+ handles.first.writeMessage(buffer, null, MessagePipeHandle.WriteFlags.none());
+
+ ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(1);
+ MessagePipeHandle.ReadMessageResult result = handles.second.readMessage(receiveBuffer,
+ 0,
+ MessagePipeHandle.ReadFlags.none());
+ assertFalse(result.getWasMessageRead());
+ assertEquals(bytes.length, result.getMessageSize());
+ assertEquals(0, result.getHandlesCount());
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+ }
+
+ /**
+ * Testing {@link MessagePipeHandle}.
+ */
+ @SmallTest
+ public void testMessagePipeSendHandles() {
+ Core core = CoreSingleton.getInstance();
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
+ Pair<MessagePipeHandle, MessagePipeHandle> handlesToShare = core.createMessagePipe();
+
+ try {
+ handles.first.writeMessage(null,
+ Collections.<Handle> singletonList(handlesToShare.second),
+ WriteFlags.none());
+ assertFalse(handlesToShare.second.isValid());
+ ReadMessageResult readMessageResult = handles.second.readMessage(null, 1,
+ ReadFlags.none());
+ assertEquals(1, readMessageResult.getHandlesCount());
+ MessagePipeHandle newHandle = readMessageResult.getHandles().get(0)
+ .toMessagePipeHandle();
+ try {
+ assertTrue(newHandle.isValid());
+ checkSendingMessage(handlesToShare.first, newHandle);
+ checkSendingMessage(newHandle, handlesToShare.first);
+ } finally {
+ newHandle.close();
+ }
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ handlesToShare.first.close();
+ handlesToShare.second.close();
+ }
+ }
+
+ private static void createAndCloseDataPipe(DataPipe.CreateOptions options) {
+ Core core = CoreSingleton.getInstance();
+ Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(
+ options);
+ handles.first.close();
+ handles.second.close();
+ }
+
+ /**
+ * Testing {@link DataPipe}.
+ */
+ @SmallTest
+ public void testDataPipeCreation() {
+ // Create datapipe with null options.
+ createAndCloseDataPipe(null);
+ DataPipe.CreateOptions options = new DataPipe.CreateOptions();
+ // Create datapipe with element size set.
+ options.setElementNumBytes(24);
+ createAndCloseDataPipe(options);
+ // Create datapipe with a flag set.
+ options.getFlags().setMayDiscard(true);
+ createAndCloseDataPipe(options);
+ // Create datapipe with capacity set.
+ options.setCapacityNumBytes(1024 * options.getElementNumBytes());
+ createAndCloseDataPipe(options);
+ }
+
+ /**
+ * Testing {@link DataPipe}.
+ */
+ @SmallTest
+ public void testDataPipeSend() {
+ Core core = CoreSingleton.getInstance();
+ Random random = new Random();
+
+ Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
+ try {
+ // Writing a random 8 bytes message.
+ byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+ ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
+ buffer.put(bytes);
+ int result = handles.first.writeData(buffer, DataPipe.WriteFlags.none());
+ assertEquals(bytes.length, result);
+
+ // Query number of bytes available.
+ result = handles.second.readData(null,
+ DataPipe.ReadFlags.none().query(true));
+ assertEquals(bytes.length, result);
+
+ // Read into a buffer.
+ ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length);
+ result = handles.second.readData(receiveBuffer,
+ DataPipe.ReadFlags.none());
+ assertEquals(bytes.length, result);
+ assertEquals(0, receiveBuffer.position());
+ assertEquals(bytes.length, receiveBuffer.limit());
+ byte[] receivedBytes = new byte[bytes.length];
+ receiveBuffer.get(receivedBytes);
+ assertTrue(Arrays.equals(bytes, receivedBytes));
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+ }
+
+ /**
+ * Testing {@link DataPipe}.
+ */
+ @SmallTest
+ public void testDataPipeTwoPhaseSend() {
+ Random random = new Random();
+ Core core = CoreSingleton.getInstance();
+ Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
+
+ try {
+ // Writing a random 8 bytes message.
+ byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+ ByteBuffer buffer = handles.first.beginWriteData(bytes.length,
+ DataPipe.WriteFlags.none());
+ assertTrue(buffer.capacity() >= bytes.length);
+ buffer.put(bytes);
+ handles.first.endWriteData(bytes.length);
+
+ // Read into a buffer.
+ ByteBuffer receiveBuffer = handles.second.beginReadData(bytes.length,
+ DataPipe.ReadFlags.none());
+ assertEquals(0, receiveBuffer.position());
+ assertEquals(bytes.length, receiveBuffer.limit());
+ byte[] receivedBytes = new byte[bytes.length];
+ receiveBuffer.get(receivedBytes);
+ assertTrue(Arrays.equals(bytes, receivedBytes));
+ handles.second.endReadData(bytes.length);
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+ }
+
+ /**
+ * Testing {@link DataPipe}.
+ */
+ @SmallTest
+ public void testDataPipeDiscard() {
+ Random random = new Random();
+ Core core = CoreSingleton.getInstance();
+ Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = core.createDataPipe(null);
+
+ try {
+ // Writing a random 8 bytes message.
+ byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+ ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
+ buffer.put(bytes);
+ int result = handles.first.writeData(buffer, DataPipe.WriteFlags.none());
+ assertEquals(bytes.length, result);
+
+ // Discard bytes.
+ final int nbBytesToDiscard = 4;
+ assertEquals(nbBytesToDiscard,
+ handles.second.discardData(nbBytesToDiscard, DataPipe.ReadFlags.none()));
+
+ // Read into a buffer.
+ ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(bytes.length - nbBytesToDiscard);
+ result = handles.second.readData(receiveBuffer,
+ DataPipe.ReadFlags.none());
+ assertEquals(bytes.length - nbBytesToDiscard, result);
+ assertEquals(0, receiveBuffer.position());
+ assertEquals(bytes.length - nbBytesToDiscard, receiveBuffer.limit());
+ byte[] receivedBytes = new byte[bytes.length - nbBytesToDiscard];
+ receiveBuffer.get(receivedBytes);
+ assertTrue(Arrays.equals(Arrays.copyOfRange(bytes, nbBytesToDiscard, bytes.length),
+ receivedBytes));
+ } finally {
+ handles.first.close();
+ handles.second.close();
+ }
+ }
+
+ /**
+ * Testing {@link SharedBufferHandle}.
+ */
+ @SmallTest
+ public void testSharedBufferCreation() {
+ Core core = CoreSingleton.getInstance();
+ // Test creation with empty options.
+ core.createSharedBuffer(null, 8).close();
+ // Test creation with default options.
+ core.createSharedBuffer(new SharedBufferHandle.CreateOptions(), 8);
+ }
+
+ /**
+ * Testing {@link SharedBufferHandle}.
+ */
+ @SmallTest
+ public void testSharedBufferDuplication() {
+ Core core = CoreSingleton.getInstance();
+ SharedBufferHandle handle = core.createSharedBuffer(null, 8);
+ try {
+ // Test duplication with empty options.
+ handle.duplicate(null).close();
+ // Test creation with default options.
+ handle.duplicate(new SharedBufferHandle.DuplicateOptions()).close();
+ } finally {
+ handle.close();
+ }
+ }
+
+ /**
+ * Testing {@link SharedBufferHandle}.
+ */
+ @SmallTest
+ public void testSharedBufferSending() {
+ Random random = new Random();
+ Core core = CoreSingleton.getInstance();
+ SharedBufferHandle handle = core.createSharedBuffer(null, 8);
+ SharedBufferHandle newHandle = handle.duplicate(null);
+
+ try {
+ ByteBuffer buffer1 = handle.map(0, 8, MapFlags.none());
+ assertEquals(8, buffer1.capacity());
+ ByteBuffer buffer2 = newHandle.map(0, 8, MapFlags.none());
+ assertEquals(8, buffer2.capacity());
+
+ byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+ buffer1.put(bytes);
+
+ byte[] receivedBytes = new byte[bytes.length];
+ buffer2.get(receivedBytes);
+
+ assertTrue(Arrays.equals(bytes, receivedBytes));
+
+ handle.unmap(buffer1);
+ newHandle.unmap(buffer2);
+ } finally {
+ handle.close();
+ newHandle.close();
+ }
+ }
+
+ private native void nativeInitApplicationContext(Context context);
+}
diff --git a/mojo/android/system/core_impl.cc b/mojo/android/system/core_impl.cc
new file mode 100644
index 0000000000..d7552c1a29
--- /dev/null
+++ b/mojo/android/system/core_impl.cc
@@ -0,0 +1,293 @@
+// 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/android/system/core_impl.h"
+
+#include "base/android/base_jni_registrar.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "base/android/library_loader/library_loader_hooks.h"
+#include "base/logging.h"
+#include "jni/CoreImpl_jni.h"
+#include "mojo/embedder/embedder.h"
+#include "mojo/public/c/system/core.h"
+
+namespace mojo {
+namespace android {
+
+static void Constructor(JNIEnv* env, jobject jcaller) {
+ mojo::embedder::Init();
+}
+
+static jlong GetTimeTicksNow(JNIEnv* env, jobject jcaller) {
+ return MojoGetTimeTicksNow();
+}
+
+static jint WaitMany(JNIEnv* env,
+ jobject jcaller,
+ jobject buffer,
+ jlong deadline) {
+ // Buffer contains first the list of handles, then the list of flags.
+ const void* buffer_start = env->GetDirectBufferAddress(buffer);
+ DCHECK(buffer_start);
+ const size_t record_size = 8;
+ const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
+ DCHECK_EQ(buffer_size % record_size, 0u);
+
+ const size_t nb_handles = buffer_size / record_size;
+ const MojoHandle* handle_start = static_cast<const MojoHandle*>(buffer_start);
+ const MojoWaitFlags* flags_start =
+ static_cast<const MojoWaitFlags*>(handle_start + nb_handles);
+ return MojoWaitMany(handle_start, flags_start, nb_handles, deadline);
+}
+
+static jobject CreateMessagePipe(JNIEnv* env, jobject jcaller) {
+ MojoHandle handle1;
+ MojoHandle handle2;
+ MojoResult result = MojoCreateMessagePipe(&handle1, &handle2);
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
+ .Release();
+}
+
+static jobject CreateDataPipe(JNIEnv* env,
+ jobject jcaller,
+ jobject options_buffer) {
+ const MojoCreateDataPipeOptions* options = NULL;
+ if (options_buffer) {
+ const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
+ DCHECK(buffer_start);
+ const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
+ DCHECK_EQ(buffer_size, sizeof(MojoCreateDataPipeOptions));
+ options = static_cast<const MojoCreateDataPipeOptions*>(buffer_start);
+ DCHECK_EQ(options->struct_size, buffer_size);
+ }
+ MojoHandle handle1;
+ MojoHandle handle2;
+ MojoResult result = MojoCreateDataPipe(options, &handle1, &handle2);
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle1, handle2)
+ .Release();
+}
+
+static jobject CreateSharedBuffer(JNIEnv* env,
+ jobject jcaller,
+ jobject options_buffer,
+ jlong num_bytes) {
+ const MojoCreateSharedBufferOptions* options = 0;
+ if (options_buffer) {
+ const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
+ DCHECK(buffer_start);
+ const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
+ DCHECK_EQ(buffer_size, sizeof(MojoCreateSharedBufferOptions));
+ options = static_cast<const MojoCreateSharedBufferOptions*>(buffer_start);
+ DCHECK_EQ(options->struct_size, buffer_size);
+ }
+ MojoHandle handle;
+ MojoResult result = MojoCreateSharedBuffer(options, num_bytes, &handle);
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
+ .Release();
+}
+
+static jint Close(JNIEnv* env, jobject jcaller, jint mojo_handle) {
+ return MojoClose(mojo_handle);
+}
+
+static jint Wait(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jint flags,
+ jlong deadline) {
+ return MojoWait(mojo_handle, flags, deadline);
+}
+
+static jint WriteMessage(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jobject bytes,
+ jint num_bytes,
+ jobject handles_buffer,
+ jint flags) {
+ const void* buffer_start = 0;
+ uint32_t buffer_size = 0;
+ if (bytes) {
+ buffer_start = env->GetDirectBufferAddress(bytes);
+ DCHECK(buffer_start);
+ DCHECK(env->GetDirectBufferCapacity(bytes) >= num_bytes);
+ buffer_size = num_bytes;
+ }
+ const MojoHandle* handles = 0;
+ uint32_t num_handles = 0;
+ if (handles_buffer) {
+ handles =
+ static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
+ num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
+ }
+ // Java code will handle invalidating handles if the write succeeded.
+ return MojoWriteMessage(
+ mojo_handle, buffer_start, buffer_size, handles, num_handles, flags);
+}
+
+static jobject ReadMessage(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jobject bytes,
+ jobject handles_buffer,
+ jint flags) {
+ void* buffer_start = 0;
+ uint32_t buffer_size = 0;
+ if (bytes) {
+ buffer_start = env->GetDirectBufferAddress(bytes);
+ DCHECK(buffer_start);
+ buffer_size = env->GetDirectBufferCapacity(bytes);
+ }
+ MojoHandle* handles = 0;
+ uint32_t num_handles = 0;
+ if (handles_buffer) {
+ handles =
+ static_cast<MojoHandle*>(env->GetDirectBufferAddress(handles_buffer));
+ num_handles = env->GetDirectBufferCapacity(handles_buffer) / 4;
+ }
+ MojoResult result = MojoReadMessage(
+ mojo_handle, buffer_start, &buffer_size, handles, &num_handles, flags);
+ // Jave code will handle taking ownership of any received handle.
+ return Java_CoreImpl_newNativeReadMessageResult(
+ env, result, buffer_size, num_handles).Release();
+}
+
+static jint ReadData(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jobject elements,
+ jint elements_capacity,
+ jint flags) {
+ void* buffer_start = 0;
+ uint32_t buffer_size = elements_capacity;
+ if (elements) {
+ buffer_start = env->GetDirectBufferAddress(elements);
+ DCHECK(buffer_start);
+ DCHECK(elements_capacity <= env->GetDirectBufferCapacity(elements));
+ }
+ MojoResult result =
+ MojoReadData(mojo_handle, buffer_start, &buffer_size, flags);
+ if (result < 0) {
+ return result;
+ }
+ return buffer_size;
+}
+
+static jobject BeginReadData(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jint num_bytes,
+ jint flags) {
+ void const* buffer = 0;
+ uint32_t buffer_size = num_bytes;
+ MojoResult result =
+ MojoBeginReadData(mojo_handle, &buffer, &buffer_size, flags);
+ jobject byte_buffer = 0;
+ if (result == MOJO_RESULT_OK) {
+ byte_buffer =
+ env->NewDirectByteBuffer(const_cast<void*>(buffer), buffer_size);
+ }
+ return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
+ .Release();
+}
+
+static jint EndReadData(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jint num_bytes_read) {
+ return MojoEndReadData(mojo_handle, num_bytes_read);
+}
+
+static jint WriteData(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jobject elements,
+ jint limit,
+ jint flags) {
+ void* buffer_start = env->GetDirectBufferAddress(elements);
+ DCHECK(buffer_start);
+ DCHECK(limit <= env->GetDirectBufferCapacity(elements));
+ uint32_t buffer_size = limit;
+ MojoResult result =
+ MojoWriteData(mojo_handle, buffer_start, &buffer_size, flags);
+ if (result < 0) {
+ return result;
+ }
+ return buffer_size;
+}
+
+static jobject BeginWriteData(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jint num_bytes,
+ jint flags) {
+ void* buffer = 0;
+ uint32_t buffer_size = num_bytes;
+ MojoResult result =
+ MojoBeginWriteData(mojo_handle, &buffer, &buffer_size, flags);
+ jobject byte_buffer = 0;
+ if (result == MOJO_RESULT_OK) {
+ byte_buffer = env->NewDirectByteBuffer(buffer, buffer_size);
+ }
+ return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
+ .Release();
+}
+
+static jint EndWriteData(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jint num_bytes_written) {
+ return MojoEndWriteData(mojo_handle, num_bytes_written);
+}
+
+static jobject Duplicate(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jobject options_buffer) {
+ const MojoDuplicateBufferHandleOptions* options = 0;
+ if (options_buffer) {
+ const void* buffer_start = env->GetDirectBufferAddress(options_buffer);
+ DCHECK(buffer_start);
+ const size_t buffer_size = env->GetDirectBufferCapacity(options_buffer);
+ DCHECK_EQ(buffer_size, sizeof(MojoDuplicateBufferHandleOptions));
+ options =
+ static_cast<const MojoDuplicateBufferHandleOptions*>(buffer_start);
+ DCHECK_EQ(options->struct_size, buffer_size);
+ }
+ MojoHandle handle;
+ MojoResult result = MojoDuplicateBufferHandle(mojo_handle, options, &handle);
+ return Java_CoreImpl_newNativeCreationResult(env, result, handle, 0)
+ .Release();
+}
+
+static jobject Map(JNIEnv* env,
+ jobject jcaller,
+ jint mojo_handle,
+ jlong offset,
+ jlong num_bytes,
+ jint flags) {
+ void* buffer = 0;
+ MojoResult result =
+ MojoMapBuffer(mojo_handle, offset, num_bytes, &buffer, flags);
+ jobject byte_buffer = 0;
+ if (result == MOJO_RESULT_OK) {
+ byte_buffer = env->NewDirectByteBuffer(buffer, num_bytes);
+ }
+ return Java_CoreImpl_newNativeCodeAndBufferResult(env, result, byte_buffer)
+ .Release();
+}
+
+static int Unmap(JNIEnv* env, jobject jcaller, jobject buffer) {
+ void* buffer_start = env->GetDirectBufferAddress(buffer);
+ DCHECK(buffer_start);
+ return MojoUnmapBuffer(buffer_start);
+}
+
+bool RegisterCoreImpl(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace mojo
diff --git a/mojo/android/system/core_impl.h b/mojo/android/system/core_impl.h
new file mode 100644
index 0000000000..c6249994e5
--- /dev/null
+++ b/mojo/android/system/core_impl.h
@@ -0,0 +1,20 @@
+// 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_ANDROID_SYSTEM_CORE_IMPL_H_
+#define MOJO_ANDROID_SYSTEM_CORE_IMPL_H_
+
+#include <jni.h>
+
+#include "base/android/jni_android.h"
+
+namespace mojo {
+namespace android {
+
+JNI_EXPORT bool RegisterCoreImpl(JNIEnv* env);
+
+} // namespace android
+} // namespace mojo
+
+#endif // MOJO_ANDROID_SYSTEM_CORE_IMPL_H_
diff --git a/mojo/android/system/src/org/chromium/mojo/system/CoreImpl.java b/mojo/android/system/src/org/chromium/mojo/system/CoreImpl.java
new file mode 100644
index 0000000000..1d8e56bcf0
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/CoreImpl.java
@@ -0,0 +1,584 @@
+// 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.system;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.mojo.system.DataPipe.ConsumerHandle;
+import org.chromium.mojo.system.DataPipe.ProducerHandle;
+import org.chromium.mojo.system.SharedBufferHandle.DuplicateOptions;
+import org.chromium.mojo.system.SharedBufferHandle.MapFlags;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of {@link Core}.
+ */
+@JNINamespace("mojo::android")
+class CoreImpl implements Core {
+
+ /**
+ * Discard flag for the |MojoReadData| operation.
+ */
+ private static final int MOJO_READ_DATA_FLAG_DISCARD = 1 << 1;
+
+ /**
+ * the size of a handle, in bytes.
+ */
+ private static final int HANDLE_SIZE = 4;
+
+ /**
+ * the size of a flag, in bytes.
+ */
+ private static final int FLAG_SIZE = 4;
+
+ /**
+ * The singleton instance.
+ */
+ private static Core sINSTANCE = null;
+
+ /**
+ * @return the instance.
+ */
+ static synchronized Core getInstance() {
+ if (sINSTANCE == null) {
+ sINSTANCE = new CoreImpl();
+ }
+ return sINSTANCE;
+ }
+
+ private CoreImpl() {
+ nativeConstructor();
+ }
+
+ /**
+ * @see Core#getTimeTicksNow()
+ */
+ @Override
+ public long getTimeTicksNow() {
+ return nativeGetTimeTicksNow();
+ }
+
+ /**
+ * @see Core#waitMany(List, long)
+ */
+ @Override
+ public WaitManyResult waitMany(List<Pair<Handle, WaitFlags>> handles, long deadline) {
+ // Allocate a direct buffer to allow native code not to reach back to java. Buffer will
+ // contain all mojo handles, followed by all flags values.
+ ByteBuffer buffer = allocateDirectBuffer(handles.size() * 8);
+ int index = 0;
+ for (Pair<Handle, WaitFlags> handle : handles) {
+ HandleImpl realHandler = (HandleImpl) handle.first;
+ buffer.putInt(HANDLE_SIZE * index, realHandler.getMojoHandle());
+ buffer.putInt(HANDLE_SIZE * handles.size() + FLAG_SIZE * index,
+ handle.second.getFlags());
+ index++;
+ }
+ int code = nativeWaitMany(buffer, deadline);
+ WaitManyResult result = new WaitManyResult();
+ // If result is greater than 0, result is the indexed of the available handle. To make sure
+ // it cannot be misinterpreted, set handleIndex to a negative number in case of error.
+ result.setHandleIndex(code);
+ result.setMojoResult(filterMojoResultForWait(code));
+ return result;
+ }
+
+ /**
+ * @see Core#wait(Handle, WaitFlags, long)
+ */
+ @Override
+ public int wait(Handle handle, WaitFlags flags, long deadline) {
+ return filterMojoResultForWait(nativeWait(((HandleImpl) handle).getMojoHandle(),
+ flags.getFlags(), deadline));
+ }
+
+ /**
+ * @see Core#createMessagePipe()
+ */
+ @Override
+ public Pair<MessagePipeHandle, MessagePipeHandle> createMessagePipe() {
+ NativeCreationResult result = nativeCreateMessagePipe();
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ return Pair.create(
+ new MessagePipeHandleImpl(this, result.getMojoHandle1()),
+ new MessagePipeHandleImpl(this, result.getMojoHandle2()));
+ }
+
+ /**
+ * @see Core#createDataPipe(DataPipe.CreateOptions)
+ */
+ @Override
+ public Pair<ProducerHandle, ConsumerHandle> createDataPipe(DataPipe.CreateOptions options) {
+ ByteBuffer optionsBuffer = null;
+ if (options != null) {
+ optionsBuffer = allocateDirectBuffer(16);
+ optionsBuffer.putInt(0, 16);
+ optionsBuffer.putInt(4, options.getFlags().getFlags());
+ optionsBuffer.putInt(8, options.getElementNumBytes());
+ optionsBuffer.putInt(12, options.getCapacityNumBytes());
+ }
+ NativeCreationResult result = nativeCreateDataPipe(optionsBuffer);
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ return Pair.create(
+ new DataPipeProducerHandleImpl(this, result.getMojoHandle1()),
+ new DataPipeConsumerHandleImpl(this, result.getMojoHandle2()));
+ }
+
+ /**
+ * @see Core#createSharedBuffer(SharedBufferHandle.CreateOptions, long)
+ */
+ @Override
+ public SharedBufferHandle createSharedBuffer(
+ SharedBufferHandle.CreateOptions options, long numBytes) {
+ ByteBuffer optionsBuffer = null;
+ if (options != null) {
+ optionsBuffer = allocateDirectBuffer(8);
+ optionsBuffer.putInt(0, 8);
+ optionsBuffer.putInt(4, options.getFlags().getFlags());
+ }
+ NativeCreationResult result = nativeCreateSharedBuffer(optionsBuffer, numBytes);
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ assert result.getMojoHandle2() == 0;
+ return new SharedBufferHandleImpl(this, result.getMojoHandle1());
+ }
+
+ int closeWithResult(int mojoHandle) {
+ return nativeClose(mojoHandle);
+ }
+
+ void close(int mojoHandle) {
+ int mojoResult = nativeClose(mojoHandle);
+ if (mojoResult != MojoResult.OK) {
+ throw new MojoException(mojoResult);
+ }
+ }
+
+ /**
+ * @see MessagePipeHandle#writeMessage(ByteBuffer, List, MessagePipeHandle.WriteFlags)
+ */
+ void writeMessage(MessagePipeHandleImpl pipeHandle, ByteBuffer bytes,
+ List<Handle> handles, MessagePipeHandle.WriteFlags flags) {
+ ByteBuffer handlesBuffer = null;
+ if (handles != null && !handles.isEmpty()) {
+ handlesBuffer = allocateDirectBuffer(handles.size() * HANDLE_SIZE);
+ for (Handle handle : handles) {
+ HandleImpl realHandle = (HandleImpl) handle;
+ handlesBuffer.putInt(realHandle.getMojoHandle());
+ }
+ handlesBuffer.position(0);
+ }
+ int mojoResult = nativeWriteMessage(pipeHandle.getMojoHandle(), bytes,
+ bytes == null ? 0 : bytes.limit(), handlesBuffer,
+ flags.getFlags());
+ if (mojoResult != MojoResult.OK) {
+ throw new MojoException(mojoResult);
+ }
+ // Success means the handles have been invalidated.
+ if (handles != null) {
+ for (Handle handle : handles) {
+ ((HandleImpl) handle).invalidateHandle();
+ }
+ }
+ }
+
+ /**
+ * @see MessagePipeHandle#readMessage(ByteBuffer, int, MessagePipeHandle.ReadFlags)
+ */
+ MessagePipeHandle.ReadMessageResult readMessage(MessagePipeHandleImpl handle,
+ ByteBuffer bytes, int maxNumberOfHandles,
+ MessagePipeHandle.ReadFlags flags) {
+ ByteBuffer handlesBuffer = null;
+ if (maxNumberOfHandles > 0) {
+ handlesBuffer = allocateDirectBuffer(maxNumberOfHandles * HANDLE_SIZE);
+ }
+ NativeReadMessageResult result = nativeReadMessage(
+ handle.getMojoHandle(), bytes, handlesBuffer, flags.getFlags());
+ if (result.getMojoResult() != MojoResult.OK &&
+ result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED) {
+ throw new MojoException(result.getMojoResult());
+ }
+
+ if (result.getMojoResult() == MojoResult.OK) {
+ if (bytes != null) {
+ bytes.position(0);
+ bytes.limit(result.getReadMessageResult().getMessageSize());
+ }
+
+ List<UntypedHandle> handles = new ArrayList<UntypedHandle>(
+ result.getReadMessageResult().getHandlesCount());
+ for (int i = 0; i < result.getReadMessageResult().getHandlesCount(); ++i) {
+ int mojoHandle = handlesBuffer.getInt(HANDLE_SIZE * i);
+ handles.add(new UntypedHandleImpl(this, mojoHandle));
+ }
+ result.getReadMessageResult().setHandles(handles);
+ }
+ return result.getReadMessageResult();
+ }
+
+ /**
+ * @see DataPipe.ConsumerHandle#discardData(int, DataPipe.ReadFlags)
+ */
+ int discardData(DataPipeConsumerHandleImpl handle, int numBytes,
+ DataPipe.ReadFlags flags) {
+ int result = nativeReadData(handle.getMojoHandle(), null, numBytes,
+ flags.getFlags() | MOJO_READ_DATA_FLAG_DISCARD);
+ if (result < 0) {
+ throw new MojoException(result);
+ }
+ return result;
+ }
+
+ /**
+ * @see DataPipe.ConsumerHandle#readData(ByteBuffer, DataPipe.ReadFlags)
+ */
+ int readData(DataPipeConsumerHandleImpl handle, ByteBuffer elements,
+ DataPipe.ReadFlags flags) {
+ int result = nativeReadData(handle.getMojoHandle(), elements,
+ elements == null ? 0 : elements.capacity(),
+ flags.getFlags());
+ if (result < 0) {
+ throw new MojoException(result);
+ }
+ if (elements != null) {
+ elements.limit(result);
+ }
+ return result;
+ }
+
+ /**
+ * @see DataPipe.ConsumerHandle#beginReadData(int, DataPipe.ReadFlags)
+ */
+ ByteBuffer beginReadData(DataPipeConsumerHandleImpl handle,
+ int numBytes, DataPipe.ReadFlags flags) {
+ NativeCodeAndBufferResult result = nativeBeginReadData(
+ handle.getMojoHandle(),
+ numBytes,
+ flags.getFlags());
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ return result.getBuffer().asReadOnlyBuffer();
+ }
+
+ /**
+ * @see DataPipe.ConsumerHandle#endReadData(int)
+ */
+ void endReadData(DataPipeConsumerHandleImpl handle,
+ int numBytesRead) {
+ int result = nativeEndReadData(handle.getMojoHandle(), numBytesRead);
+ if (result != MojoResult.OK) {
+ throw new MojoException(result);
+ }
+ }
+
+ /**
+ * @see DataPipe.ProducerHandle#writeData(ByteBuffer, DataPipe.WriteFlags)
+ */
+ int writeData(DataPipeProducerHandleImpl handle, ByteBuffer elements,
+ DataPipe.WriteFlags flags) {
+ return nativeWriteData(handle.getMojoHandle(), elements, elements.limit(),
+ flags.getFlags());
+ }
+
+ /**
+ * @see DataPipe.ProducerHandle#beginWriteData(int, DataPipe.WriteFlags)
+ */
+ ByteBuffer beginWriteData(DataPipeProducerHandleImpl handle,
+ int numBytes, DataPipe.WriteFlags flags) {
+ NativeCodeAndBufferResult result = nativeBeginWriteData(
+ handle.getMojoHandle(),
+ numBytes,
+ flags.getFlags());
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ return result.getBuffer();
+ }
+
+ /**
+ * @see DataPipe.ProducerHandle#endWriteData(int)
+ */
+ void endWriteData(DataPipeProducerHandleImpl handle,
+ int numBytesWritten) {
+ int result = nativeEndWriteData(handle.getMojoHandle(), numBytesWritten);
+ if (result != MojoResult.OK) {
+ throw new MojoException(result);
+ }
+ }
+
+ /**
+ * @see SharedBufferHandle#duplicate(DuplicateOptions)
+ */
+ SharedBufferHandle duplicate(SharedBufferHandleImpl handle,
+ DuplicateOptions options) {
+ ByteBuffer optionsBuffer = null;
+ if (options != null) {
+ optionsBuffer = allocateDirectBuffer(8);
+ optionsBuffer.putInt(0, 8);
+ optionsBuffer.putInt(4, options.getFlags().getFlags());
+ }
+ NativeCreationResult result = nativeDuplicate(handle.getMojoHandle(),
+ optionsBuffer);
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ assert result.getMojoHandle2() == 0;
+ return new SharedBufferHandleImpl(this, result.getMojoHandle1());
+ }
+
+ /**
+ * @see SharedBufferHandle#map(long, long, MapFlags)
+ */
+ ByteBuffer map(SharedBufferHandleImpl handle, long offset, long numBytes,
+ MapFlags flags) {
+ NativeCodeAndBufferResult result = nativeMap(handle.getMojoHandle(), offset, numBytes,
+ flags.getFlags());
+ if (result.getMojoResult() != MojoResult.OK) {
+ throw new MojoException(result.getMojoResult());
+ }
+ return result.getBuffer();
+ }
+
+ /**
+ * @see SharedBufferHandle#unmap(ByteBuffer)
+ */
+ void unmap(ByteBuffer buffer) {
+ int result = nativeUnmap(buffer);
+ if (result != MojoResult.OK) {
+ throw new MojoException(result);
+ }
+ }
+
+ private static int filterMojoResultForWait(int code) {
+ if (code >= 0) {
+ return MojoResult.OK;
+ }
+ switch (code) {
+ case MojoResult.DEADLINE_EXCEEDED:
+ case MojoResult.CANCELLED:
+ case MojoResult.FAILED_PRECONDITION:
+ return code;
+ default:
+ throw new MojoException(code);
+ }
+
+ }
+
+ private static ByteBuffer allocateDirectBuffer(int capacity) {
+ ByteBuffer buffer = ByteBuffer.allocateDirect(capacity);
+ buffer.order(ByteOrder.nativeOrder());
+ return buffer;
+ }
+
+ private static class NativeCodeAndBufferResult {
+ private int mMojoResult;
+ private ByteBuffer mBuffer;
+
+ /**
+ * @return the mojoResult
+ */
+ public int getMojoResult() {
+ return mMojoResult;
+ }
+
+ /**
+ * @param mojoResult the mojoResult to set
+ */
+ public void setMojoResult(int mojoResult) {
+ mMojoResult = mojoResult;
+ }
+
+ /**
+ * @return the buffer
+ */
+ public ByteBuffer getBuffer() {
+ return mBuffer;
+ }
+
+ /**
+ * @param buffer the buffer to set
+ */
+ public void setBuffer(ByteBuffer buffer) {
+ mBuffer = buffer;
+ }
+
+ }
+
+ @CalledByNative
+ private static NativeCodeAndBufferResult newNativeCodeAndBufferResult(int mojoResult,
+ ByteBuffer buffer) {
+ NativeCodeAndBufferResult result = new NativeCodeAndBufferResult();
+ result.setMojoResult(mojoResult);
+ result.setBuffer(buffer);
+ return result;
+ }
+
+ private static class NativeReadMessageResult {
+ public int mMojoResult;
+ public MessagePipeHandle.ReadMessageResult mReadMessageResult;
+
+ /**
+ * @return the mojoResult
+ */
+ public int getMojoResult() {
+ return mMojoResult;
+ }
+
+ /**
+ * @param mojoResult the mojoResult to set
+ */
+ public void setMojoResult(int mojoResult) {
+ this.mMojoResult = mojoResult;
+ }
+
+ /**
+ * @return the readMessageResult
+ */
+ public MessagePipeHandle.ReadMessageResult getReadMessageResult() {
+ return mReadMessageResult;
+ }
+
+ /**
+ * @param readMessageResult the readMessageResult to set
+ */
+ public void setReadMessageResult(MessagePipeHandle.ReadMessageResult readMessageResult) {
+ this.mReadMessageResult = readMessageResult;
+ }
+ }
+
+ @CalledByNative
+ private static NativeReadMessageResult newNativeReadMessageResult(int mojoResult,
+ int messageSize,
+ int handlesCount) {
+ NativeReadMessageResult result = new NativeReadMessageResult();
+ if (mojoResult >= 0) {
+ result.setMojoResult(MojoResult.OK);
+ } else {
+ result.setMojoResult(mojoResult);
+ }
+ MessagePipeHandle.ReadMessageResult readMessageResult =
+ new MessagePipeHandle.ReadMessageResult();
+ readMessageResult.setWasMessageRead(result.getMojoResult() == MojoResult.OK);
+ readMessageResult.setMessageSize(messageSize);
+ readMessageResult.setHandlesCount(handlesCount);
+ result.setReadMessageResult(readMessageResult);
+ return result;
+ }
+
+ private static class NativeCreationResult {
+ private int mMojoResult;
+ private int mMojoHandle1;
+ private int mMojoHandle2;
+
+ /**
+ * @return the mojoResult
+ */
+ public int getMojoResult() {
+ return mMojoResult;
+ }
+
+ /**
+ * @param mojoResult the mojoResult to set
+ */
+ public void setMojoResult(int mojoResult) {
+ mMojoResult = mojoResult;
+ }
+
+ /**
+ * @return the mojoHandle1
+ */
+ public int getMojoHandle1() {
+ return mMojoHandle1;
+ }
+
+ /**
+ * @param mojoHandle1 the mojoHandle1 to set
+ */
+ public void setMojoHandle1(int mojoHandle1) {
+ mMojoHandle1 = mojoHandle1;
+ }
+
+ /**
+ * @return the mojoHandle2
+ */
+ public int getMojoHandle2() {
+ return mMojoHandle2;
+ }
+
+ /**
+ * @param mojoHandle2 the mojoHandle2 to set
+ */
+ public void setMojoHandle2(int mojoHandle2) {
+ mMojoHandle2 = mojoHandle2;
+ }
+ }
+
+ @CalledByNative
+ private static NativeCreationResult newNativeCreationResult(int mojoResult,
+ int mojoHandle1, int mojoHandle2) {
+ NativeCreationResult result = new NativeCreationResult();
+ result.setMojoResult(mojoResult);
+ result.setMojoHandle1(mojoHandle1);
+ result.setMojoHandle2(mojoHandle2);
+ return result;
+ }
+
+ private native void nativeConstructor();
+
+ private native long nativeGetTimeTicksNow();
+
+ private native int nativeWaitMany(ByteBuffer buffer, long deadline);
+
+ private native NativeCreationResult nativeCreateMessagePipe();
+
+ private native NativeCreationResult nativeCreateDataPipe(ByteBuffer optionsBuffer);
+
+ private native NativeCreationResult nativeCreateSharedBuffer(ByteBuffer optionsBuffer,
+ long numBytes);
+
+ private native int nativeClose(int mojoHandle);
+
+ private native int nativeWait(int mojoHandle, int flags, long deadline);
+
+ private native int nativeWriteMessage(int mojoHandle, ByteBuffer bytes, int numBytes,
+ ByteBuffer handlesBuffer, int flags);
+
+ private native NativeReadMessageResult nativeReadMessage(int mojoHandle, ByteBuffer bytes,
+ ByteBuffer handlesBuffer,
+ int flags);
+
+ private native int nativeReadData(int mojoHandle, ByteBuffer elements, int elementsSize,
+ int flags);
+
+ private native NativeCodeAndBufferResult nativeBeginReadData(int mojoHandle, int numBytes,
+ int flags);
+
+ private native int nativeEndReadData(int mojoHandle, int numBytesRead);
+
+ private native int nativeWriteData(int mojoHandle, ByteBuffer elements, int limit, int flags);
+
+ private native NativeCodeAndBufferResult nativeBeginWriteData(int mojoHandle, int numBytes,
+ int flags);
+
+ private native int nativeEndWriteData(int mojoHandle, int numBytesWritten);
+
+ private native NativeCreationResult nativeDuplicate(int mojoHandle, ByteBuffer optionsBuffer);
+
+ private native NativeCodeAndBufferResult nativeMap(int mojoHandle, long offset, long numBytes,
+ int flags);
+
+ private native int nativeUnmap(ByteBuffer buffer);
+
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/CoreSingleton.java b/mojo/android/system/src/org/chromium/mojo/system/CoreSingleton.java
new file mode 100644
index 0000000000..3cdbf969af
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/CoreSingleton.java
@@ -0,0 +1,18 @@
+// 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.system;
+
+/**
+ * Access to the core singleton.
+ */
+public class CoreSingleton {
+
+ /**
+ * Access to the {@link Core} singleton.
+ */
+ public static Core getInstance() {
+ return CoreImpl.getInstance();
+ }
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/DataPipeConsumerHandleImpl.java b/mojo/android/system/src/org/chromium/mojo/system/DataPipeConsumerHandleImpl.java
new file mode 100644
index 0000000000..84985bfe82
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/DataPipeConsumerHandleImpl.java
@@ -0,0 +1,63 @@
+// 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.system;
+
+import org.chromium.mojo.system.DataPipe.ConsumerHandle;
+import org.chromium.mojo.system.DataPipe.ReadFlags;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Implementation of {@link ConsumerHandle}.
+ */
+class DataPipeConsumerHandleImpl extends HandleImpl implements ConsumerHandle {
+
+ /**
+ * @see HandleImpl#HandleImpl(CoreImpl, int)
+ */
+ DataPipeConsumerHandleImpl(CoreImpl core, int mojoHandle) {
+ super(core, mojoHandle);
+ }
+
+ /**
+ * @see HandleImpl#HandleImpl(UntypedHandleImpl)
+ */
+ DataPipeConsumerHandleImpl(UntypedHandleImpl other) {
+ super(other);
+ }
+
+ /**
+ * @see ConsumerHandle#discardData(int, ReadFlags)
+ */
+ @Override
+ public int discardData(int numBytes, ReadFlags flags) {
+ return mCore.discardData(this, numBytes, flags);
+ }
+
+ /**
+ * @see ConsumerHandle#readData(ByteBuffer, ReadFlags)
+ */
+ @Override
+ public int readData(ByteBuffer elements, ReadFlags flags) {
+ return mCore.readData(this, elements, flags);
+ }
+
+ /**
+ * @see ConsumerHandle#beginReadData(int, ReadFlags)
+ */
+ @Override
+ public ByteBuffer beginReadData(int numBytes, ReadFlags flags) {
+ return mCore.beginReadData(this, numBytes, flags);
+ }
+
+ /**
+ * @see ConsumerHandle#endReadData(int)
+ */
+ @Override
+ public void endReadData(int numBytesRead) {
+ mCore.endReadData(this, numBytesRead);
+ }
+
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/DataPipeProducerHandleImpl.java b/mojo/android/system/src/org/chromium/mojo/system/DataPipeProducerHandleImpl.java
new file mode 100644
index 0000000000..d6e00dfed5
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/DataPipeProducerHandleImpl.java
@@ -0,0 +1,55 @@
+// 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.system;
+
+import org.chromium.mojo.system.DataPipe.ProducerHandle;
+import org.chromium.mojo.system.DataPipe.WriteFlags;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Implementation of {@link ProducerHandle}.
+ */
+class DataPipeProducerHandleImpl extends HandleImpl implements ProducerHandle {
+
+ /**
+ * @see HandleImpl#HandleImpl(CoreImpl, int)
+ */
+ DataPipeProducerHandleImpl(CoreImpl core, int mojoHandle) {
+ super(core, mojoHandle);
+ }
+
+ /**
+ * @see HandleImpl#HandleImpl(UntypedHandleImpl)
+ */
+ DataPipeProducerHandleImpl(UntypedHandleImpl handle) {
+ super(handle);
+ }
+
+ /**
+ * @see DataPipe.ProducerHandle#writeData(ByteBuffer, WriteFlags)
+ */
+ @Override
+ public int writeData(ByteBuffer elements, WriteFlags flags) {
+ return mCore.writeData(this, elements, flags);
+ }
+
+ /**
+ * @see DataPipe.ProducerHandle#beginWriteData(int, WriteFlags)
+ */
+ @Override
+ public ByteBuffer beginWriteData(int numBytes, WriteFlags flags) {
+ return mCore.beginWriteData(this, numBytes, flags);
+ }
+
+ /**
+ * @see DataPipe.ProducerHandle#endWriteData(int)
+ */
+ @Override
+ public void endWriteData(int numBytesWritten) {
+ mCore.endWriteData(this, numBytesWritten);
+ }
+
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/HandleImpl.java b/mojo/android/system/src/org/chromium/mojo/system/HandleImpl.java
new file mode 100644
index 0000000000..00cb9cd267
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/HandleImpl.java
@@ -0,0 +1,112 @@
+// 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.system;
+
+import android.util.Log;
+
+import org.chromium.mojo.system.Core.WaitFlags;
+
+/**
+ * Implementation of {@link Handle}.
+ */
+class HandleImpl implements Handle {
+
+ private static final String TAG = "HandleImpl";
+
+ private static final int INVALID_HANDLE = 0;
+
+ /**
+ * The pointer to the scoped handle owned by this object.
+ */
+ private int mMojoHandle;
+
+ /**
+ * the core implementation. Will be used to delegate all behavior.
+ */
+ protected CoreImpl mCore;
+
+ /**
+ * Base constructor. Takes ownership of the passed handle.
+ */
+ HandleImpl(CoreImpl core, int mojoHandle) {
+ mCore = core;
+ mMojoHandle = mojoHandle;
+ }
+
+ /**
+ * Constructor for transforming an {@link UntypedHandle} into a specific one.
+ */
+ HandleImpl(UntypedHandleImpl other) {
+ mCore = other.mCore;
+ HandleImpl otherAsHandleImpl = other;
+ int mojoHandle = otherAsHandleImpl.mMojoHandle;
+ otherAsHandleImpl.mMojoHandle = INVALID_HANDLE;
+ mMojoHandle = mojoHandle;
+ }
+
+ /**
+ * @see org.chromium.mojo.system.Handle#close()
+ */
+ @Override
+ public void close() {
+ if (mMojoHandle != INVALID_HANDLE) {
+ // After a close, the handle is invalid whether the close succeed or not.
+ int handle = mMojoHandle;
+ mMojoHandle = INVALID_HANDLE;
+ mCore.close(handle);
+ }
+ }
+
+ /**
+ * @see org.chromium.mojo.system.Handle#wait(WaitFlags, long)
+ */
+ @Override
+ public int wait(WaitFlags flags, long deadline) {
+ return mCore.wait(this, flags, deadline);
+ }
+
+ /**
+ * @see org.chromium.mojo.system.Handle#isValid()
+ */
+ @Override
+ public boolean isValid() {
+ return mMojoHandle != INVALID_HANDLE;
+ }
+
+ /**
+ * Getter for the native scoped handle.
+ *
+ * @return the native scoped handle.
+ */
+ int getMojoHandle() {
+ return mMojoHandle;
+ }
+
+ /**
+ * invalidate the handle. The caller must ensures that the handle does not leak.
+ */
+ void invalidateHandle() {
+ mMojoHandle = INVALID_HANDLE;
+ }
+
+ /**
+ * Close the handle if it is valid. Necessary because we cannot let handle leak, and we cannot
+ * ensure that every handle will be manually closed.
+ *
+ * @see java.lang.Object#finalize()
+ */
+ @Override
+ protected final void finalize() throws Throwable {
+ if (isValid()) {
+ // This should not happen, as the user of this class should close the handle. Adding a
+ // warning.
+ Log.w(TAG, "Handle was not closed.");
+ // Ignore result at this point.
+ mCore.closeWithResult(mMojoHandle);
+ }
+ super.finalize();
+ }
+
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/MessagePipeHandleImpl.java b/mojo/android/system/src/org/chromium/mojo/system/MessagePipeHandleImpl.java
new file mode 100644
index 0000000000..6441b1cf42
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/MessagePipeHandleImpl.java
@@ -0,0 +1,47 @@
+// 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.system;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * Implementation of {@link MessagePipeHandle}.
+ */
+class MessagePipeHandleImpl extends HandleImpl implements MessagePipeHandle {
+
+ /**
+ * @see HandleImpl#HandleImpl(CoreImpl, int)
+ */
+ MessagePipeHandleImpl(CoreImpl core, int mojoHandle) {
+ super(core, mojoHandle);
+ }
+
+ /**
+ * @see HandleImpl#HandleImpl(UntypedHandleImpl)
+ */
+ MessagePipeHandleImpl(UntypedHandleImpl handle) {
+ super(handle);
+ }
+
+ /**
+ * @see MessagePipeHandle#writeMessage(ByteBuffer, List, WriteFlags)
+ */
+ @Override
+ public void writeMessage(ByteBuffer bytes, List<Handle> handles, WriteFlags flags) {
+ mCore.writeMessage(this, bytes, handles, flags);
+ }
+
+ /**
+ * @see MessagePipeHandle#readMessage(ByteBuffer, int, ReadFlags)
+ */
+ @Override
+ public ReadMessageResult readMessage(ByteBuffer bytes,
+ int maxNumberOfHandles,
+ ReadFlags flags) {
+ return mCore.readMessage(this, bytes, maxNumberOfHandles, flags);
+ }
+
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/SharedBufferHandleImpl.java b/mojo/android/system/src/org/chromium/mojo/system/SharedBufferHandleImpl.java
new file mode 100644
index 0000000000..4679bd097f
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/SharedBufferHandleImpl.java
@@ -0,0 +1,52 @@
+// 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.system;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Implementation of {@link SharedBufferHandle}.
+ */
+class SharedBufferHandleImpl extends HandleImpl implements SharedBufferHandle {
+
+ /**
+ * @see HandleImpl#HandleImpl(CoreImpl, int)
+ */
+ SharedBufferHandleImpl(CoreImpl core, int mojoHandle) {
+ super(core, mojoHandle);
+ }
+
+ /**
+ * @see HandleImpl#HandleImpl(UntypedHandleImpl)
+ */
+ SharedBufferHandleImpl(UntypedHandleImpl handle) {
+ super(handle);
+ }
+
+ /**
+ * @see SharedBufferHandle#duplicate(DuplicateOptions)
+ */
+ @Override
+ public SharedBufferHandle duplicate(DuplicateOptions options) {
+ return mCore.duplicate(this, options);
+ }
+
+ /**
+ * @see SharedBufferHandle#map(long, long, MapFlags)
+ */
+ @Override
+ public ByteBuffer map(long offset, long numBytes, MapFlags flags) {
+ return mCore.map(this, offset, numBytes, flags);
+ }
+
+ /**
+ * @see SharedBufferHandle#unmap(ByteBuffer)
+ */
+ @Override
+ public void unmap(ByteBuffer buffer) {
+ mCore.unmap(buffer);
+ }
+
+}
diff --git a/mojo/android/system/src/org/chromium/mojo/system/UntypedHandleImpl.java b/mojo/android/system/src/org/chromium/mojo/system/UntypedHandleImpl.java
new file mode 100644
index 0000000000..85c769132f
--- /dev/null
+++ b/mojo/android/system/src/org/chromium/mojo/system/UntypedHandleImpl.java
@@ -0,0 +1,54 @@
+// 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.system;
+
+import org.chromium.mojo.system.DataPipe.ConsumerHandle;
+import org.chromium.mojo.system.DataPipe.ProducerHandle;
+
+/**
+ * Implementation of {@link UntypedHandle}.
+ */
+class UntypedHandleImpl extends HandleImpl implements UntypedHandle {
+
+ /**
+ * @see HandleImpl#HandleImpl(CoreImpl, int)
+ */
+ UntypedHandleImpl(CoreImpl core, int mojoHandle) {
+ super(core, mojoHandle);
+ }
+
+ /**
+ * @see org.chromium.mojo.system.UntypedHandle#toMessagePipeHandle()
+ */
+ @Override
+ public MessagePipeHandle toMessagePipeHandle() {
+ return new MessagePipeHandleImpl(this);
+ }
+
+ /**
+ * @see org.chromium.mojo.system.UntypedHandle#toDataPipeConsumerHandle()
+ */
+ @Override
+ public ConsumerHandle toDataPipeConsumerHandle() {
+ return new DataPipeConsumerHandleImpl(this);
+ }
+
+ /**
+ * @see org.chromium.mojo.system.UntypedHandle#toDataPipeProducerHandle()
+ */
+ @Override
+ public ProducerHandle toDataPipeProducerHandle() {
+ return new DataPipeProducerHandleImpl(this);
+ }
+
+ /**
+ * @see org.chromium.mojo.system.UntypedHandle#toSharedBufferHandle()
+ */
+ @Override
+ public SharedBufferHandle toSharedBufferHandle() {
+ return new SharedBufferHandleImpl(this);
+ }
+
+}
diff --git a/mojo/apps/js/bindings/connection_unittests.js b/mojo/apps/js/bindings/connection_unittests.js
index 0ec37b01ff..91ea8e3494 100644
--- a/mojo/apps/js/bindings/connection_unittests.js
+++ b/mojo/apps/js/bindings/connection_unittests.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Mock out the support module to avoid depending on the message loop.
-define("mojo/bindings/js/support", ["timer"], function(timer) {
+define("mojo/public/js/bindings/support", ["timer"], function(timer) {
var waitingCallbacks = [];
function WaitCookie(id) {
@@ -55,8 +55,8 @@ define("mojo/bindings/js/support", ["timer"], function(timer) {
define([
"gin/test/expect",
- "mojo/bindings/js/support",
- "mojo/bindings/js/core",
+ "mojo/public/js/bindings/support",
+ "mojo/public/js/bindings/core",
"mojo/public/js/bindings/connection",
"mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
"mojo/public/interfaces/bindings/tests/sample_service.mojom",
diff --git a/mojo/apps/js/bindings/sample_service_unittests.js b/mojo/apps/js/bindings/sample_service_unittests.js
index 1191c8863e..d7c01266b9 100644
--- a/mojo/apps/js/bindings/sample_service_unittests.js
+++ b/mojo/apps/js/bindings/sample_service_unittests.js
@@ -140,8 +140,10 @@ define([
}
SimpleMessageReceiver.prototype.accept = function(message) {
- if (dumpMessageAsHex)
- console.log(hexdump.dumpArray(message.memory));
+ if (dumpMessageAsHex) {
+ var uint8Array = new Uint8Array(message.buffer.arrayBuffer);
+ console.log(hexdump.dumpArray(uint8Array));
+ }
// Imagine some IPC happened here.
var serviceImpl = new ServiceImpl();
serviceImpl.accept(message);
diff --git a/mojo/apps/js/main.js b/mojo/apps/js/main.js
index fb2d15bf2c..a3b3dd2d48 100644
--- a/mojo/apps/js/main.js
+++ b/mojo/apps/js/main.js
@@ -7,7 +7,7 @@ define([
'monotonic_clock',
'timer',
'mojo/public/js/bindings/connection',
- 'mojo/bindings/js/core',
+ 'mojo/public/js/bindings/core',
'mojo/apps/js/bindings/gl',
'mojo/apps/js/bindings/threading',
'mojo/services/native_viewport/native_viewport.mojom',
diff --git a/mojo/apps/js/test/run_apps_js_tests.cc b/mojo/apps/js/test/run_apps_js_tests.cc
index 3d27e47c9c..5037f8a352 100644
--- a/mojo/apps/js/test/run_apps_js_tests.cc
+++ b/mojo/apps/js/test/run_apps_js_tests.cc
@@ -13,6 +13,7 @@
#include "mojo/apps/js/bindings/monotonic_clock.h"
#include "mojo/apps/js/bindings/threading.h"
#include "mojo/bindings/js/core.h"
+#include "mojo/bindings/js/unicode.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -24,6 +25,7 @@ class TestRunnerDelegate : public gin::FileRunnerDelegate {
TestRunnerDelegate() {
AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule);
AddBuiltinModule(Core::kModuleName, Core::GetModule);
+ AddBuiltinModule(Unicode::kModuleName, Unicode::GetModule);
AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule);
AddBuiltinModule(apps::MonotonicClock::kModuleName,
apps::MonotonicClock::GetModule);
diff --git a/mojo/bindings/js/codec_unittests.js b/mojo/bindings/js/codec_unittests.js
index e2823e0701..b20dbcb47a 100644
--- a/mojo/bindings/js/codec_unittests.js
+++ b/mojo/bindings/js/codec_unittests.js
@@ -10,6 +10,7 @@ define([
testBar();
testFoo();
testAlign();
+ testUtf8();
this.result = "PASS";
function testBar() {
@@ -41,7 +42,8 @@ define([
5, 6, 7, 8,
]);
- expect(message.memory).toEqual(expectedMemory);
+ var actualMemory = new Uint8Array(message.buffer.arrayBuffer);
+ expect(actualMemory).toEqual(expectedMemory);
var reader = new codec.MessageReader(message);
@@ -83,7 +85,7 @@ define([
foo.source = 23423782;
var messageName = 31;
- var payloadSize = 224;
+ var payloadSize = 240;
var builder = new codec.MessageBuilder(messageName, payloadSize);
builder.encodeStruct(sample.Foo, foo);
@@ -93,13 +95,13 @@ define([
var expectedMemory = new Uint8Array([
/* 0: */ 16, 0, 0, 0, 2, 0, 0, 0,
/* 8: */ 31, 0, 0, 0, 0, 0, 0, 0,
- /* 16: */ 72, 0, 0, 0, 12, 0, 0, 0,
+ /* 16: */ 80, 0, 0, 0, 13, 0, 0, 0,
/* 24: */ 0xD5, 0xB4, 0x12, 0x02, 0x93, 0x6E, 0x01, 0,
/* 32: */ 5, 0, 0, 0, 0, 0, 0, 0,
- /* 40: */ 48, 0, 0, 0, 0, 0, 0, 0,
+ /* 40: */ 56, 0, 0, 0, 0, 0, 0, 0,
]);
// TODO(abarth): Test more of the message's raw memory.
- var actualMemory = new Uint8Array(message.memory.buffer,
+ var actualMemory = new Uint8Array(message.buffer.arrayBuffer,
0, expectedMemory.length);
expect(actualMemory).toEqual(expectedMemory);
@@ -158,4 +160,31 @@ define([
for (var i = 0; i < aligned.length; ++i)
expect(codec.align(i)).toBe(aligned[i]);
}
+
+ function testUtf8() {
+ var str = "B\u03ba\u1f79"; // some UCS-2 codepoints
+ var messageName = 42;
+ var payloadSize = 24;
+
+ var builder = new codec.MessageBuilder(messageName, payloadSize);
+ var encoder = builder.createEncoder(8);
+ encoder.encodeStringPointer(str);
+ var message = builder.finish();
+ var expectedMemory = new Uint8Array([
+ /* 0: */ 16, 0, 0, 0, 2, 0, 0, 0,
+ /* 8: */ 42, 0, 0, 0, 0, 0, 0, 0,
+ /* 16: */ 8, 0, 0, 0, 0, 0, 0, 0,
+ /* 24: */ 14, 0, 0, 0, 6, 0, 0, 0,
+ /* 32: */ 0x42, 0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0, 0,
+ ]);
+ var actualMemory = new Uint8Array(message.buffer.arrayBuffer);
+ expect(actualMemory.length).toEqual(expectedMemory.length);
+ expect(actualMemory).toEqual(expectedMemory);
+
+ var reader = new codec.MessageReader(message);
+ expect(reader.payloadSize).toBe(payloadSize);
+ expect(reader.messageName).toBe(messageName);
+ var str2 = reader.decoder.decodeStringPointer();
+ expect(str2).toEqual(str);
+ }
});
diff --git a/mojo/bindings/js/core.cc b/mojo/bindings/js/core.cc
index de53cfc7e4..855637b920 100644
--- a/mojo/bindings/js/core.cc
+++ b/mojo/bindings/js/core.cc
@@ -199,7 +199,7 @@ gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
} // namespace
-const char Core::kModuleName[] = "mojo/bindings/js/core";
+const char Core::kModuleName[] = "mojo/public/js/bindings/core";
v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) {
gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
diff --git a/mojo/bindings/js/core_unittests.js b/mojo/bindings/js/core_unittests.js
index 62b20d1ac6..20446dbc26 100644
--- a/mojo/bindings/js/core_unittests.js
+++ b/mojo/bindings/js/core_unittests.js
@@ -4,7 +4,7 @@
define([
"gin/test/expect",
- "mojo/bindings/js/core",
+ "mojo/public/js/bindings/core",
"gc",
], function(expect, core, gc) {
runWithMessagePipe(testNop);
diff --git a/mojo/bindings/js/run_js_tests.cc b/mojo/bindings/js/run_js_tests.cc
index d47070d1de..c3349ccf7c 100644
--- a/mojo/bindings/js/run_js_tests.cc
+++ b/mojo/bindings/js/run_js_tests.cc
@@ -10,6 +10,7 @@
#include "gin/test/file_runner.h"
#include "gin/test/gtest.h"
#include "mojo/bindings/js/core.h"
+#include "mojo/bindings/js/unicode.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -21,6 +22,7 @@ class TestRunnerDelegate : public gin::FileRunnerDelegate {
TestRunnerDelegate() {
AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule);
AddBuiltinModule(Core::kModuleName, Core::GetModule);
+ AddBuiltinModule(Unicode::kModuleName, Unicode::GetModule);
}
private:
diff --git a/mojo/bindings/js/support.cc b/mojo/bindings/js/support.cc
index ba62e8a306..cb8cb99665 100644
--- a/mojo/bindings/js/support.cc
+++ b/mojo/bindings/js/support.cc
@@ -55,7 +55,7 @@ gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
} // namespace
-const char Support::kModuleName[] = "mojo/bindings/js/support";
+const char Support::kModuleName[] = "mojo/public/js/bindings/support";
v8::Local<v8::Value> Support::GetModule(v8::Isolate* isolate) {
gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
diff --git a/mojo/bindings/js/unicode.cc b/mojo/bindings/js/unicode.cc
new file mode 100644
index 0000000000..22f9e9830d
--- /dev/null
+++ b/mojo/bindings/js/unicode.cc
@@ -0,0 +1,69 @@
+// 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/bindings/js/unicode.h"
+
+#include "gin/arguments.h"
+#include "gin/array_buffer.h"
+#include "gin/object_template_builder.h"
+#include "gin/per_isolate_data.h"
+#include "gin/public/wrapper_info.h"
+
+namespace mojo {
+namespace js {
+
+namespace {
+
+v8::Handle<v8::Value> DecodeUtf8String(const gin::Arguments& args,
+ const gin::ArrayBufferView& buffer) {
+ assert(static_cast<int>(buffer.num_bytes()) >= 0);
+ return v8::String::NewFromUtf8(args.isolate(),
+ reinterpret_cast<char*>(buffer.bytes()),
+ v8::String::kNormalString,
+ static_cast<int>(buffer.num_bytes()));
+}
+
+int EncodeUtf8String(const gin::Arguments& args,
+ v8::Handle<v8::Value> str_value,
+ const gin::ArrayBufferView& buffer) {
+ assert(static_cast<int>(buffer.num_bytes()) >= 0);
+ v8::Handle<v8::String> str = str_value->ToString();
+ int num_bytes = str->WriteUtf8(
+ reinterpret_cast<char*>(buffer.bytes()),
+ static_cast<int>(buffer.num_bytes()),
+ NULL,
+ v8::String::NO_NULL_TERMINATION | v8::String::REPLACE_INVALID_UTF8);
+ return num_bytes;
+}
+
+int Utf8Length(v8::Handle<v8::Value> str_value) {
+ return str_value->ToString()->Utf8Length();
+}
+
+gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
+
+} // namespace
+
+const char Unicode::kModuleName[] = "mojo/public/js/bindings/unicode";
+
+v8::Local<v8::Value> Unicode::GetModule(v8::Isolate* isolate) {
+ gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
+ v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
+ &g_wrapper_info);
+
+ if (templ.IsEmpty()) {
+ templ = gin::ObjectTemplateBuilder(isolate)
+ .SetMethod("decodeUtf8String", DecodeUtf8String)
+ .SetMethod("encodeUtf8String", EncodeUtf8String)
+ .SetMethod("utf8Length", Utf8Length)
+ .Build();
+
+ data->SetObjectTemplate(&g_wrapper_info, templ);
+ }
+
+ return templ->NewInstance();
+}
+
+} // namespace js
+} // namespace mojo
diff --git a/mojo/bindings/js/unicode.h b/mojo/bindings/js/unicode.h
new file mode 100644
index 0000000000..de1e3bb205
--- /dev/null
+++ b/mojo/bindings/js/unicode.h
@@ -0,0 +1,22 @@
+// 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_BINDINGS_JS_UNICODE_H_
+#define MOJO_BINDINGS_JS_UNICODE_H_
+
+#include "v8/include/v8.h"
+
+namespace mojo {
+namespace js {
+
+class Unicode {
+ public:
+ static const char kModuleName[];
+ static v8::Local<v8::Value> GetModule(v8::Isolate* isolate);
+};
+
+} // namespace js
+} // namespace mojo
+
+#endif // MOJO_BINDINGS_JS_UNICODE_H_
diff --git a/mojo/bindings/js/waiting_callback.h b/mojo/bindings/js/waiting_callback.h
index bc17d19391..90cf284254 100644
--- a/mojo/bindings/js/waiting_callback.h
+++ b/mojo/bindings/js/waiting_callback.h
@@ -8,7 +8,7 @@
#include "gin/handle.h"
#include "gin/runner.h"
#include "gin/wrappable.h"
-#include "mojo/public/c/system/async_waiter.h"
+#include "mojo/public/c/environment/async_waiter.h"
namespace mojo {
namespace js {
diff --git a/mojo/common/DEPS b/mojo/common/DEPS
index a1d21b53ea..26456c6ff0 100644
--- a/mojo/common/DEPS
+++ b/mojo/common/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"-mojo",
"+mojo/common",
+ "+mojo/embedder",
"+mojo/public",
]
diff --git a/mojo/common/message_pump_mojo.cc b/mojo/common/message_pump_mojo.cc
index 2afa72f1dc..5bc3462b0c 100644
--- a/mojo/common/message_pump_mojo.cc
+++ b/mojo/common/message_pump_mojo.cc
@@ -68,69 +68,84 @@ void MessagePumpMojo::RemoveHandler(const Handle& handle) {
}
void MessagePumpMojo::Run(Delegate* delegate) {
- RunState* old_state = run_state_;
RunState run_state;
// TODO: better deal with error handling.
CHECK(run_state.read_handle.is_valid());
CHECK(run_state.write_handle.is_valid());
- run_state_ = &run_state;
+ RunState* old_state = NULL;
+ {
+ base::AutoLock auto_lock(run_state_lock_);
+ old_state = run_state_;
+ run_state_ = &run_state;
+ }
+ DoRunLoop(&run_state, delegate);
+ {
+ base::AutoLock auto_lock(run_state_lock_);
+ run_state_ = old_state;
+ }
+}
+
+void MessagePumpMojo::Quit() {
+ base::AutoLock auto_lock(run_state_lock_);
+ if (run_state_)
+ run_state_->should_quit = true;
+}
+
+void MessagePumpMojo::ScheduleWork() {
+ base::AutoLock auto_lock(run_state_lock_);
+ if (run_state_)
+ SignalControlPipe(*run_state_);
+}
+
+void MessagePumpMojo::ScheduleDelayedWork(
+ const base::TimeTicks& delayed_work_time) {
+ base::AutoLock auto_lock(run_state_lock_);
+ if (!run_state_)
+ return;
+ run_state_->delayed_work_time = delayed_work_time;
+ SignalControlPipe(*run_state_);
+}
+
+void MessagePumpMojo::DoRunLoop(RunState* run_state, Delegate* delegate) {
bool more_work_is_plausible = true;
for (;;) {
const bool block = !more_work_is_plausible;
- DoInternalWork(block);
+ DoInternalWork(*run_state, block);
// There isn't a good way to know if there are more handles ready, we assume
// not.
more_work_is_plausible = false;
- if (run_state.should_quit)
+ if (run_state->should_quit)
break;
more_work_is_plausible |= delegate->DoWork();
- if (run_state.should_quit)
+ if (run_state->should_quit)
break;
more_work_is_plausible |= delegate->DoDelayedWork(
- &run_state.delayed_work_time);
- if (run_state.should_quit)
+ &run_state->delayed_work_time);
+ if (run_state->should_quit)
break;
if (more_work_is_plausible)
continue;
more_work_is_plausible = delegate->DoIdleWork();
- if (run_state.should_quit)
+ if (run_state->should_quit)
break;
}
- run_state_ = old_state;
-}
-
-void MessagePumpMojo::Quit() {
- if (run_state_)
- run_state_->should_quit = true;
}
-void MessagePumpMojo::ScheduleWork() {
- SignalControlPipe();
-}
-
-void MessagePumpMojo::ScheduleDelayedWork(
- const base::TimeTicks& delayed_work_time) {
- if (!run_state_)
- return;
- run_state_->delayed_work_time = delayed_work_time;
- SignalControlPipe();
-}
-
-void MessagePumpMojo::DoInternalWork(bool block) {
- const MojoDeadline deadline = block ? GetDeadlineForWait() : 0;
- const WaitState wait_state = GetWaitState();
+void MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) {
+ const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0;
+ const WaitState wait_state = GetWaitState(run_state);
const MojoResult result =
WaitMany(wait_state.handles, wait_state.wait_flags, deadline);
if (result == 0) {
// Control pipe was written to.
uint32_t num_bytes = 0;
- ReadMessageRaw(run_state_->read_handle.get(), NULL, &num_bytes, NULL, NULL,
+ ReadMessageRaw(run_state.read_handle.get(), NULL, &num_bytes, NULL, NULL,
MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
} else if (result > 0) {
const size_t index = static_cast<size_t>(result);
@@ -187,18 +202,16 @@ void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
}
}
-void MessagePumpMojo::SignalControlPipe() {
- if (!run_state_)
- return;
-
+void MessagePumpMojo::SignalControlPipe(const RunState& run_state) {
// TODO(sky): deal with error?
- WriteMessageRaw(run_state_->write_handle.get(), NULL, 0, NULL, 0,
+ WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0,
MOJO_WRITE_MESSAGE_FLAG_NONE);
}
-MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState() const {
+MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState(
+ const RunState& run_state) const {
WaitState wait_state;
- wait_state.handles.push_back(run_state_->read_handle.get());
+ wait_state.handles.push_back(run_state.read_handle.get());
wait_state.wait_flags.push_back(MOJO_WAIT_FLAG_READABLE);
for (HandleToHandler::const_iterator i = handlers_.begin();
@@ -209,8 +222,9 @@ MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState() const {
return wait_state;
}
-MojoDeadline MessagePumpMojo::GetDeadlineForWait() const {
- base::TimeTicks min_time = run_state_->delayed_work_time;
+MojoDeadline MessagePumpMojo::GetDeadlineForWait(
+ const RunState& run_state) const {
+ base::TimeTicks min_time = run_state.delayed_work_time;
for (HandleToHandler::const_iterator i = handlers_.begin();
i != handlers_.end(); ++i) {
if (min_time.is_null() && i->second.deadline < min_time)
diff --git a/mojo/common/message_pump_mojo.h b/mojo/common/message_pump_mojo.h
index cc21565b65..c76110678c 100644
--- a/mojo/common/message_pump_mojo.h
+++ b/mojo/common/message_pump_mojo.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump.h"
+#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "mojo/common/mojo_common_export.h"
#include "mojo/public/cpp/system/core.h"
@@ -61,25 +62,33 @@ class MOJO_COMMON_EXPORT MessagePumpMojo : public base::MessagePump {
typedef std::map<Handle, Handler> HandleToHandler;
+ // Implementation of Run().
+ void DoRunLoop(RunState* run_state, Delegate* delegate);
+
// Services the set of handles ready. If |block| is true this waits for a
// handle to become ready, otherwise this does not block.
- void DoInternalWork(bool block);
+ void DoInternalWork(const RunState& run_state, bool block);
// Removes the first invalid handle. This is called if MojoWaitMany finds an
// invalid handle.
void RemoveFirstInvalidHandle(const WaitState& wait_state);
- void SignalControlPipe();
+ void SignalControlPipe(const RunState& run_state);
- WaitState GetWaitState() const;
+ WaitState GetWaitState(const RunState& run_state) const;
// Returns the deadline for the call to MojoWaitMany().
- MojoDeadline GetDeadlineForWait() const;
+ MojoDeadline GetDeadlineForWait(const RunState& run_state) const;
// If non-NULL we're running (inside Run()). Member is reference to value on
// stack.
RunState* run_state_;
+ // Lock for accessing |run_state_|. In general the only method that we have to
+ // worry about is ScheduleWork(). All other methods are invoked on the same
+ // thread.
+ base::Lock run_state_lock_;
+
HandleToHandler handlers_;
// An ever increasing value assigned to each Handler::id. Used to detect
diff --git a/mojo/common/mojo_channel_init.cc b/mojo/common/mojo_channel_init.cc
new file mode 100644
index 0000000000..96190f9d5d
--- /dev/null
+++ b/mojo/common/mojo_channel_init.cc
@@ -0,0 +1,59 @@
+// 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/common/mojo_channel_init.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/embedder/embedder.h"
+
+namespace mojo {
+namespace common {
+
+MojoChannelInit::MojoChannelInit()
+ : channel_info_(NULL),
+ weak_factory_(this) {
+}
+
+MojoChannelInit::~MojoChannelInit() {
+ bootstrap_message_pipe_.reset();
+ if (channel_info_) {
+ io_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&mojo::embedder::DestroyChannelOnIOThread, channel_info_));
+ }
+}
+
+void MojoChannelInit::Init(
+ base::PlatformFile file,
+ scoped_refptr<base::TaskRunner> io_thread_task_runner) {
+ DCHECK(!io_thread_task_runner_.get()); // Should only init once.
+ io_thread_task_runner_ = io_thread_task_runner;
+ bootstrap_message_pipe_ = mojo::embedder::CreateChannel(
+ mojo::embedder::ScopedPlatformHandle(
+ mojo::embedder::PlatformHandle(file)),
+ io_thread_task_runner,
+ base::Bind(&MojoChannelInit::OnCreatedChannel, weak_factory_.GetWeakPtr(),
+ io_thread_task_runner),
+ base::MessageLoop::current()->message_loop_proxy()).Pass();
+}
+
+// static
+void MojoChannelInit::OnCreatedChannel(
+ base::WeakPtr<MojoChannelInit> host,
+ scoped_refptr<base::TaskRunner> io_thread,
+ embedder::ChannelInfo* channel) {
+ // By the time we get here |host| may have been destroyed. If so, shutdown the
+ // channel.
+ if (!host.get()) {
+ io_thread->PostTask(
+ FROM_HERE,
+ base::Bind(&mojo::embedder::DestroyChannelOnIOThread, channel));
+ return;
+ }
+ host->channel_info_ = channel;
+}
+
+} // namespace common
+} // namespace mojo
diff --git a/mojo/common/mojo_channel_init.h b/mojo/common/mojo_channel_init.h
new file mode 100644
index 0000000000..8fa00941c2
--- /dev/null
+++ b/mojo/common/mojo_channel_init.h
@@ -0,0 +1,66 @@
+// 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_COMMON_MOJO_CHANNEL_INIT_H_
+#define MOJO_COMMON_MOJO_CHANNEL_INIT_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/platform_file.h"
+#include "mojo/common/mojo_common_export.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace base {
+class MessageLoopProxy;
+class TaskRunner;
+}
+
+namespace mojo {
+namespace embedder {
+struct ChannelInfo;
+}
+
+namespace common {
+
+// MojoChannelInit handle creation (and destruction) of the mojo channel. It is
+// expected that this class is created and destroyed on the main thread.
+class MOJO_COMMON_EXPORT MojoChannelInit {
+ public:
+ MojoChannelInit();
+ ~MojoChannelInit();
+
+ // Inits the channel. This takes ownership of |file|.
+ void Init(base::PlatformFile file,
+ scoped_refptr<base::TaskRunner> io_thread_task_runner);
+
+ bool is_handle_valid() const { return bootstrap_message_pipe_.is_valid(); }
+
+ mojo::ScopedMessagePipeHandle bootstrap_message_pipe() {
+ return bootstrap_message_pipe_.Pass();
+ }
+
+ private:
+ // Invoked on the main thread once the channel has been established.
+ static void OnCreatedChannel(
+ base::WeakPtr<MojoChannelInit> host,
+ scoped_refptr<base::TaskRunner> io_thread,
+ embedder::ChannelInfo* channel);
+
+ scoped_refptr<base::TaskRunner> io_thread_task_runner_;
+
+ // If non-null the channel has been established.
+ embedder::ChannelInfo* channel_info_;
+
+ // The handle from channel creation.
+ mojo::ScopedMessagePipeHandle bootstrap_message_pipe_;
+
+ base::WeakPtrFactory<MojoChannelInit> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoChannelInit);
+};
+
+} // namespace common
+} // namespace mojo
+
+#endif // MOJO_COMMON_MOJO_CHANNEL_INIT_H_
diff --git a/mojo/embedder/embedder.cc b/mojo/embedder/embedder.cc
index 7698160336..e8c6e8e53b 100644
--- a/mojo/embedder/embedder.cc
+++ b/mojo/embedder/embedder.cc
@@ -44,6 +44,8 @@ static void CreateChannelOnIOThread(
// Attach the message pipe endpoint.
system::MessageInTransit::EndpointId endpoint_id =
channel_info->channel->AttachMessagePipeEndpoint(message_pipe, 1);
+ // We shouldn't get |kInvalidEndpointId| here -- since |CreateChannel()| is
+ // responsible for the local endpoint, and won't close it.
DCHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId);
success = channel_info->channel->RunMessagePipeEndpoint(
system::Channel::kBootstrapEndpointId,
diff --git a/mojo/environment/default_async_waiter_impl.h b/mojo/environment/default_async_waiter_impl.h
index 266a70f687..8e697cb425 100644
--- a/mojo/environment/default_async_waiter_impl.h
+++ b/mojo/environment/default_async_waiter_impl.h
@@ -6,7 +6,7 @@
#define MOJO_ENVIRONMENT_DEFAULT_ASYNC_WAITER_IMPL_H_
#include "mojo/environment/mojo_environment_impl_export.h"
-#include "mojo/public/c/system/async_waiter.h"
+#include "mojo/public/c/environment/async_waiter.h"
namespace mojo {
namespace internal {
diff --git a/mojo/examples/sample_view_manager_app/sample_view_manager_app.cc b/mojo/examples/sample_view_manager_app/sample_view_manager_app.cc
new file mode 100644
index 0000000000..c6d6e7c779
--- /dev/null
+++ b/mojo/examples/sample_view_manager_app/sample_view_manager_app.cc
@@ -0,0 +1,74 @@
+// 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/bind.h"
+#include "mojo/public/cpp/bindings/allocation_scope.h"
+#include "mojo/public/cpp/bindings/remote_ptr.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/shell/application.h"
+#include "mojo/public/cpp/system/core.h"
+#include "mojo/public/cpp/system/macros.h"
+#include "mojo/public/cpp/utility/run_loop.h"
+#include "mojo/public/interfaces/shell/shell.mojom.h"
+#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
+
+#if defined(WIN32)
+#if !defined(CDECL)
+#define CDECL __cdecl
+#endif
+#define SAMPLE_APP_EXPORT __declspec(dllexport)
+#else
+#define CDECL
+#define SAMPLE_APP_EXPORT __attribute__((visibility("default")))
+#endif
+
+namespace mojo {
+namespace examples {
+
+class SampleApp : public Application,
+ public services::view_manager::ViewManagerClient {
+ public:
+ explicit SampleApp(MojoHandle shell_handle) : Application(shell_handle) {
+ InterfacePipe<services::view_manager::ViewManager, AnyInterface>
+ view_manager_pipe;
+ AllocationScope scope;
+ shell()->Connect("mojo:mojo_view_manager",
+ view_manager_pipe.handle_to_peer.Pass());
+ view_manager_.reset(view_manager_pipe.handle_to_self.Pass(), this);
+ view_manager_->CreateNode(1, base::Bind(&SampleApp::OnCreatedView,
+ base::Unretained(this)));
+ }
+
+ virtual ~SampleApp() {
+ }
+
+ // ViewManagerClient::
+ virtual void OnConnectionEstablished(uint16_t connection_id) OVERRIDE {
+ }
+ virtual void OnNodeHierarchyChanged(uint32_t node,
+ uint32_t new_parent,
+ uint32_t old_parent,
+ int32_t change_id) OVERRIDE {
+ }
+
+ private:
+ void OnCreatedView(bool success) {
+ DCHECK(success);
+ }
+
+ RemotePtr<services::view_manager::ViewManager> view_manager_;
+};
+
+} // namespace examples
+} // namespace mojo
+
+extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain(
+ MojoHandle shell_handle) {
+ mojo::Environment env;
+ mojo::RunLoop loop;
+
+ mojo::examples::SampleApp app(shell_handle);
+ loop.Run();
+ return MOJO_RESULT_OK;
+}
diff --git a/mojo/examples/view_manager/view_manager.cc b/mojo/examples/view_manager/view_manager.cc
deleted file mode 100644
index e10363b5af..0000000000
--- a/mojo/examples/view_manager/view_manager.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 <stdio.h>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/scoped_vector.h"
-#include "base/message_loop/message_loop.h"
-#include "mojo/examples/launcher/launcher.mojom.h"
-#include "mojo/examples/view_manager/view_manager.mojom.h"
-#include "mojo/public/cpp/bindings/allocation_scope.h"
-#include "mojo/public/cpp/bindings/remote_ptr.h"
-#include "mojo/public/cpp/shell/application.h"
-#include "mojo/public/cpp/system/core.h"
-#include "mojo/public/interfaces/shell/shell.mojom.h"
-#include "mojo/services/native_viewport/geometry_conversions.h"
-#include "mojo/services/native_viewport/native_viewport.mojom.h"
-#include "ui/events/event_constants.h"
-#include "ui/events/keycodes/keyboard_codes.h"
-#include "ui/gfx/rect.h"
-
-#if defined(WIN32)
-#if !defined(CDECL)
-#define CDECL __cdecl)
-#endif
-#define VIEW_MANAGER_EXPORT __declspec(dllexport)
-#else
-#define CDECL
-#define VIEW_MANAGER_EXPORT __attribute__((visibility("default")))
-#endif
-
-namespace mojo {
-namespace examples {
-
-class ViewImpl : public View {
- public:
- explicit ViewImpl(ScopedViewClientHandle handle)
- : id_(-1),
- client_(handle.Pass(), this) {}
- virtual ~ViewImpl() {}
-
- private:
- // Overridden from View:
- virtual void SetId(int view_id) OVERRIDE {
- id_ = view_id;
- }
- virtual void GetId(const mojo::Callback<void(int32_t)>& callback) OVERRIDE {
- callback.Run(id_);
- }
-
- int id_;
- RemotePtr<ViewClient> client_;
-
- DISALLOW_COPY_AND_ASSIGN(ViewImpl);
-};
-
-class ViewManagerImpl : public Service<ViewManager, ViewManagerImpl>,
- public NativeViewportClient,
- public LauncherClient {
- public:
- explicit ViewManagerImpl() {
- InitNativeViewport();
- }
-
- private:
- // Overridden from ViewManager:
- virtual void CreateView(const Callback<void(ScopedViewHandle)>& callback)
- OVERRIDE {
- InterfacePipe<View> pipe;
- views_.push_back(new ViewImpl(pipe.handle_to_peer.Pass()));
- callback.Run(pipe.handle_to_self.Pass());
- }
-
- // Overridden from NativeViewportClient:
- virtual void OnCreated() OVERRIDE {
- }
- virtual void OnDestroyed() OVERRIDE {
- base::MessageLoop::current()->Quit();
- }
- virtual void OnBoundsChanged(const Rect& bounds) OVERRIDE {
- // TODO(beng):
- }
- virtual void OnEvent(const Event& event,
- const mojo::Callback<void()>& callback) OVERRIDE {
- if (event.action() == ui::ET_KEY_RELEASED) {
- if (event.key_data().key_code() == ui::VKEY_L &&
- (event.flags() & ui::EF_CONTROL_DOWN)) {
- InitLauncher();
- launcher_->Show();
- }
- }
- callback.Run();
- }
-
- // Overridden from LauncherClient:
- virtual void OnURLEntered(const mojo::String& url) OVERRIDE {
- std::string url_spec = url.To<std::string>();
- printf("Received URL from launcher app: %s\n", url_spec.c_str());
- launcher_->Hide();
- }
-
- void InitNativeViewport() {
- InterfacePipe<NativeViewport, AnyInterface> pipe;
-
- AllocationScope scope;
- shell()->Connect("mojo:mojo_native_viewport_service",
- pipe.handle_to_peer.Pass());
-
- native_viewport_.reset(pipe.handle_to_self.Pass(), this);
- native_viewport_->Create(gfx::Rect(50, 50, 800, 600));
- native_viewport_->Show();
- }
-
- void InitLauncher() {
- if (!launcher_.is_null())
- return;
-
- InterfacePipe<Launcher, AnyInterface> pipe;
-
- AllocationScope scope;
- shell()->Connect("mojo:mojo_launcher", pipe.handle_to_peer.Pass());
-
- launcher_.reset(pipe.handle_to_self.Pass(), this);
- }
-
- void DidCreateContext() {
- }
-
- ScopedVector<ViewImpl> views_;
- RemotePtr<NativeViewport> native_viewport_;
- RemotePtr<Launcher> launcher_;
-
- DISALLOW_COPY_AND_ASSIGN(ViewManagerImpl);
-};
-
-} // namespace examples
-} // namespace mojo
-
-extern "C" VIEW_MANAGER_EXPORT MojoResult CDECL MojoMain(
- MojoHandle shell_handle) {
- base::MessageLoop loop;
- mojo::Application app(shell_handle);
- app.AddServiceFactory(
- new mojo::ServiceFactory<mojo::examples::ViewManagerImpl>);
- loop.Run();
-
- return MOJO_RESULT_OK;
-}
diff --git a/mojo/examples/view_manager/view_manager.mojom b/mojo/examples/view_manager/view_manager.mojom
deleted file mode 100644
index 56beea48e0..0000000000
--- a/mojo/examples/view_manager/view_manager.mojom
+++ /dev/null
@@ -1,26 +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 {
-
-[Peer=ViewClient]
-interface View {
- SetId(int32 id);
- GetId() => (int32 id);
-};
-
-[Peer=View]
-interface ViewClient {
-};
-
-[Peer=ViewManagerClient]
-interface ViewManager {
- CreateView() => (View view);
-};
-
-[Peer=ViewManager]
-interface ViewManagerClient {
-};
-
-}
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index 86c1f9454a..4db1476458 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -59,7 +59,17 @@
'dependencies': [
'mojo_aura_demo',
'mojo_launcher',
+ 'mojo_sample_view_manager_app',
'mojo_view_manager',
+ 'mojo_view_manager_unittests',
+ ],
+ }],
+ ['OS == "android"', {
+ 'dependencies': [
+ 'mojo_public_java',
+ 'mojo_system_java',
+ 'libmojo_system_java',
+ 'mojo_test_apk',
],
}],
]
@@ -279,6 +289,8 @@
'common/message_pump_mojo.cc',
'common/message_pump_mojo.h',
'common/message_pump_mojo_handler.h',
+ 'common/mojo_channel_init.cc',
+ 'common/mojo_channel_init.h',
'common/time_helper.cc',
'common/time_helper.h',
],
@@ -523,6 +535,8 @@
'bindings/js/handle.h',
'bindings/js/support.cc',
'bindings/js/support.h',
+ 'bindings/js/unicode.cc',
+ 'bindings/js/unicode.h',
'bindings/js/waiting_callback.cc',
'bindings/js/waiting_callback.h',
],
@@ -534,7 +548,7 @@
'../gin/gin.gyp:gin_test',
'mojo_js_bindings_lib',
'mojo_run_all_unittests',
- 'mojo_sample_service',
+ 'mojo_public_test_interfaces',
],
'sources': [
'bindings/js/run_js_tests.cc',
@@ -560,41 +574,102 @@
['OS=="android"', {
'targets': [
{
- 'target_name': 'mojo_native_viewport_java',
+ 'target_name': 'mojo_jni_headers',
+ 'type': 'none',
+ 'dependencies': [
+ 'mojo_java_set_jni_headers',
+ ],
+ 'sources': [
+ 'android/javatests/src/org/chromium/mojo/system/CoreTest.java',
+ 'android/system/src/org/chromium/mojo/system/CoreImpl.java',
+ 'services/native_viewport/android/src/org/chromium/mojo/NativeViewportAndroid.java',
+ 'shell/android/apk/src/org/chromium/mojo_shell_apk/MojoMain.java',
+ ],
+ 'variables': {
+ 'jni_gen_package': 'mojo',
+ 'jni_generator_ptr_type': 'long',
+ },
+ 'includes': [ '../build/jni_generator.gypi' ],
+ },
+ {
+ 'target_name': 'mojo_system_java',
'type': 'none',
'dependencies': [
'../base/base.gyp:base_java',
+ 'mojo_public_java',
],
'variables': {
- 'java_in_dir': '<(DEPTH)/mojo/services/native_viewport/android',
+ 'java_in_dir': '<(DEPTH)/mojo/android/system',
},
'includes': [ '../build/java.gypi' ],
},
{
- 'target_name': 'mojo_java_set_jni_headers',
+ 'target_name': 'libmojo_system_java',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ 'mojo_common_lib',
+ 'mojo_environment_chromium',
+ 'mojo_jni_headers',
+ 'mojo_shell_bindings',
+ 'mojo_shell_lib',
+ ],
+ 'sources': [
+ 'android/system/core_impl.cc',
+ 'android/system/core_impl.h',
+ ],
+ },
+ {
+ 'target_name': 'libmojo_java_unittest',
+ 'type': 'shared_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ 'libmojo_system_java',
+ 'mojo_jni_headers',
+ ],
+ 'sources': [
+ 'android/javatests/core_test.cc',
+ 'android/javatests/core_test.h',
+ 'android/javatests/init_library.cc',
+ ],
+ },
+ {
+ 'target_name': 'mojo_test_apk',
'type': 'none',
+ 'dependencies': [
+ 'mojo_system_java',
+ '../base/base.gyp:base_java_test_support',
+ ],
'variables': {
- 'jni_gen_package': 'mojo',
- 'jni_generator_ptr_type': 'long',
- 'input_java_class': 'java/util/HashSet.class',
+ 'apk_name': 'MojoTest',
+ 'java_in_dir': '<(DEPTH)/mojo/android/javatests',
+ 'resource_dir': '<(DEPTH)/mojo/android/javatests/apk',
+ 'native_lib_target': 'libmojo_java_unittest',
+ 'is_test_apk': 1,
},
- 'includes': [ '../build/jar_file_jni_generator.gypi' ],
+ 'includes': [ '../build/java_apk.gypi' ],
},
{
- 'target_name': 'mojo_jni_headers',
+ 'target_name': 'mojo_native_viewport_java',
'type': 'none',
'dependencies': [
- 'mojo_java_set_jni_headers',
- ],
- 'sources': [
- 'services/native_viewport/android/src/org/chromium/mojo/NativeViewportAndroid.java',
- 'shell/android/apk/src/org/chromium/mojo_shell_apk/MojoMain.java',
+ '../base/base.gyp:base_java',
],
'variables': {
+ 'java_in_dir': '<(DEPTH)/mojo/services/native_viewport/android',
+ },
+ 'includes': [ '../build/java.gypi' ],
+ },
+ {
+ 'target_name': 'mojo_java_set_jni_headers',
+ 'type': 'none',
+ 'variables': {
'jni_gen_package': 'mojo',
'jni_generator_ptr_type': 'long',
- },
- 'includes': [ '../build/jni_generator.gypi' ],
+ 'input_java_class': 'java/util/HashSet.class',
+ },
+ 'includes': [ '../build/jar_file_jni_generator.gypi' ],
},
{
'target_name': 'libmojo_shell',
diff --git a/mojo/mojo_apps.gypi b/mojo/mojo_apps.gypi
index 62d904d231..66afb47d23 100644
--- a/mojo/mojo_apps.gypi
+++ b/mojo/mojo_apps.gypi
@@ -43,7 +43,7 @@
'../gin/gin.gyp:gin_test',
'mojo_js_lib',
'mojo_run_all_unittests',
- 'mojo_sample_service',
+ 'mojo_public_test_interfaces',
],
'sources': [
'apps/js/test/run_apps_js_tests.cc',
diff --git a/mojo/mojo_bindings.target.darwin-arm.mk b/mojo/mojo_bindings.target.darwin-arm.mk
index 9f6e80f3d2..04f97b853f 100644
--- a/mojo/mojo_bindings.target.darwin-arm.mk
+++ b/mojo/mojo_bindings.target.darwin-arm.mk
@@ -230,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.darwin-mips.mk b/mojo/mojo_bindings.target.darwin-mips.mk
index 21ef642573..d455f4fa9a 100644
--- a/mojo/mojo_bindings.target.darwin-mips.mk
+++ b/mojo/mojo_bindings.target.darwin-mips.mk
@@ -226,7 +226,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.darwin-x86.mk b/mojo/mojo_bindings.target.darwin-x86.mk
index efd4c43b10..0e0af9f4ee 100644
--- a/mojo/mojo_bindings.target.darwin-x86.mk
+++ b/mojo/mojo_bindings.target.darwin-x86.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.darwin-x86_64.mk b/mojo/mojo_bindings.target.darwin-x86_64.mk
index 3cfb6e3e97..6fbbc7b193 100644
--- a/mojo/mojo_bindings.target.darwin-x86_64.mk
+++ b/mojo/mojo_bindings.target.darwin-x86_64.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.linux-arm.mk b/mojo/mojo_bindings.target.linux-arm.mk
index 9f6e80f3d2..04f97b853f 100644
--- a/mojo/mojo_bindings.target.linux-arm.mk
+++ b/mojo/mojo_bindings.target.linux-arm.mk
@@ -230,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.linux-mips.mk b/mojo/mojo_bindings.target.linux-mips.mk
index 21ef642573..d455f4fa9a 100644
--- a/mojo/mojo_bindings.target.linux-mips.mk
+++ b/mojo/mojo_bindings.target.linux-mips.mk
@@ -226,7 +226,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.linux-x86.mk b/mojo/mojo_bindings.target.linux-x86.mk
index efd4c43b10..0e0af9f4ee 100644
--- a/mojo/mojo_bindings.target.linux-x86.mk
+++ b/mojo/mojo_bindings.target.linux-x86.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_bindings.target.linux-x86_64.mk b/mojo/mojo_bindings.target.linux-x86_64.mk
index 3cfb6e3e97..6fbbc7b193 100644
--- a/mojo/mojo_bindings.target.linux-x86_64.mk
+++ b/mojo/mojo_bindings.target.linux-x86_64.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.darwin-arm.mk b/mojo/mojo_common_lib.target.darwin-arm.mk
index 68b35f7b6d..ebf534cfe7 100644
--- a/mojo/mojo_common_lib.target.darwin-arm.mk
+++ b/mojo/mojo_common_lib.target.darwin-arm.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -227,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.darwin-mips.mk b/mojo/mojo_common_lib.target.darwin-mips.mk
index b1a8bd7045..f059697b50 100644
--- a/mojo/mojo_common_lib.target.darwin-mips.mk
+++ b/mojo/mojo_common_lib.target.darwin-mips.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -223,7 +224,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.darwin-x86.mk b/mojo/mojo_common_lib.target.darwin-x86.mk
index 0909f0ba0d..14e7ed77a5 100644
--- a/mojo/mojo_common_lib.target.darwin-x86.mk
+++ b/mojo/mojo_common_lib.target.darwin-x86.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -225,7 +226,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.darwin-x86_64.mk b/mojo/mojo_common_lib.target.darwin-x86_64.mk
index 370d66234b..c777ccc711 100644
--- a/mojo/mojo_common_lib.target.darwin-x86_64.mk
+++ b/mojo/mojo_common_lib.target.darwin-x86_64.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -225,7 +226,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.linux-arm.mk b/mojo/mojo_common_lib.target.linux-arm.mk
index 68b35f7b6d..ebf534cfe7 100644
--- a/mojo/mojo_common_lib.target.linux-arm.mk
+++ b/mojo/mojo_common_lib.target.linux-arm.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -227,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.linux-mips.mk b/mojo/mojo_common_lib.target.linux-mips.mk
index b1a8bd7045..f059697b50 100644
--- a/mojo/mojo_common_lib.target.linux-mips.mk
+++ b/mojo/mojo_common_lib.target.linux-mips.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -223,7 +224,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.linux-x86.mk b/mojo/mojo_common_lib.target.linux-x86.mk
index 0909f0ba0d..14e7ed77a5 100644
--- a/mojo/mojo_common_lib.target.linux-x86.mk
+++ b/mojo/mojo_common_lib.target.linux-x86.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -225,7 +226,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_common_lib.target.linux-x86_64.mk b/mojo/mojo_common_lib.target.linux-x86_64.mk
index 370d66234b..c777ccc711 100644
--- a/mojo/mojo_common_lib.target.linux-x86_64.mk
+++ b/mojo/mojo_common_lib.target.linux-x86_64.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/common/environment_data.cc \
mojo/common/handle_watcher.cc \
mojo/common/message_pump_mojo.cc \
+ mojo/common/mojo_channel_init.cc \
mojo/common/time_helper.cc
@@ -225,7 +226,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.darwin-arm.mk b/mojo/mojo_environment_chromium.target.darwin-arm.mk
index 60946212b8..b7e5624dfe 100644
--- a/mojo/mojo_environment_chromium.target.darwin-arm.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-arm.mk
@@ -223,7 +223,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.darwin-mips.mk b/mojo/mojo_environment_chromium.target.darwin-mips.mk
index c3ed74f1b4..aca1c30c9a 100644
--- a/mojo/mojo_environment_chromium.target.darwin-mips.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-mips.mk
@@ -219,7 +219,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.darwin-x86.mk b/mojo/mojo_environment_chromium.target.darwin-x86.mk
index f59dfba895..435cc4c7ff 100644
--- a/mojo/mojo_environment_chromium.target.darwin-x86.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-x86.mk
@@ -221,7 +221,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.darwin-x86_64.mk b/mojo/mojo_environment_chromium.target.darwin-x86_64.mk
index d408e14d67..8062f990ef 100644
--- a/mojo/mojo_environment_chromium.target.darwin-x86_64.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-x86_64.mk
@@ -221,7 +221,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.linux-arm.mk b/mojo/mojo_environment_chromium.target.linux-arm.mk
index 60946212b8..b7e5624dfe 100644
--- a/mojo/mojo_environment_chromium.target.linux-arm.mk
+++ b/mojo/mojo_environment_chromium.target.linux-arm.mk
@@ -223,7 +223,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.linux-mips.mk b/mojo/mojo_environment_chromium.target.linux-mips.mk
index c3ed74f1b4..aca1c30c9a 100644
--- a/mojo/mojo_environment_chromium.target.linux-mips.mk
+++ b/mojo/mojo_environment_chromium.target.linux-mips.mk
@@ -219,7 +219,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.linux-x86.mk b/mojo/mojo_environment_chromium.target.linux-x86.mk
index f59dfba895..435cc4c7ff 100644
--- a/mojo/mojo_environment_chromium.target.linux-x86.mk
+++ b/mojo/mojo_environment_chromium.target.linux-x86.mk
@@ -221,7 +221,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium.target.linux-x86_64.mk b/mojo/mojo_environment_chromium.target.linux-x86_64.mk
index d408e14d67..8062f990ef 100644
--- a/mojo/mojo_environment_chromium.target.linux-x86_64.mk
+++ b/mojo/mojo_environment_chromium.target.linux-x86_64.mk
@@ -221,7 +221,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk b/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk
index aea2ccd664..9b04cb45ad 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk
@@ -224,7 +224,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-mips.mk b/mojo/mojo_environment_chromium_impl.target.darwin-mips.mk
index d3991d51bd..b683e4708f 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-mips.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-mips.mk
@@ -220,7 +220,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk b/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk
index f9c06ba959..0ce43342e0 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk
@@ -222,7 +222,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk b/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk
index 969b92b04e..be57920033 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk
@@ -222,7 +222,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-arm.mk b/mojo/mojo_environment_chromium_impl.target.linux-arm.mk
index aea2ccd664..9b04cb45ad 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-arm.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-arm.mk
@@ -224,7 +224,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-mips.mk b/mojo/mojo_environment_chromium_impl.target.linux-mips.mk
index d3991d51bd..b683e4708f 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-mips.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-mips.mk
@@ -220,7 +220,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-x86.mk b/mojo/mojo_environment_chromium_impl.target.linux-x86.mk
index f9c06ba959..0ce43342e0 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-x86.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-x86.mk
@@ -222,7 +222,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk b/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk
index 969b92b04e..be57920033 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk
@@ -222,7 +222,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi
index 590285fd19..4de6fbd755 100644
--- a/mojo/mojo_examples.gypi
+++ b/mojo/mojo_examples.gypi
@@ -9,9 +9,8 @@
'type': 'shared_library',
'dependencies': [
# TODO(darin): we should not be linking against these libraries!
- '../ui/gfx/gfx.gyp:gfx',
+ '../ui/events/events.gyp:events',
'../ui/gfx/gfx.gyp:gfx_geometry',
- '../ui/gl/gl.gyp:gl',
'mojo_bindings',
'mojo_environment_standalone',
'mojo_gles2',
@@ -277,47 +276,25 @@
'includes': [ 'build/package_app.gypi' ],
},
{
- 'target_name': 'mojo_view_manager_bindings',
- 'type': 'static_library',
- 'sources': [
- 'examples/view_manager/view_manager.mojom',
- ],
- 'variables': {
- 'mojom_base_output_dir': 'mojo',
- },
- 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
- 'export_dependent_settings': [
- 'mojo_bindings',
- ],
- 'dependencies': [
- 'mojo_bindings',
- ],
- },
- {
- 'target_name': 'mojo_view_manager',
+ 'target_name': 'mojo_sample_view_manager_app',
'type': 'shared_library',
'dependencies': [
'../base/base.gyp:base',
+ '../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
- 'mojo_common_lib',
- 'mojo_environment_chromium',
- 'mojo_launcher_bindings',
- 'mojo_native_viewport_bindings',
- 'mojo_shell_client',
- 'mojo_system_impl',
+ '../ui/gl/gl.gyp:gl',
+ 'mojo_bindings',
+ 'mojo_environment_standalone',
+ 'mojo_gles2',
'mojo_view_manager_bindings',
+ 'mojo_shell_client',
+ 'mojo_system',
+ 'mojo_utility',
],
'sources': [
- 'examples/view_manager/view_manager.cc',
+ 'examples/sample_view_manager_app/sample_view_manager_app.cc',
],
},
- {
- 'target_name': 'package_mojo_view_manager',
- 'variables': {
- 'app_name': 'mojo_view_manager',
- },
- 'includes': [ 'build/package_app.gypi' ],
- },
],
}],
],
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-arm.mk b/mojo/mojo_js_bindings_lib.target.darwin-arm.mk
index e6d62904d8..447aa89258 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-arm.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-arm.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -231,7 +232,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-mips.mk b/mojo/mojo_js_bindings_lib.target.darwin-mips.mk
index fbe094e163..41c997a6ff 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-mips.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-mips.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -227,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-x86.mk b/mojo/mojo_js_bindings_lib.target.darwin-x86.mk
index e7af031fa6..d5cf56fe93 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-x86.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-x86.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -229,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk b/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk
index 729edf8a01..8252f697f5 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -229,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.linux-arm.mk b/mojo/mojo_js_bindings_lib.target.linux-arm.mk
index e6d62904d8..447aa89258 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-arm.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-arm.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -231,7 +232,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.linux-mips.mk b/mojo/mojo_js_bindings_lib.target.linux-mips.mk
index fbe094e163..41c997a6ff 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-mips.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-mips.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -227,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.linux-x86.mk b/mojo/mojo_js_bindings_lib.target.linux-x86.mk
index e7af031fa6..d5cf56fe93 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-x86.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-x86.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -229,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk b/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk
index 729edf8a01..8252f697f5 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
mojo/bindings/js/core.cc \
mojo/bindings/js/handle.cc \
mojo/bindings/js/support.cc \
+ mojo/bindings/js/unicode.cc \
mojo/bindings/js/waiting_callback.cc
@@ -229,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_public.gypi b/mojo/mojo_public.gypi
index 15eccb0c7e..7f9c2f7c16 100644
--- a/mojo/mojo_public.gypi
+++ b/mojo/mojo_public.gypi
@@ -14,8 +14,18 @@
'..',
],
},
+ 'all_dependent_settings': {
+ 'conditions': [
+ # We need to be able to call the MojoSetSystemThunks() function in
+ # system_thunks.cc
+ ['OS=="android"', {
+ 'ldflags!': [
+ '-Wl,--exclude-libs=ALL',
+ ],
+ }],
+ ],
+ },
'sources': [
- 'public/c/system/async_waiter.h',
'public/c/system/core.h',
'public/c/system/macros.h',
'public/c/system/system_export.h',
@@ -111,7 +121,7 @@
'mojo_environment_standalone',
'mojo_public_test_utils',
'mojo_run_all_unittests',
- 'mojo_sample_service',
+ 'mojo_public_test_interfaces',
'mojo_utility',
],
'sources': [
@@ -124,15 +134,7 @@
'public/cpp/bindings/tests/router_unittest.cc',
'public/cpp/bindings/tests/sample_service_unittest.cc',
'public/cpp/bindings/tests/type_conversion_unittest.cc',
- 'public/interfaces/bindings/tests/math_calculator.mojom',
- 'public/interfaces/bindings/tests/sample_factory.mojom',
- 'public/interfaces/bindings/tests/sample_interfaces.mojom',
- 'public/interfaces/bindings/tests/test_structs.mojom',
],
- 'variables': {
- 'mojom_base_output_dir': 'mojo',
- },
- 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
},
{
'target_name': 'mojo_public_environment_unittests',
@@ -256,12 +258,16 @@
],
},
{
- 'target_name': 'mojo_sample_service',
+ 'target_name': 'mojo_public_test_interfaces',
'type': 'static_library',
'sources': [
- 'public/interfaces/bindings/tests/sample_service.mojom',
+ 'public/interfaces/bindings/tests/math_calculator.mojom',
+ 'public/interfaces/bindings/tests/sample_factory.mojom',
'public/interfaces/bindings/tests/sample_import.mojom',
'public/interfaces/bindings/tests/sample_import2.mojom',
+ 'public/interfaces/bindings/tests/sample_interfaces.mojom',
+ 'public/interfaces/bindings/tests/sample_service.mojom',
+ 'public/interfaces/bindings/tests/test_structs.mojom',
],
'variables': {
'mojom_base_output_dir': 'mojo',
@@ -354,4 +360,18 @@
],
},
],
+ 'conditions': [
+ ['OS == "android"', {
+ 'targets': [
+ {
+ 'target_name': 'mojo_public_java',
+ 'type': 'none',
+ 'variables': {
+ 'java_in_dir': 'public/java',
+ },
+ 'includes': [ '../build/java.gypi' ],
+ },
+ ],
+ }],
+ ],
}
diff --git a/mojo/mojo_service_manager.target.darwin-arm.mk b/mojo/mojo_service_manager.target.darwin-arm.mk
index 29faa1c09f..b90703cdf7 100644
--- a/mojo/mojo_service_manager.target.darwin-arm.mk
+++ b/mojo/mojo_service_manager.target.darwin-arm.mk
@@ -232,7 +232,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.darwin-mips.mk b/mojo/mojo_service_manager.target.darwin-mips.mk
index 705c431d0e..3fe9c8274e 100644
--- a/mojo/mojo_service_manager.target.darwin-mips.mk
+++ b/mojo/mojo_service_manager.target.darwin-mips.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.darwin-x86.mk b/mojo/mojo_service_manager.target.darwin-x86.mk
index bcf69b8672..d953c977f2 100644
--- a/mojo/mojo_service_manager.target.darwin-x86.mk
+++ b/mojo/mojo_service_manager.target.darwin-x86.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.darwin-x86_64.mk b/mojo/mojo_service_manager.target.darwin-x86_64.mk
index 1074db399d..4868f8333d 100644
--- a/mojo/mojo_service_manager.target.darwin-x86_64.mk
+++ b/mojo/mojo_service_manager.target.darwin-x86_64.mk
@@ -230,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.linux-arm.mk b/mojo/mojo_service_manager.target.linux-arm.mk
index 29faa1c09f..b90703cdf7 100644
--- a/mojo/mojo_service_manager.target.linux-arm.mk
+++ b/mojo/mojo_service_manager.target.linux-arm.mk
@@ -232,7 +232,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.linux-mips.mk b/mojo/mojo_service_manager.target.linux-mips.mk
index 705c431d0e..3fe9c8274e 100644
--- a/mojo/mojo_service_manager.target.linux-mips.mk
+++ b/mojo/mojo_service_manager.target.linux-mips.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.linux-x86.mk b/mojo/mojo_service_manager.target.linux-x86.mk
index bcf69b8672..d953c977f2 100644
--- a/mojo/mojo_service_manager.target.linux-x86.mk
+++ b/mojo/mojo_service_manager.target.linux-x86.mk
@@ -228,7 +228,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_service_manager.target.linux-x86_64.mk b/mojo/mojo_service_manager.target.linux-x86_64.mk
index 1074db399d..4868f8333d 100644
--- a/mojo/mojo_service_manager.target.linux-x86_64.mk
+++ b/mojo/mojo_service_manager.target.linux-x86_64.mk
@@ -230,7 +230,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi
index 208f14bbca..3911a21856 100644
--- a/mojo/mojo_services.gypi
+++ b/mojo/mojo_services.gypi
@@ -60,7 +60,8 @@
},
{
'target_name': 'mojo_native_viewport_service',
- 'type': 'shared_library',
+ # This is linked directly into the embedder, so we make it a component.
+ 'type': '<(component)',
'dependencies': [
'../base/base.gyp:base',
'../ui/events/events.gyp:events',
@@ -100,5 +101,124 @@
}],
],
},
+ {
+ 'target_name': 'mojo_view_manager_lib',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'sources': [
+ 'services/public/cpp/view_manager/lib/view.cc',
+ 'services/public/cpp/view_manager/lib/view_manager.cc',
+ 'services/public/cpp/view_manager/lib/view_tree_host.cc',
+ 'services/public/cpp/view_manager/lib/view_tree_node.cc',
+ 'services/public/cpp/view_manager/lib/view_tree_node_observer.cc',
+ 'services/public/cpp/view_manager/lib/view_tree_node_private.cc',
+ 'services/public/cpp/view_manager/lib/view_tree_node_private.h',
+ 'services/public/cpp/view_manager/view.h',
+ 'services/public/cpp/view_manager/view_manager.h',
+ 'services/public/cpp/view_manager/view_tree_host.h',
+ 'services/public/cpp/view_manager/view_tree_node.h',
+ 'services/public/cpp/view_manager/view_tree_node_observer.h',
+ ],
+ },
+ {
+ 'target_name': 'mojo_view_manager_lib_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../base/base.gyp:test_support_base',
+ '../testing/gtest.gyp:gtest',
+ 'mojo_run_all_unittests',
+ 'mojo_view_manager_lib',
+ ],
+ 'sources': [
+ 'services/public/cpp/view_manager/tests/view_unittest.cc',
+ 'services/public/cpp/view_manager/tests/view_manager_unittest.cc',
+ 'services/public/cpp/view_manager/tests/view_tree_host_unittest.cc',
+ 'services/public/cpp/view_manager/tests/view_tree_node_unittest.cc',
+ ],
+ },
+ ],
+ 'conditions': [
+ ['use_aura==1', {
+ 'targets': [
+ {
+ 'target_name': 'mojo_view_manager_bindings',
+ 'type': 'static_library',
+ 'sources': [
+ 'services/public/interfaces/view_manager/view_manager.mojom',
+ ],
+ 'variables': {
+ 'mojom_base_output_dir': 'mojo',
+ },
+ 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
+ 'export_dependent_settings': [
+ 'mojo_bindings',
+ ],
+ 'dependencies': [
+ 'mojo_bindings',
+ ],
+ },
+ {
+ 'target_name': 'mojo_view_manager',
+ 'type': '<(component)',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../skia/skia.gyp:skia',
+ '../ui/aura/aura.gyp:aura',
+ '../ui/gfx/gfx.gyp:gfx_geometry',
+ 'mojo_common_lib',
+ 'mojo_environment_chromium',
+ 'mojo_launcher_bindings',
+ 'mojo_native_viewport_bindings',
+ 'mojo_shell_client',
+ 'mojo_system_impl',
+ 'mojo_view_manager_bindings',
+ ],
+ 'sources': [
+ 'services/view_manager/ids.h',
+ 'services/view_manager/node.cc',
+ 'services/view_manager/node.h',
+ 'services/view_manager/node_delegate.h',
+ 'services/view_manager/root_node_manager.cc',
+ 'services/view_manager/root_node_manager.h',
+ 'services/view_manager/view_manager.cc',
+ 'services/view_manager/view_manager_connection.cc',
+ 'services/view_manager/view_manager_connection.h',
+ 'services/view_manager/view_manager_export.h',
+ ],
+ 'defines': [
+ 'MOJO_VIEW_MANAGER_IMPLEMENTATION',
+ ],
+ },
+ {
+ 'target_name': 'mojo_view_manager_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../skia/skia.gyp:skia',
+ '../testing/gtest.gyp:gtest',
+ '../ui/aura/aura.gyp:aura',
+ 'mojo_environment_chromium',
+ 'mojo_run_all_unittests',
+ 'mojo_shell_client',
+ 'mojo_system_impl',
+ 'mojo_view_manager',
+ 'mojo_view_manager_bindings',
+ ],
+ 'sources': [
+ 'services/view_manager/view_manager_connection_unittest.cc',
+ ],
+ },
+ {
+ 'target_name': 'package_mojo_view_manager',
+ 'variables': {
+ 'app_name': 'mojo_view_manager',
+ },
+ 'includes': [ 'build/package_app.gypi' ],
+ },
+ ],
+ }],
],
}
diff --git a/mojo/mojo_shell_bindings.target.darwin-arm.mk b/mojo/mojo_shell_bindings.target.darwin-arm.mk
index 34e065264d..fd24e3b38b 100644
--- a/mojo/mojo_shell_bindings.target.darwin-arm.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-arm.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -244,7 +244,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.darwin-mips.mk b/mojo/mojo_shell_bindings.target.darwin-mips.mk
index dcb5ada33e..3488379fd6 100644
--- a/mojo/mojo_shell_bindings.target.darwin-mips.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-mips.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -240,7 +240,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.darwin-x86.mk b/mojo/mojo_shell_bindings.target.darwin-x86.mk
index 154618ab57..7594e6f5c0 100644
--- a/mojo/mojo_shell_bindings.target.darwin-x86.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-x86.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -242,7 +242,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.darwin-x86_64.mk b/mojo/mojo_shell_bindings.target.darwin-x86_64.mk
index b95ff6b4e5..b2d097e4a2 100644
--- a/mojo/mojo_shell_bindings.target.darwin-x86_64.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-x86_64.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -242,7 +242,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.linux-arm.mk b/mojo/mojo_shell_bindings.target.linux-arm.mk
index 34e065264d..fd24e3b38b 100644
--- a/mojo/mojo_shell_bindings.target.linux-arm.mk
+++ b/mojo/mojo_shell_bindings.target.linux-arm.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -244,7 +244,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.linux-mips.mk b/mojo/mojo_shell_bindings.target.linux-mips.mk
index dcb5ada33e..3488379fd6 100644
--- a/mojo/mojo_shell_bindings.target.linux-mips.mk
+++ b/mojo/mojo_shell_bindings.target.linux-mips.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -240,7 +240,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.linux-x86.mk b/mojo/mojo_shell_bindings.target.linux-x86.mk
index 154618ab57..7594e6f5c0 100644
--- a/mojo/mojo_shell_bindings.target.linux-x86.mk
+++ b/mojo/mojo_shell_bindings.target.linux-x86.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -242,7 +242,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_shell_bindings.target.linux-x86_64.mk b/mojo/mojo_shell_bindings.target.linux-x86_64.mk
index b95ff6b4e5..b2d097e4a2 100644
--- a/mojo/mojo_shell_bindings.target.linux-x86_64.mk
+++ b/mojo/mojo_shell_bindings.target.linux-x86_64.mk
@@ -15,12 +15,12 @@ GYP_TARGET_DEPENDENCIES :=
### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/parse/__init__.py', '../mojo/public/tools/bindings/pylib/parse/mojo_lexer.py', '../mojo/public/tools/bindings/pylib/parse/mojo_parser.py', '../mojo/public/tools/bindings/pylib/parse/mojo_translate.py', '../mojo/public/tools/bindings/pylib/generate/__init__.py', '../mojo/public/tools/bindings/pylib/generate/mojom.py', '../mojo/public/tools/bindings/pylib/generate/mojom_data.py', '../mojo/public/tools/bindings/pylib/generate/mojom_generator.py', '../mojo/public/tools/bindings/pylib/generate/mojom_pack.py', '../mojo/public/tools/bindings/pylib/generate/template_expander.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/generate/template_expander.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: $(LOCAL_PATH)/mojo/public/interfaces/shell/shell.mojom $(LOCAL_PATH)/mojo/public/tools/bindings/mojom_bindings_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/generators/mojom_js_generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py $(LOCAL_PATH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py $(GYP_TARGET_DEPENDENCIES)
mkdir -p $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell; cd $(gyp_local_path)/mojo; python ../mojo/public/tools/bindings/mojom_bindings_generator.py public/interfaces/shell/shell.mojom -d .. -o "$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell"
$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.h: $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc ;
@@ -242,7 +242,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.darwin-arm.mk b/mojo/mojo_system_impl.target.darwin-arm.mk
index 5337403863..cea7e9507c 100644
--- a/mojo/mojo_system_impl.target.darwin-arm.mk
+++ b/mojo/mojo_system_impl.target.darwin-arm.mk
@@ -256,7 +256,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.darwin-mips.mk b/mojo/mojo_system_impl.target.darwin-mips.mk
index 6c230facd6..a1cb2a9d1e 100644
--- a/mojo/mojo_system_impl.target.darwin-mips.mk
+++ b/mojo/mojo_system_impl.target.darwin-mips.mk
@@ -252,7 +252,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.darwin-x86.mk b/mojo/mojo_system_impl.target.darwin-x86.mk
index 31241a66d4..c78af2fcbf 100644
--- a/mojo/mojo_system_impl.target.darwin-x86.mk
+++ b/mojo/mojo_system_impl.target.darwin-x86.mk
@@ -254,7 +254,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.darwin-x86_64.mk b/mojo/mojo_system_impl.target.darwin-x86_64.mk
index dd4dc4933c..a9bc33b168 100644
--- a/mojo/mojo_system_impl.target.darwin-x86_64.mk
+++ b/mojo/mojo_system_impl.target.darwin-x86_64.mk
@@ -254,7 +254,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.linux-arm.mk b/mojo/mojo_system_impl.target.linux-arm.mk
index 5337403863..cea7e9507c 100644
--- a/mojo/mojo_system_impl.target.linux-arm.mk
+++ b/mojo/mojo_system_impl.target.linux-arm.mk
@@ -256,7 +256,6 @@ LOCAL_LDFLAGS_Debug := \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.linux-mips.mk b/mojo/mojo_system_impl.target.linux-mips.mk
index 6c230facd6..a1cb2a9d1e 100644
--- a/mojo/mojo_system_impl.target.linux-mips.mk
+++ b/mojo/mojo_system_impl.target.linux-mips.mk
@@ -252,7 +252,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.linux-x86.mk b/mojo/mojo_system_impl.target.linux-x86.mk
index 31241a66d4..c78af2fcbf 100644
--- a/mojo/mojo_system_impl.target.linux-x86.mk
+++ b/mojo/mojo_system_impl.target.linux-x86.mk
@@ -254,7 +254,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/mojo_system_impl.target.linux-x86_64.mk b/mojo/mojo_system_impl.target.linux-x86_64.mk
index dd4dc4933c..a9bc33b168 100644
--- a/mojo/mojo_system_impl.target.linux-x86_64.mk
+++ b/mojo/mojo_system_impl.target.linux-x86_64.mk
@@ -254,7 +254,6 @@ LOCAL_LDFLAGS_Debug := \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
- -Wl,--gc-sections \
-Wl,--warn-shared-textrel \
-Wl,-O1 \
-Wl,--as-needed
diff --git a/mojo/public/README.md b/mojo/public/README.md
index 32fc4b1861..a31a8a8245 100644
--- a/mojo/public/README.md
+++ b/mojo/public/README.md
@@ -1,62 +1,43 @@
Mojo Public API
===============
-The Mojo Public API is a binary stable API to the Mojo system. There are
-several components to the API:
+The Mojo Public API is a binary stable API to the Mojo system.
-Bindings
---------
-
-This directory contains a static library that clients may link into their
-binary. The contents of this directory are not binary stable as each client is
-free to use whichever version they prefer.
+It consists of support for a number of programming languages (with a directory
+for each support language), some "build" tools and build-time requirements, and
+interface definitions for Mojo services (specified using an IDL).
-This directory also contains a compiler that translates mojom interface
-definition files into idiomatic bindings for various languages, including
-C++ and JavaScript. Clients are expected to statically link with the generated
-code, which reads and writes the binary stable IPC message format.
+Note that there are various subdirectories named tests/. These contain tests of
+the code in the enclosing directory, and are not meant for use by Mojo
+applications.
-Environment
------------
+C/CPP/JS
+--------
-This directory contains a static library that clients may link into their
-binary. The contents of this directory are not binary stable as each client is
-free to use whichever version they prefer.
+The c/, cpp/, js/ subdirectories define the API for C, C++, and JavaScript,
+respectively.
-The environment static library represents the shared state that is needed to
-support the Bindings and GLES2 libraries. It depends on the Utility library.
+The basic principle for these directories is that they consist of the source
+files that one needs at build/deployment/run time (as appropriate for the
+language), organized in a natural way for the particular language.
-GLES2
------
+Interfaces
+----------
-The IPC protocol used to communicate between Mojo client and the GLES2
-service is not binary stable. To insulate themselves from changes in this
-protocol, clients are expected to link dynamically against the standard GLES2
-headers from Khronos and the headers in this directory, which provide an
-adaptor between the GLES2 C API and the underlying IPC protocol.
+The interfaces/ subdirectory contains Mojo IDL (a.k.a. .mojom) descriptions of
+standard Mojo services.
-System
-------
+Platform
+--------
-This directory defines the interface between Mojo clients and the Mojo IPC
-system. Although the Mojo IPC message format is binary stable, the mechanism
-by which these messages are transported is not stable. To insulate themselves
-from changes in the underlying transport, clients are expected to link against
-these headers dynamically.
+The platform/ subdirectory contains any build-time requirements (e.g., static
+libraries) that may be needed to produce a Mojo application for certain
+platforms, such as a native shared library or as a NaCl binary.
-Tests
+Tools
-----
-This directory contains tests for code contained in the public API. Mojo
-clients are expected to ignore this directory.
-
-Utility
--------
-
-This directory contains a static library that clients may link into their
-binary. The contents of this directory are not binary stable as each client is
-free to use whichever version they prefer.
-
-The Utility static library most notably defines an implementation of a RunLoop
-based on the MojoWaitMany that clients may use as the basis for asynchronous
-message processing.
+The tools/ subdirectory contains tools that are useful/necessary at
+build/deployment time. These tools may be needed (as a practical necessity) to
+use the API in any given language, e.g., to generate bindings from Mojo IDL
+files.
diff --git a/mojo/public/c/README.md b/mojo/public/c/README.md
new file mode 100644
index 0000000000..8e11545deb
--- /dev/null
+++ b/mojo/public/c/README.md
@@ -0,0 +1,45 @@
+Mojo Public C API
+=================
+
+This directory contains C language bindings for the Mojo Public API.
+
+Environment
+-----------
+
+The environment/ subdirectory defines some common things that, while not part of
+the system API, may be required for GLES2 (for example). These are things that a
+Mojo application may be required to provide to the GLES2 (for example) library
+in order to use it. (However, the Mojo application may implement these things as
+it sees fit.)
+
+GLES2
+-----
+
+The gles2/ subdirectory defines the GLES2 C API that's available to Mojo
+applications. To use GLES2, Mojo applications must link against a dynamic
+library (the exact mechanism being platform-dependent) and use the header files
+in this directory as well as the standard Khronos GLES2 header files.
+
+The reason for this, rather than providing GLES2 using the standard Mojo IPC
+mechanism, is performance: The protocol (and transport mechanisms) used to
+communicate with the Mojo GLES2 service is not stable nor "public" (mainly for
+performance reasons), and using the dynamic library shields the application from
+changes to the underlying system.
+
+System
+------
+
+The system/ subdirectory provides definitions of the basic low-level API used by
+all Mojo applications (whether directly or indirectly). These consist primarily
+of the IPC primitives used to communicate with Mojo services.
+
+Though the message protocol is stable, the implementation of the transport is
+not, and access to the IPC mechanisms must be via the primitives defined in this
+directory.
+
+Test Support
+------------
+
+This directory contains a C API for running tests. This API is only available
+under special, specific test conditions. It is not meant for general use by Mojo
+applications.
diff --git a/mojo/public/c/system/async_waiter.h b/mojo/public/c/environment/async_waiter.h
index ab999a3bd5..05689543b5 100644
--- a/mojo/public/c/system/async_waiter.h
+++ b/mojo/public/c/environment/async_waiter.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 MOJO_PUBLIC_C_SYSTEM_ASYNC_WAITER_H_
-#define MOJO_PUBLIC_C_SYSTEM_ASYNC_WAITER_H_
+#ifndef MOJO_PUBLIC_C_ENVIRONMENT_ASYNC_WAITER_H_
+#define MOJO_PUBLIC_C_ENVIRONMENT_ASYNC_WAITER_H_
#include "mojo/public/c/system/core.h"
@@ -37,4 +37,4 @@ struct MojoAsyncWaiter {
} // extern "C"
#endif
-#endif // MOJO_PUBLIC_C_SYSTEM_ASYNC_WAITER_H_
+#endif // MOJO_PUBLIC_C_ENVIRONMENT_ASYNC_WAITER_H_
diff --git a/mojo/public/c/gles2/DEPS b/mojo/public/c/gles2/DEPS
new file mode 100644
index 0000000000..3887457940
--- /dev/null
+++ b/mojo/public/c/gles2/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+mojo/public/c/environment",
+]
diff --git a/mojo/public/c/gles2/gles2.h b/mojo/public/c/gles2/gles2.h
index 6b20b9c596..3ee249d5aa 100644
--- a/mojo/public/c/gles2/gles2.h
+++ b/mojo/public/c/gles2/gles2.h
@@ -10,9 +10,9 @@
#include <stdint.h>
#include <GLES2/gl2.h>
+#include "mojo/public/c/environment/async_waiter.h"
#include "mojo/public/c/gles2/gles2_export.h"
#include "mojo/public/c/gles2/gles2_types.h"
-#include "mojo/public/c/system/async_waiter.h"
#include "mojo/public/c/system/core.h"
#ifdef __cplusplus
diff --git a/mojo/public/c/system/tests/core_unittest_pure_c.c b/mojo/public/c/system/tests/core_unittest_pure_c.c
index 7293ff2d65..a95af50d17 100644
--- a/mojo/public/c/system/tests/core_unittest_pure_c.c
+++ b/mojo/public/c/system/tests/core_unittest_pure_c.c
@@ -11,8 +11,8 @@
// Include all the header files that are meant to be compilable as C. Start with
// core.h, since it's the most important one.
+#include "mojo/public/c/environment/async_waiter.h"
#include "mojo/public/c/system/core.h"
-#include "mojo/public/c/system/async_waiter.h"
#include "mojo/public/c/system/macros.h"
// The joys of the C preprocessor....
diff --git a/mojo/public/cpp/README.md b/mojo/public/cpp/README.md
new file mode 100644
index 0000000000..8f03d984b9
--- /dev/null
+++ b/mojo/public/cpp/README.md
@@ -0,0 +1,71 @@
+Mojo Public C++ API
+===================
+
+This directory contains C++ language bindings for the Mojo Public API.
+
+A number of subdirectories provide wrappers for the lower-level C APIs (in
+subdirectories of the same name, under mojo/public/c/). Typically, these
+wrappers provide increased convenience and/or type-safety.
+
+Other subdirectories provide support (static) libraries of various sorts. In
+this case, the organization is to have the public interface for the library in
+defined in header files in the subdirectory itself and the implementation of the
+library at a lower level, under a lib (sub)subdirectory. A developer should be
+able to substitute their own implementation of any such support library, and
+expect other support libraries, which may depend on that library, to work
+properly.
+
+Bindings
+--------
+
+The bindings/ subdirectory contains a support (static) library needed by the
+code generated by the bindings generator tool (in mojo/public/tools/bindings/),
+which translates Mojo IDL (.mojom) files into idiomatic C++ (among other
+languages).
+
+This library depends on the Environment library.
+
+Environment
+-----------
+
+The environment/ subdirectory contains a support (static) library that
+represents shared state needed to support the Bindings and GLES2 libraries.
+
+This library depends on the Utility library.
+
+
+GLES2
+-----
+
+The gles2/ subdirectory contains C++ wrappers (and some additional helpers) of
+the API defined in mojo/public/c/gles2/ (which provides access to GLES2).
+
+These wrappers depend on the Environment library.
+
+Shell
+-----
+
+The shell/ subdirectory contains a support (static) library that aids in writing
+Mojo applications and interacting with the Shell service.
+
+System
+------
+
+The system/ subdirectory contains C++ wrappers (and some additional helpers) of
+the API defined in mojo/public/c/system/, which defines the basic, "core" API,
+especially used to communicate with Mojo services.
+
+Test Support
+------------
+
+The test_support/ subdirectory contains C++ wrappers of the test-only API
+defined in mojo/public/c/test_support/. It is not meant for general use by Mojo
+applications.
+
+Utility
+-------
+
+The utility/ subdirectory contains a support (static) library that provides
+various basic functionality. Most notably, it provides an implementation of a
+RunLoop based on MojoWaitMany() that applications may use as the basis for
+asynchronous message processing.
diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h
index 72aa56de58..f7ced01aa8 100644
--- a/mojo/public/cpp/bindings/array.h
+++ b/mojo/public/cpp/bindings/array.h
@@ -20,7 +20,9 @@ namespace mojo {
template <typename T>
class Array {
public:
- typedef internal::ArrayTraits<T, internal::TypeTraits<T>::kIsObject> Traits_;
+ typedef internal::ArrayTraits<T,
+ internal::TypeTraits<T>::kIsObject,
+ internal::TypeTraits<T>::kIsHandle> Traits_;
typedef typename Traits_::DataType Data;
typedef typename Traits_::ConstRef ConstRef;
@@ -65,7 +67,7 @@ class Array {
typedef typename Traits_::Ref Ref;
explicit Builder(size_t num_elements, Buffer* buf = mojo::Buffer::current())
- : data_(Data::New(num_elements, buf)) {
+ : data_(Data::New(num_elements, buf, Traits_::GetDestructor())) {
}
size_t size() const { return data_->size(); }
diff --git a/mojo/public/cpp/bindings/lib/array_internal.cc b/mojo/public/cpp/bindings/lib/array_internal.cc
index efdda8c810..1852ff73ce 100644
--- a/mojo/public/cpp/bindings/lib/array_internal.cc
+++ b/mojo/public/cpp/bindings/lib/array_internal.cc
@@ -35,7 +35,25 @@ ArrayDataTraits<bool>::BitRef::operator bool() const {
}
// static
-void ArraySerializationHelper<Handle>::EncodePointersAndHandles(
+void ArraySerializationHelper<Handle, true>::ClearHandles(
+ const ArrayHeader* header,
+ ElementType* elements) {
+ for (uint32_t i = 0; i < header->num_elements; ++i)
+ elements[i].set_value(MOJO_HANDLE_INVALID);
+}
+
+// static
+void ArraySerializationHelper<Handle, true>::CloseHandles(
+ const ArrayHeader* header,
+ ElementType* elements) {
+ for (uint32_t i = 0; i < header->num_elements; ++i) {
+ if (elements[i].is_valid())
+ CloseRaw(elements[i]);
+ }
+}
+
+// static
+void ArraySerializationHelper<Handle, true>::EncodePointersAndHandles(
const ArrayHeader* header,
ElementType* elements,
std::vector<Handle>* handles) {
@@ -44,7 +62,7 @@ void ArraySerializationHelper<Handle>::EncodePointersAndHandles(
}
// static
-bool ArraySerializationHelper<Handle>::DecodePointersAndHandles(
+bool ArraySerializationHelper<Handle, true>::DecodePointersAndHandles(
const ArrayHeader* header,
ElementType* elements,
Message* message) {
diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h
index 978dca36a4..4ecad35591 100644
--- a/mojo/public/cpp/bindings/lib/array_internal.h
+++ b/mojo/public/cpp/bindings/lib/array_internal.h
@@ -8,10 +8,10 @@
#include <new>
#include "mojo/public/cpp/bindings/buffer.h"
+#include "mojo/public/cpp/bindings/interface.h"
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
#include "mojo/public/cpp/bindings/passable.h"
-#include "mojo/public/cpp/system/core.h"
namespace mojo {
template <typename T> class Array;
@@ -97,9 +97,11 @@ struct ArrayDataTraits<bool> {
// are two interesting cases: arrays of primitives and arrays of objects.
// Arrays of objects are represented as arrays of pointers to objects.
+template <typename T, bool kIsHandle> struct ArraySerializationHelper;
+
template <typename T>
-struct ArraySerializationHelper {
- typedef T ElementType;
+struct ArraySerializationHelper<T, false> {
+ typedef typename ArrayDataTraits<T>::StorageType ElementType;
static size_t ComputeSizeOfElements(const ArrayHeader* header,
const ElementType* elements) {
@@ -111,6 +113,13 @@ struct ArraySerializationHelper {
Buffer* buf) {
}
+ static void ClearHandles(const ArrayHeader* header, ElementType* elements) {
+ }
+
+ static void CloseHandles(const ArrayHeader* header,
+ ElementType* elements) {
+ }
+
static void EncodePointersAndHandles(const ArrayHeader* header,
ElementType* elements,
std::vector<Handle>* handles) {
@@ -124,8 +133,8 @@ struct ArraySerializationHelper {
};
template <>
-struct ArraySerializationHelper<Handle> {
- typedef Handle ElementType;
+struct ArraySerializationHelper<Handle, true> {
+ typedef ArrayDataTraits<Handle>::StorageType ElementType;
static size_t ComputeSizeOfElements(const ArrayHeader* header,
const ElementType* elements) {
@@ -137,6 +146,10 @@ struct ArraySerializationHelper<Handle> {
Buffer* buf) {
}
+ static void ClearHandles(const ArrayHeader* header, ElementType* elements);
+
+ static void CloseHandles(const ArrayHeader* header, ElementType* elements);
+
static void EncodePointersAndHandles(const ArrayHeader* header,
ElementType* elements,
std::vector<Handle>* handles);
@@ -146,9 +159,46 @@ struct ArraySerializationHelper<Handle> {
Message* message);
};
+template <typename H>
+struct ArraySerializationHelper<H, true> {
+ typedef typename ArrayDataTraits<H>::StorageType ElementType;
+
+ static size_t ComputeSizeOfElements(const ArrayHeader* header,
+ const ElementType* elements) {
+ return 0;
+ }
+
+ static void CloneElements(const ArrayHeader* header,
+ ElementType* elements,
+ Buffer* buf) {
+ }
+
+ static void ClearHandles(const ArrayHeader* header, ElementType* elements) {
+ ArraySerializationHelper<Handle, true>::ClearHandles(header, elements);
+ }
+
+ static void CloseHandles(const ArrayHeader* header, ElementType* elements) {
+ ArraySerializationHelper<Handle, true>::CloseHandles(header, elements);
+ }
+
+ static void EncodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ std::vector<Handle>* handles) {
+ ArraySerializationHelper<Handle, true>::EncodePointersAndHandles(
+ header, elements, handles);
+ }
+
+ static bool DecodePointersAndHandles(const ArrayHeader* header,
+ ElementType* elements,
+ Message* message) {
+ return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles(
+ header, elements, message);
+ }
+};
+
template <typename P>
-struct ArraySerializationHelper<P*> {
- typedef StructPointer<P> ElementType;
+struct ArraySerializationHelper<P*, false> {
+ typedef typename ArrayDataTraits<P*>::StorageType ElementType;
static size_t ComputeSizeOfElements(const ArrayHeader* header,
const ElementType* elements) {
@@ -169,6 +219,17 @@ struct ArraySerializationHelper<P*> {
}
}
+ static void ClearHandles(const ArrayHeader* header, ElementType* elements) {
+ }
+
+ static void CloseHandles(const ArrayHeader* header,
+ ElementType* elements) {
+ for (uint32_t i = 0; i < header->num_elements; ++i) {
+ if (elements[i].ptr)
+ elements[i].ptr->CloseHandles();
+ }
+ }
+
static void EncodePointersAndHandles(const ArrayHeader* header,
ElementType* elements,
std::vector<Handle>* handles) {
@@ -195,12 +256,18 @@ class Array_Data {
typedef typename Traits::Wrapper Wrapper;
typedef typename Traits::Ref Ref;
typedef typename Traits::ConstRef ConstRef;
+ typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper;
- static Array_Data<T>* New(size_t num_elements, Buffer* buf) {
+ static Array_Data<T>* New(size_t num_elements, Buffer* buf,
+ Buffer::Destructor dtor = NULL) {
size_t num_bytes = sizeof(Array_Data<T>) +
Traits::GetStorageSize(num_elements);
- return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes,
- num_elements);
+ return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes,
+ num_elements);
+ }
+
+ static void Destructor(void* address) {
+ static_cast<Array_Data*>(address)->CloseHandles();
}
size_t size() const { return header_.num_elements; }
@@ -227,33 +294,32 @@ class Array_Data {
size_t ComputeSize() const {
return Align(header_.num_bytes) +
- ArraySerializationHelper<T>::ComputeSizeOfElements(&header_, storage());
+ Helper::ComputeSizeOfElements(&header_, storage());
}
- Array_Data<T>* Clone(Buffer* buf) const {
+ Array_Data<T>* Clone(Buffer* buf) {
Array_Data<T>* clone = New(header_.num_elements, buf);
memcpy(clone->storage(),
storage(),
header_.num_bytes - sizeof(Array_Data<T>));
+ Helper::CloneElements(&clone->header_, clone->storage(), buf);
- ArraySerializationHelper<T>::CloneElements(&clone->header_,
- clone->storage(), buf);
+ // Zero-out handles in the original storage as they have been transferred
+ // to the clone.
+ Helper::ClearHandles(&header_, storage());
return clone;
}
void CloseHandles() {
- // TODO(darin): Implement!
+ Helper::CloseHandles(&header_, storage());
}
void EncodePointersAndHandles(std::vector<Handle>* handles) {
- ArraySerializationHelper<T>::EncodePointersAndHandles(&header_, storage(),
- handles);
+ Helper::EncodePointersAndHandles(&header_, storage(), handles);
}
bool DecodePointersAndHandles(Message* message) {
- return ArraySerializationHelper<T>::DecodePointersAndHandles(&header_,
- storage(),
- message);
+ return Helper::DecodePointersAndHandles(&header_, storage(), message);
}
private:
@@ -272,12 +338,16 @@ MOJO_COMPILE_ASSERT(sizeof(Array_Data<char>) == 8, bad_sizeof_Array_Data);
// UTF-8 encoded
typedef Array_Data<char> String_Data;
-template <typename T, bool kIsObject> struct ArrayTraits {};
+template <typename T, bool kIsObject, bool kIsHandle> struct ArrayTraits {};
-template <typename T> struct ArrayTraits<T, true> {
+// When T is an object type:
+template <typename T> struct ArrayTraits<T, true, false> {
typedef Array_Data<typename T::Data*> DataType;
typedef const T& ConstRef;
typedef T& Ref;
+ static Buffer::Destructor GetDestructor() {
+ return NULL;
+ }
static typename T::Data* ToArrayElement(const T& value) {
return Unwrap(value);
}
@@ -290,10 +360,14 @@ template <typename T> struct ArrayTraits<T, true> {
}
};
-template <typename T> struct ArrayTraits<T, false> {
+// When T is a primitive (non-bool) type:
+template <typename T> struct ArrayTraits<T, false, false> {
typedef Array_Data<T> DataType;
typedef const T& ConstRef;
typedef T& Ref;
+ static Buffer::Destructor GetDestructor() {
+ return NULL;
+ }
static T ToArrayElement(const T& value) {
return value;
}
@@ -301,10 +375,14 @@ template <typename T> struct ArrayTraits<T, false> {
static ConstRef ToConstRef(const T& data) { return data; }
};
-template <> struct ArrayTraits<bool, false> {
+// When T is a bool type:
+template <> struct ArrayTraits<bool, false, false> {
typedef Array_Data<bool> DataType;
typedef bool ConstRef;
typedef ArrayDataTraits<bool>::Ref Ref;
+ static Buffer::Destructor GetDestructor() {
+ return NULL;
+ }
static bool ToArrayElement(const bool& value) {
return value;
}
@@ -312,57 +390,20 @@ template <> struct ArrayTraits<bool, false> {
static ConstRef ToConstRef(ConstRef data) { return data; }
};
-template <> struct ArrayTraits<Handle, false> {
- typedef Array_Data<Handle> DataType;
- typedef Passable<Handle> ConstRef;
- typedef AssignableAndPassable<Handle> Ref;
- static Handle ToArrayElement(const Handle& value) {
- return value;
- }
- static Ref ToRef(Handle& data) { return Ref(&data); }
- static ConstRef ToConstRef(const Handle& data) {
- return ConstRef(const_cast<Handle*>(&data));
- }
-};
-
-template <> struct ArrayTraits<DataPipeConsumerHandle, false> {
- typedef Array_Data<DataPipeConsumerHandle> DataType;
- typedef Passable<DataPipeConsumerHandle> ConstRef;
- typedef AssignableAndPassable<DataPipeConsumerHandle> Ref;
- static DataPipeConsumerHandle ToArrayElement(
- const DataPipeConsumerHandle& value) {
- return value;
- }
- static Ref ToRef(DataPipeConsumerHandle& data) { return Ref(&data); }
- static ConstRef ToConstRef(const DataPipeConsumerHandle& data) {
- return ConstRef(const_cast<DataPipeConsumerHandle*>(&data));
+// When T is a handle type:
+template <typename H> struct ArrayTraits<H, false, true> {
+ typedef Array_Data<H> DataType;
+ typedef Passable<H> ConstRef;
+ typedef AssignableAndPassable<H> Ref;
+ static Buffer::Destructor GetDestructor() {
+ return &DataType::Destructor;
}
-};
-
-template <> struct ArrayTraits<DataPipeProducerHandle, false> {
- typedef Array_Data<DataPipeProducerHandle> DataType;
- typedef Passable<DataPipeProducerHandle> ConstRef;
- typedef AssignableAndPassable<DataPipeProducerHandle> Ref;
- static DataPipeProducerHandle ToArrayElement(
- const DataPipeProducerHandle& value) {
- return value;
- }
- static Ref ToRef(DataPipeProducerHandle& data) { return Ref(&data); }
- static ConstRef ToConstRef(const DataPipeProducerHandle& data) {
- return ConstRef(const_cast<DataPipeProducerHandle*>(&data));
- }
-};
-
-template <> struct ArrayTraits<MessagePipeHandle, false> {
- typedef Array_Data<MessagePipeHandle> DataType;
- typedef Passable<MessagePipeHandle> ConstRef;
- typedef AssignableAndPassable<MessagePipeHandle> Ref;
- static MessagePipeHandle ToArrayElement(const MessagePipeHandle& value) {
+ static H ToArrayElement(const H& value) {
return value;
}
- static Ref ToRef(MessagePipeHandle& data) { return Ref(&data); }
- static ConstRef ToConstRef(const MessagePipeHandle& data) {
- return ConstRef(const_cast<MessagePipeHandle*>(&data));
+ static Ref ToRef(H& data) { return Ref(&data); }
+ static ConstRef ToConstRef(const H& data) {
+ return ConstRef(const_cast<H*>(&data));
}
};
diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h
index ef6fc47dc8..4b847e71e3 100644
--- a/mojo/public/cpp/bindings/lib/bindings_internal.h
+++ b/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -8,6 +8,8 @@
#include "mojo/public/cpp/system/core.h"
namespace mojo {
+template <typename S> class InterfaceHandle;
+
namespace internal {
template <typename T> class Array_Data;
@@ -82,54 +84,75 @@ inline typename T::Data* Unwrap(const T& object) {
}
template <typename T> struct TypeTraits {
+ static const bool kIsHandle = false;
static const bool kIsObject = true;
};
template <> struct TypeTraits<bool> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<char> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<int8_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<int16_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<int32_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<int64_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<uint8_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<uint16_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<uint32_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<uint64_t> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<float> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<double> {
+ static const bool kIsHandle = false;
static const bool kIsObject = false;
};
template <> struct TypeTraits<Handle> {
+ static const bool kIsHandle = true;
static const bool kIsObject = false;
};
template <> struct TypeTraits<DataPipeConsumerHandle> {
+ static const bool kIsHandle = true;
static const bool kIsObject = false;
};
template <> struct TypeTraits<DataPipeProducerHandle> {
+ static const bool kIsHandle = true;
static const bool kIsObject = false;
};
template <> struct TypeTraits<MessagePipeHandle> {
+ static const bool kIsHandle = true;
+ static const bool kIsObject = false;
+};
+template <typename S> struct TypeTraits<InterfaceHandle<S> > {
+ static const bool kIsHandle = true;
static const bool kIsObject = false;
};
diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/mojo/public/cpp/bindings/lib/bindings_serialization.cc
index ff06d95f83..fc574d77e7 100644
--- a/mojo/public/cpp/bindings/lib/bindings_serialization.cc
+++ b/mojo/public/cpp/bindings/lib/bindings_serialization.cc
@@ -37,7 +37,7 @@ const void* DecodePointerRaw(const uint64_t* offset) {
bool ValidatePointer(const void* ptr, const Message& message) {
const uint8_t* data = static_cast<const uint8_t*>(ptr);
- if (reinterpret_cast<ptrdiff_t>(data) % 8 != 0)
+ if (reinterpret_cast<uintptr_t>(data) % 8 != 0)
return false;
const uint8_t* data_start = message.data();
diff --git a/mojo/public/cpp/bindings/lib/shared_data.h b/mojo/public/cpp/bindings/lib/shared_data.h
index e396b0d795..bba4710910 100644
--- a/mojo/public/cpp/bindings/lib/shared_data.h
+++ b/mojo/public/cpp/bindings/lib/shared_data.h
@@ -32,6 +32,7 @@ class SharedData {
holder_->Release();
holder_ = other.holder_;
holder_->Retain();
+ return *this;
}
void reset() {
diff --git a/mojo/public/cpp/bindings/tests/array_unittest.cc b/mojo/public/cpp/bindings/tests/array_unittest.cc
index 72033eab29..dccd7167e9 100644
--- a/mojo/public/cpp/bindings/tests/array_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/array_unittest.cc
@@ -4,9 +4,11 @@
#include "mojo/public/cpp/bindings/allocation_scope.h"
#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/interface.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
#include "mojo/public/cpp/bindings/lib/scratch_buffer.h"
#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -84,6 +86,86 @@ TEST(ArrayTest, Handle) {
EXPECT_FALSE(handles[0].is_valid());
}
+// Tests that Array<Handle> supports closing handles.
+TEST(ArrayTest, HandlesAreClosed) {
+ Environment env;
+
+ ScopedMessagePipeHandle msg_pipe0, msg_pipe1;
+ CreateMessagePipe(&msg_pipe0, &msg_pipe1);
+
+ ScopedHandle pipe0 = ScopedHandle::From(msg_pipe0.Pass());
+ ScopedHandle pipe1 = ScopedHandle::From(msg_pipe1.Pass());
+
+ MojoHandle pipe0_value = pipe0.get().value();
+ MojoHandle pipe1_value = pipe1.get().value();
+
+ {
+ AllocationScope scope;
+
+ Array<Handle>::Builder handles_builder(2);
+ handles_builder[0] = pipe0.Pass();
+ handles_builder[1].reset(pipe1.release());
+
+ MOJO_ALLOW_UNUSED Array<Handle> handles =
+ handles_builder.Finish();
+ }
+
+ // We expect the pipes to have been closed.
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
+}
+
+// Tests that Array<MessagePipeHandle> supports closing handles.
+TEST(ArrayTest, MessagePipeHandlesAreClosed) {
+ Environment env;
+
+ ScopedMessagePipeHandle pipe0, pipe1;
+ CreateMessagePipe(&pipe0, &pipe1);
+
+ MojoHandle pipe0_value = pipe0.get().value();
+ MojoHandle pipe1_value = pipe1.get().value();
+
+ {
+ AllocationScope scope;
+
+ Array<MessagePipeHandle>::Builder handles_builder(2);
+ handles_builder[0] = pipe0.Pass();
+ handles_builder[1].reset(pipe1.release());
+
+ MOJO_ALLOW_UNUSED Array<MessagePipeHandle> handles =
+ handles_builder.Finish();
+ }
+
+ // We expect the pipes to have been closed.
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
+}
+
+// Tests that Array<InterfaceHandle<S>> supports closing handles.
+TEST(ArrayTest, InterfaceHandlesAreClosed) {
+ Environment env;
+
+ InterfacePipe<sample::Port, sample::Port> pipe;
+
+ MojoHandle pipe0_value = pipe.handle_to_self.get().value();
+ MojoHandle pipe1_value = pipe.handle_to_peer.get().value();
+
+ {
+ AllocationScope scope;
+
+ Array<sample::PortHandle>::Builder handles_builder(2);
+ handles_builder[0] = pipe.handle_to_self.Pass();
+ handles_builder[1].reset(pipe.handle_to_peer.release());
+
+ MOJO_ALLOW_UNUSED Array<sample::PortHandle> handles =
+ handles_builder.Finish();
+ }
+
+ // We expect the pipes to have been closed.
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
+}
+
} // namespace
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
index 23d8798462..7df6db6e02 100644
--- a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
@@ -231,6 +231,39 @@ TEST_F(HandlePassingTest, DataPipe) {
EXPECT_TRUE(factory_client.got_response());
}
+TEST_F(HandlePassingTest, PipesAreClosed) {
+ InterfacePipe<sample::Factory> pipe;
+ RemotePtr<sample::Factory> factory(pipe.handle_to_self.Pass(), NULL);
+
+ MessagePipe extra_pipe;
+
+ MojoHandle handle0_value = extra_pipe.handle0.get().value();
+ MojoHandle handle1_value = extra_pipe.handle1.get().value();
+
+ {
+ AllocationScope scope;
+
+ Array<MessagePipeHandle>::Builder pipes(2);
+ pipes[0] = extra_pipe.handle0.Pass();
+ pipes[1] = extra_pipe.handle1.Pass();
+
+ sample::Request::Builder request_builder;
+ request_builder.set_more_pipes(pipes.Finish());
+
+ sample::Request request = request_builder.Finish();
+
+ factory->DoStuff(request, ScopedMessagePipeHandle());
+
+ // The handles should have been transferred to the underlying Message.
+ EXPECT_EQ(MOJO_HANDLE_INVALID, request.more_pipes()[0].get().value());
+ EXPECT_EQ(MOJO_HANDLE_INVALID, request.more_pipes()[1].get().value());
+ }
+
+ // We expect the pipes to have been closed.
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value));
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value));
+}
+
} // namespace
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/request_response_unittest.cc b/mojo/public/cpp/bindings/tests/request_response_unittest.cc
index 9ca7cd4e89..94ed91ff87 100644
--- a/mojo/public/cpp/bindings/tests/request_response_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/request_response_unittest.cc
@@ -25,7 +25,10 @@ class ProviderImpl : public sample::Provider {
const String& a,
const Callback<void(String)>& callback) MOJO_OVERRIDE {
AllocationScope scope;
- callback.Run(a);
+ Callback<void(String)> callback_copy;
+ // Make sure operator= is used.
+ callback_copy = callback;
+ callback_copy.Run(a);
}
virtual void EchoStrings(
@@ -43,6 +46,12 @@ class ProviderImpl : public sample::Provider {
callback.Run(a.Pass());
}
+ virtual void EchoEnum(sample::Enum a,
+ const Callback<void(sample::Enum)>& callback)
+ MOJO_OVERRIDE {
+ callback.Run(a);
+ }
+
private:
RemotePtr<sample::ProviderClient> client_;
};
@@ -61,6 +70,17 @@ class StringRecorder {
std::string* buf_;
};
+class EnumRecorder {
+ public:
+ EnumRecorder(sample::Enum* value) : value_(value) {
+ }
+ void Run(sample::Enum a) const {
+ *value_ = a;
+ }
+ private:
+ sample::Enum* value_;
+};
+
class MessagePipeWriter {
public:
explicit MessagePipeWriter(const char* text) : text_(text) {
@@ -135,6 +155,22 @@ TEST_F(RequestResponseTest, EchoMessagePipeHandle) {
EXPECT_EQ(std::string("hello"), value);
}
+TEST_F(RequestResponseTest, EchoEnum) {
+ InterfacePipe<sample::Provider> pipe;
+ ProviderImpl provider_impl(pipe.handle_to_peer.Pass());
+ RemotePtr<sample::Provider> provider(pipe.handle_to_self.Pass(), NULL);
+
+ sample::Enum value;
+ {
+ AllocationScope scope;
+ provider->EchoEnum(sample::ENUM_VALUE, EnumRecorder(&value));
+ }
+
+ PumpMessages();
+
+ EXPECT_EQ(sample::ENUM_VALUE, value);
+}
+
} // namespace
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
index 75d0d9b3e2..05eca4486c 100644
--- a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
@@ -75,6 +75,15 @@ Foo MakeFoo() {
output_streams[i] = producer.Pass();
}
+ mojo::Array<mojo::Array<bool> >::Builder array_of_array_of_bools(2);
+ for (size_t i = 0; i < 2; ++i) {
+ mojo::Array<bool>::Builder array_of_bools(2);
+ for (size_t j = 0; j < 2; ++j) {
+ array_of_bools[j] = j;
+ }
+ array_of_array_of_bools[i] = array_of_bools.Finish();
+ }
+
mojo::ScopedMessagePipeHandle pipe0, pipe1;
mojo::CreateMessagePipe(&pipe0, &pipe1);
@@ -91,6 +100,7 @@ Foo MakeFoo() {
foo.set_source(pipe1.Pass());
foo.set_input_streams(input_streams.Finish());
foo.set_output_streams(output_streams.Finish());
+ foo.set_array_of_array_of_bools(array_of_array_of_bools.Finish());
return foo.Finish();
}
@@ -138,6 +148,14 @@ void CheckFoo(const Foo& foo) {
EXPECT_FALSE(foo.output_streams().is_null());
EXPECT_EQ(2u, foo.output_streams().size());
+
+ EXPECT_EQ(2u, foo.array_of_array_of_bools().size());
+ for (size_t i = 0; i < foo.array_of_array_of_bools().size(); ++i) {
+ EXPECT_EQ(2u, foo.array_of_array_of_bools()[i].size());
+ for (size_t j = 0; j < foo.array_of_array_of_bools()[i].size(); ++j) {
+ EXPECT_EQ(bool(j), foo.array_of_array_of_bools()[i][j]);
+ }
+ }
}
void PrintSpacer(int depth) {
@@ -222,6 +240,7 @@ void Print(int depth, const char* name, const Foo& foo) {
Print(depth, "source", foo.source().get());
Print(depth, "input_streams", foo.input_streams());
Print(depth, "output_streams", foo.output_streams());
+ Print(depth, "array_of_array_of_bools", foo.array_of_array_of_bools());
--depth;
}
}
diff --git a/mojo/public/cpp/environment/DEPS b/mojo/public/cpp/environment/DEPS
new file mode 100644
index 0000000000..3887457940
--- /dev/null
+++ b/mojo/public/cpp/environment/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+mojo/public/c/environment",
+]
diff --git a/mojo/public/cpp/environment/default_async_waiter.h b/mojo/public/cpp/environment/default_async_waiter.h
index d7f48bf529..6edfaaa0cf 100644
--- a/mojo/public/cpp/environment/default_async_waiter.h
+++ b/mojo/public/cpp/environment/default_async_waiter.h
@@ -5,7 +5,7 @@
#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_DEFAULT_ASYNC_WAITER_H_
#define MOJO_PUBLIC_CPP_ENVIRONMENT_DEFAULT_ASYNC_WAITER_H_
-#include "mojo/public/c/system/async_waiter.h"
+#include "mojo/public/c/environment/async_waiter.h"
namespace mojo {
diff --git a/mojo/public/cpp/shell/application.h b/mojo/public/cpp/shell/application.h
index 9a2ea67cba..ffca7fe682 100644
--- a/mojo/public/cpp/shell/application.h
+++ b/mojo/public/cpp/shell/application.h
@@ -14,18 +14,18 @@
namespace mojo {
-class Application : public internal::ServiceFactoryBase::Owner {
+class Application : public internal::ServiceConnectorBase::Owner {
public:
explicit Application(ScopedShellHandle shell_handle);
explicit Application(MojoHandle shell_handle);
virtual ~Application();
- // internal::ServiceFactoryBase::Owner methods.
- // Takes ownership of |service_factory|.
- virtual void AddServiceFactory(internal::ServiceFactoryBase* service_factory)
- MOJO_OVERRIDE;
- virtual void RemoveServiceFactory(
- internal::ServiceFactoryBase* service_factory) MOJO_OVERRIDE;
+ // internal::ServiceConnectorBase::Owner methods.
+ // Takes ownership of |service_connector|.
+ virtual void AddServiceConnector(
+ internal::ServiceConnectorBase* service_connector) MOJO_OVERRIDE;
+ virtual void RemoveServiceConnector(
+ internal::ServiceConnectorBase* service_connector) MOJO_OVERRIDE;
protected:
// ShellClient methods.
@@ -34,8 +34,8 @@ class Application : public internal::ServiceFactoryBase::Owner {
MOJO_OVERRIDE;
private:
- typedef std::vector<internal::ServiceFactoryBase*> ServiceFactoryList;
- ServiceFactoryList service_factories_;
+ typedef std::vector<internal::ServiceConnectorBase*> ServiceConnectorList;
+ ServiceConnectorList service_connectors_;
};
} // namespace mojo
diff --git a/mojo/public/cpp/shell/lib/application.cc b/mojo/public/cpp/shell/lib/application.cc
index 4d0b06f63f..3224202873 100644
--- a/mojo/public/cpp/shell/lib/application.cc
+++ b/mojo/public/cpp/shell/lib/application.cc
@@ -7,48 +7,48 @@
namespace mojo {
Application::Application(ScopedShellHandle shell_handle)
- : internal::ServiceFactoryBase::Owner(shell_handle.Pass()) {
+ : internal::ServiceConnectorBase::Owner(shell_handle.Pass()) {
}
Application::Application(MojoHandle shell_handle)
- : internal::ServiceFactoryBase::Owner(
+ : internal::ServiceConnectorBase::Owner(
mojo::MakeScopedHandle(ShellHandle(shell_handle)).Pass()) {}
Application::~Application() {
- for (ServiceFactoryList::iterator it = service_factories_.begin();
- it != service_factories_.end(); ++it) {
+ for (ServiceConnectorList::iterator it = service_connectors_.begin();
+ it != service_connectors_.end(); ++it) {
delete *it;
}
}
-void Application::AddServiceFactory(
- internal::ServiceFactoryBase* service_factory) {
- service_factories_.push_back(service_factory);
- set_service_factory_owner(service_factory, this);
+void Application::AddServiceConnector(
+ internal::ServiceConnectorBase* service_connector) {
+ service_connectors_.push_back(service_connector);
+ set_service_connector_owner(service_connector, this);
}
-void Application::RemoveServiceFactory(
- internal::ServiceFactoryBase* service_factory) {
- for (ServiceFactoryList::iterator it = service_factories_.begin();
- it != service_factories_.end(); ++it) {
- if (*it == service_factory) {
- service_factories_.erase(it);
- delete service_factory;
+void Application::RemoveServiceConnector(
+ internal::ServiceConnectorBase* service_connector) {
+ for (ServiceConnectorList::iterator it = service_connectors_.begin();
+ it != service_connectors_.end(); ++it) {
+ if (*it == service_connector) {
+ service_connectors_.erase(it);
+ delete service_connector;
break;
}
}
- if (service_factories_.empty())
+ if (service_connectors_.empty())
shell_.reset();
}
void Application::AcceptConnection(const mojo::String& url,
ScopedMessagePipeHandle client_handle) {
// TODO(davemoore): This method must be overridden by an Application subclass
- // to dispatch to the right ServiceFactory. We need to figure out an approach
- // to registration to make this better.
- assert(1 == service_factories_.size());
- return service_factories_.front()->AcceptConnection(url.To<std::string>(),
- client_handle.Pass());
+ // to dispatch to the right ServiceConnector. We need to figure out an
+ // approach to registration to make this better.
+ assert(1 == service_connectors_.size());
+ return service_connectors_.front()->AcceptConnection(url.To<std::string>(),
+ client_handle.Pass());
}
} // namespace mojo
diff --git a/mojo/public/cpp/shell/lib/service.cc b/mojo/public/cpp/shell/lib/service.cc
index 391a57612c..e408481a35 100644
--- a/mojo/public/cpp/shell/lib/service.cc
+++ b/mojo/public/cpp/shell/lib/service.cc
@@ -7,13 +7,13 @@
namespace mojo {
namespace internal {
-ServiceFactoryBase::Owner::Owner(ScopedShellHandle shell_handle)
+ServiceConnectorBase::Owner::Owner(ScopedShellHandle shell_handle)
: shell_(shell_handle.Pass(), this) {
}
-ServiceFactoryBase::Owner::~Owner() {}
+ServiceConnectorBase::Owner::~Owner() {}
-ServiceFactoryBase::~ServiceFactoryBase() {}
+ServiceConnectorBase::~ServiceConnectorBase() {}
} // namespace internal
} // namespace mojo
diff --git a/mojo/public/cpp/shell/service.h b/mojo/public/cpp/shell/service.h
index 55b4aaea2f..7dd08ffa70 100644
--- a/mojo/public/cpp/shell/service.h
+++ b/mojo/public/cpp/shell/service.h
@@ -19,41 +19,42 @@
// class FooImpl : public Foo {
// public:
// FooImpl();
-// void Initialize(ServiceFactory<FooImpl>* service_factory,
+// void Initialize(ServiceConnector<FooImpl>* service_connector,
// ScopedMessagePipeHandle client_handle
// private:
-// ServiceFactory<FooImpl>* service_factory_;
+// ServiceConnector<FooImpl>* service_connector_;
// RemotePtr<FooPeer> client_;
// };
//
//
-// To simplify further FooImpl can use the Service<> template.
-// class FooImpl : public Service<Foo, FooImpl> {
+// To simplify further FooImpl can use the ServiceConnection<> template.
+// class FooImpl : public ServiceConnection<Foo, FooImpl> {
// public:
// FooImpl();
// ...
// <Foo implementation>
// };
//
-// Instances of FooImpl will be created by a specialized ServiceFactory
+// Instances of FooImpl will be created by a specialized ServiceConnector
//
-// ServiceFactory<FooImpl>
+// ServiceConnector<FooImpl>
//
// Optionally the classes can be specializeed with a shared context
-// class ServiceFactory<FooImpl, MyContext>
+// class ServiceConnector<FooImpl, MyContext>
// and
-// class FooImpl : public Service<Foo, FooImpl, MyContext>
+// class FooImpl : public ServiceConnection<Foo, FooImpl, MyContext>
//
-// foo_factory = new ServiceFactory<FooImpl, MyContext>(my_context);
+// foo_connector = new ServiceConnector<FooImpl, MyContext>(my_context);
// instances of FooImpl can call context() and retrieve the value of my_context.
//
-// Lastly create an Application instance that collects all the ServiceFactories.
+// Lastly create an Application instance that collects all the
+// ServiceConnectors.
//
// Application app(shell_handle);
-// app.AddServiceFactory(new ServiceFactory<FooImpl>);
+// app.AddServiceConnector(new ServiceConnector<FooImpl>);
//
//
-// Specialization of ServiceFactory.
+// Specialization of ServiceConnector.
// ServiceImpl: Implementation of Service interface.
// Context: Optional type of shared context.v
//
@@ -61,27 +62,27 @@
namespace mojo {
namespace internal {
-class ServiceFactoryBase {
+class ServiceConnectorBase {
public:
class Owner : public ShellClient {
public:
Owner(ScopedShellHandle shell_handle);
~Owner();
Shell* shell() { return shell_.get(); }
- virtual void AddServiceFactory(
- internal::ServiceFactoryBase* service_factory) = 0;
- virtual void RemoveServiceFactory(
- internal::ServiceFactoryBase* service_factory) = 0;
+ virtual void AddServiceConnector(
+ internal::ServiceConnectorBase* service_connector) = 0;
+ virtual void RemoveServiceConnector(
+ internal::ServiceConnectorBase* service_connector) = 0;
protected:
- void set_service_factory_owner(ServiceFactoryBase* service_factory,
- Owner* owner) {
- service_factory->owner_ = owner;
+ void set_service_connector_owner(ServiceConnectorBase* service_connector,
+ Owner* owner) {
+ service_connector->owner_ = owner;
}
RemotePtr<Shell> shell_;
};
- ServiceFactoryBase() : owner_(NULL) {}
- virtual ~ServiceFactoryBase();
+ ServiceConnectorBase() : owner_(NULL) {}
+ virtual ~ServiceConnectorBase();
Shell* shell() { return owner_->shell(); }
virtual void AcceptConnection(const std::string& url,
ScopedMessagePipeHandle client_handle) = 0;
@@ -92,11 +93,11 @@ class ServiceFactoryBase {
} // namespace internal
template <class ServiceImpl, typename Context=void>
-class ServiceFactory : public internal::ServiceFactoryBase {
+class ServiceConnector : public internal::ServiceConnectorBase {
public:
- ServiceFactory(Context* context = NULL) : context_(context) {}
+ ServiceConnector(Context* context = NULL) : context_(context) {}
- virtual ~ServiceFactory() {
+ virtual ~ServiceConnector() {
for (typename ServiceList::iterator it = services_.begin();
it != services_.end(); ++it) {
delete *it;
@@ -118,7 +119,7 @@ class ServiceFactory : public internal::ServiceFactoryBase {
services_.erase(it);
delete service;
if (services_.empty())
- owner_->RemoveServiceFactory(this);
+ owner_->RemoveServiceConnector(this);
return;
}
}
@@ -132,21 +133,21 @@ class ServiceFactory : public internal::ServiceFactoryBase {
Context* context_;
};
-// Specialization of ServiceFactory.
+// Specialization of ServiceConnection.
// ServiceInterface: Service interface.
// ServiceImpl: Implementation of Service interface.
// Context: Optional type of shared context.
template <class ServiceInterface, class ServiceImpl, typename Context=void>
-class Service : public ServiceInterface {
+class ServiceConnection : public ServiceInterface {
public:
- virtual ~Service() {}
+ virtual ~ServiceConnection() {}
protected:
- Service() : reaper_(this), service_factory_(NULL) {}
+ ServiceConnection() : reaper_(this), service_connector_(NULL) {}
- void Initialize(ServiceFactory<ServiceImpl, Context>* service_factory,
+ void Initialize(ServiceConnector<ServiceImpl, Context>* service_connector,
ScopedMessagePipeHandle client_handle) {
- service_factory_ = service_factory;
+ service_connector_ = service_connector;
client_.reset(
MakeScopedHandle(
InterfaceHandle<typename ServiceInterface::_Peer>(
@@ -155,27 +156,27 @@ class Service : public ServiceInterface {
&reaper_);
}
- Shell* shell() { return service_factory_->shell(); }
- Context* context() const { return service_factory_->context(); }
+ Shell* shell() { return service_connector_->shell(); }
+ Context* context() const { return service_connector_->context(); }
typename ServiceInterface::_Peer* client() { return client_.get(); }
private:
// The Reaper class allows us to handle errors on the client proxy without
- // polluting the name space of the Service<> class.
+ // polluting the name space of the ServiceConnection<> class.
class Reaper : public ErrorHandler {
public:
- Reaper(Service<ServiceInterface, ServiceImpl, Context>* service)
+ Reaper(ServiceConnection<ServiceInterface, ServiceImpl, Context>* service)
: service_(service) {}
virtual void OnError() {
- service_->service_factory_->RemoveService(
+ service_->service_connector_->RemoveService(
static_cast<ServiceImpl*>(service_));
}
private:
- Service<ServiceInterface, ServiceImpl, Context>* service_;
+ ServiceConnection<ServiceInterface, ServiceImpl, Context>* service_;
};
- friend class ServiceFactory<ServiceImpl, Context>;
+ friend class ServiceConnector<ServiceImpl, Context>;
Reaper reaper_;
- ServiceFactory<ServiceImpl, Context>* service_factory_;
+ ServiceConnector<ServiceImpl, Context>* service_connector_;
RemotePtr<typename ServiceInterface::_Peer> client_;
};
diff --git a/mojo/public/gles2/gles2_private.h b/mojo/public/gles2/gles2_private.h
index 591e043592..c92f555ea8 100644
--- a/mojo/public/gles2/gles2_private.h
+++ b/mojo/public/gles2/gles2_private.h
@@ -7,9 +7,9 @@
#include <stdint.h>
+#include "mojo/public/c/environment/async_waiter.h"
#include "mojo/public/c/gles2/gles2_export.h"
#include "mojo/public/c/gles2/gles2_types.h"
-#include "mojo/public/c/system/async_waiter.h"
#include "mojo/public/cpp/system/core.h"
namespace mojo {
diff --git a/mojo/public/interfaces/bindings/tests/sample_factory.mojom b/mojo/public/interfaces/bindings/tests/sample_factory.mojom
index 15b771a100..00ab1ef076 100644
--- a/mojo/public/interfaces/bindings/tests/sample_factory.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_factory.mojom
@@ -10,6 +10,7 @@ module sample {
struct Request {
int32 x;
handle<message_pipe> pipe;
+ handle<message_pipe>[] more_pipes;
};
struct Response {
diff --git a/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom b/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
index 50e2c60df7..7c20b30473 100644
--- a/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
@@ -4,11 +4,16 @@
module sample {
+enum Enum {
+ ENUM_VALUE
+};
+
[Peer=ProviderClient]
interface Provider {
EchoString(string a) => (string a);
EchoStrings(string a, string b) => (string a, string b);
EchoMessagePipeHandle(handle<message_pipe> a) => (handle<message_pipe> a);
+ EchoEnum(Enum a) => (Enum a);
};
[Peer=Provider]
diff --git a/mojo/public/interfaces/bindings/tests/sample_service.mojom b/mojo/public/interfaces/bindings/tests/sample_service.mojom
index e9cdbd4fb8..04893a4952 100644
--- a/mojo/public/interfaces/bindings/tests/sample_service.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_service.mojom
@@ -34,6 +34,7 @@ struct Foo {
handle<message_pipe> source @9;
handle<data_pipe_consumer>[] input_streams @10;
handle<data_pipe_producer>[] output_streams @11;
+ bool[][] array_of_array_of_bools @12;
};
struct DefaultsTestInner {
@@ -51,10 +52,6 @@ struct DefaultsTest {
Bar.Type bar_type = Bar.TYPE_BOTH;
};
-interface Port {
- PostMessage@0(string message_text @0);
-};
-
[Peer=ServiceClient]
interface Service {
enum BazOptions {
@@ -69,4 +66,10 @@ interface ServiceClient {
DidFrobinate@0(int32 result @0);
};
+// This interface is referenced above where it is defined. It also refers to
+// itself from a method.
+interface Port {
+ PostMessage@0(string message_text @0, Port[] extra_ports@1);
+};
+
}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/Core.java b/mojo/public/java/src/org/chromium/mojo/system/Core.java
new file mode 100644
index 0000000000..8d084b32be
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/Core.java
@@ -0,0 +1,178 @@
+// 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.system;
+
+import java.util.List;
+
+/**
+ * Core mojo interface giving access to the base operations. See |src/mojo/public/c/system/core.h|
+ * for the underlying api.
+ */
+public interface Core {
+
+ /**
+ * Used to indicate an infinite deadline (timeout).
+ */
+ public static final long DEADLINE_INFINITE = -1;
+
+ /**
+ * Flags for the wait operations on handles.
+ */
+ public static class WaitFlags extends Flags<WaitFlags> {
+ /**
+ * Constructor.
+ *
+ * @param flags the serialized flags.
+ */
+ private WaitFlags(int flags) {
+ super(flags);
+ }
+
+ private static final int FLAG_NONE = 0;
+ private static final int FLAG_READABLE = 1 << 0;
+ private static final int FLAG_WRITABLE = 1 << 1;
+ private static final int FLAG_ALL = ~0;
+
+ /**
+ * Change the readable bit of this flag.
+ *
+ * @param readable the new value of the readable bit.
+ * @return this.
+ */
+ public WaitFlags setReadable(boolean readable) {
+ return setFlag(FLAG_READABLE, readable);
+ }
+
+ /**
+ * Change the writable bit of this flag.
+ *
+ * @param writable the new value of the writable bit.
+ * @return this.
+ */
+ public WaitFlags setWritable(boolean writable) {
+ return setFlag(FLAG_WRITABLE, writable);
+ }
+
+ /**
+ * @return a flag with no bit set.
+ */
+ public static WaitFlags none() {
+ return new WaitFlags(FLAG_NONE);
+ }
+
+ /**
+ * @return a flag with all bits set.
+ */
+ public static WaitFlags all() {
+ return new WaitFlags(FLAG_ALL);
+ }
+ }
+
+ /**
+ * @return a platform-dependent monotonically increasing tick count representing "right now."
+ */
+ public long getTimeTicksNow();
+
+ /**
+ * Waits on the given |handle| until the state indicated by |flags| is satisfied or until
+ * |deadline| has passed.
+ *
+ * @return |MojoResult.OK| if some flag in |flags| was satisfied (or is already satisfied).
+ * <p>
+ * |MojoResult.DEADLINE_EXCEEDED| if the deadline has passed without any of the flags
+ * begin satisfied.
+ * <p>
+ * |MojoResult.CANCELLED| if |handle| is closed concurrently by another thread.
+ * <p>
+ * |MojoResult.FAILED_PRECONDITION| if it is or becomes impossible that any flag in
+ * |flags| will ever be satisfied (for example, if the other endpoint is close).
+ */
+ public int wait(Handle handle, WaitFlags flags, long deadline);
+
+ /**
+ * Result for the |waitMany| method.
+ */
+ public static class WaitManyResult {
+
+ /**
+ * See |wait| for the different possible values.
+ */
+ private int mMojoResult;
+ /**
+ * If |mojoResult| is |MojoResult.OK|, |handleIndex| is the index of the handle for which
+ * some flag was satisfied (or is already satisfied). If |mojoResult| is
+ * |MojoResult.CANCELLED| or |MojoResult.FAILED_PRECONDITION|, |handleIndex| is the index of
+ * the handle for which the issue occurred.
+ */
+ private int mHandleIndex;
+
+ /**
+ * @return the mojoResult
+ */
+ public int getMojoResult() {
+ return mMojoResult;
+ }
+
+ /**
+ * @param mojoResult the mojoResult to set
+ */
+ public void setMojoResult(int mojoResult) {
+ mMojoResult = mojoResult;
+ }
+
+ /**
+ * @return the handleIndex
+ */
+ public int getHandleIndex() {
+ return mHandleIndex;
+ }
+
+ /**
+ * @param handleIndex the handleIndex to set
+ */
+ public void setHandleIndex(int handleIndex) {
+ mHandleIndex = handleIndex;
+ }
+ }
+
+ /**
+ * Waits on handle in |handles| for at least one of them to satisfy the associated |WaitFlags|,
+ * or until |deadline| has passed.
+ *
+ * @returns a |WaitManyResult|.
+ */
+ public WaitManyResult waitMany(List<Pair<Handle, WaitFlags>> handles, long deadline);
+
+ /**
+ * Creates a message pipe, which is a bidirectional communication channel for framed data (i.e.,
+ * messages). Messages can contain plain data and/or Mojo handles.
+ *
+ * @return the set of handles for the two endpoints (ports) of the message pipe.
+ */
+ public Pair<MessagePipeHandle, MessagePipeHandle> createMessagePipe();
+
+ /**
+ * Creates a data pipe, which is a unidirectional communication channel for unframed data, with
+ * the given options. Data is unframed, but must come as (multiples of) discrete elements, of
+ * the size given in |options|. See |DataPipe.CreateOptions| for a description of the different
+ * options available for data pipes. |options| may be set to null for a data pipe with the
+ * default options (which will have an element size of one byte and have some system-dependent
+ * capacity).
+ *
+ * @return the set of handles for the two endpoints of the data pipe.
+ */
+ public Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> createDataPipe(
+ DataPipe.CreateOptions options);
+
+ /**
+ * Creates a buffer that can be shared between applications (by duplicating the handle -- see
+ * |SharedBufferHandle.duplicate()| -- and passing it over a message pipe). To access the
+ * buffer, one must call |SharedBufferHandle.map|.
+ *
+ * @return the new |SharedBufferHandle|.
+ */
+ public SharedBufferHandle createSharedBuffer(SharedBufferHandle.CreateOptions options,
+ long numBytes);
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/DataPipe.java b/mojo/public/java/src/org/chromium/mojo/system/DataPipe.java
new file mode 100644
index 0000000000..175f97b305
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/DataPipe.java
@@ -0,0 +1,308 @@
+// 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.system;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Interface for data pipes. A data pipe is a unidirectional communication channel for unframed
+ * data. Data is unframed, but must come as (multiples of) discrete elements, of the size given at
+ * creation time.
+ */
+public interface DataPipe {
+
+ /**
+ * Flags for the data pipe creation operation.
+ */
+ public static class CreateFlags extends Flags<CreateFlags> {
+ private static final int FLAG_NONE = 0;
+ private static final int FLAG_MAY_DISCARD = 1 << 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flags.
+ */
+ protected CreateFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * Change the may-discard bit of this flag. This indicates that the data pipe may discard
+ * data for whatever reason; best-effort delivery. In particular, if the capacity is
+ * reached, old data may be discard to make room for new data.
+ *
+ * @param mayDiscard the new value of the may-discard bit.
+ * @return this.
+ */
+ public CreateFlags setMayDiscard(boolean mayDiscard) {
+ return setFlag(FLAG_MAY_DISCARD, mayDiscard);
+ }
+
+ /**
+ * @return flags with no bit set.
+ */
+ public static CreateFlags none() {
+ return new CreateFlags(FLAG_NONE);
+ }
+
+ }
+
+ /**
+ * Used to specify creation parameters for a data pipe to |Core.createDataPipe()|.
+ */
+ public static class CreateOptions {
+
+ /**
+ * Used to specify different modes of operation, see |DataPipe.CreateFlags|.
+ */
+ private CreateFlags mFlags = CreateFlags.none();
+ /**
+ * The size of an element, in bytes. All transactions and buffers will consist of an
+ * integral number of elements. Must be nonzero.
+ */
+ private int mElementNumBytes;
+ /**
+ * The capacity of the data pipe, in number of bytes; must be a multiple of
+ * |element_num_bytes|. The data pipe will always be able to queue AT LEAST this much data.
+ * Set to zero to opt for a system-dependent automatically-calculated capacity (which will
+ * always be at least one element).
+ */
+ private int mCapacityNumBytes;
+
+ /**
+ * @return the flags
+ */
+ public CreateFlags getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * @return the elementNumBytes
+ */
+ public int getElementNumBytes() {
+ return mElementNumBytes;
+ }
+
+ /**
+ * @param elementNumBytes the elementNumBytes to set
+ */
+ public void setElementNumBytes(int elementNumBytes) {
+ mElementNumBytes = elementNumBytes;
+ }
+
+ /**
+ * @return the capacityNumBytes
+ */
+ public int getCapacityNumBytes() {
+ return mCapacityNumBytes;
+ }
+
+ /**
+ * @param capacityNumBytes the capacityNumBytes to set
+ */
+ public void setCapacityNumBytes(int capacityNumBytes) {
+ mCapacityNumBytes = capacityNumBytes;
+ }
+
+ }
+
+ /**
+ * Flags for the write operations on MessagePipeHandle .
+ */
+ public static class WriteFlags extends Flags<WriteFlags> {
+ private static final int FLAG_NONE = 0;
+ private static final int FLAG_ALL_OR_NONE = 1 << 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flags.
+ */
+ private WriteFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * Change the all-or-none bit of those flags. If set, write either all the elements
+ * requested or none of them.
+ *
+ * @param allOrNone the new value of all-or-none bit.
+ * @return this.
+ */
+ public WriteFlags setAllOrNone(boolean allOrNone) {
+ return setFlag(FLAG_ALL_OR_NONE, allOrNone);
+ }
+
+ /**
+ * @return a flag with no bit set.
+ */
+ public static WriteFlags none() {
+ return new WriteFlags(FLAG_NONE);
+ }
+ }
+
+ /**
+ * Flags for the read operations on MessagePipeHandle.
+ */
+ public static class ReadFlags extends Flags<ReadFlags> {
+ private static final int FLAG_NONE = 0;
+ private static final int FLAG_ALL_OR_NONE = 1 << 0;
+ private static final int FLAG_QUERY = 1 << 2;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flag.
+ */
+ private ReadFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * Change the all-or-none bit of this flag. If set, read (or discard) either the requested
+ * number of elements or none.
+ *
+ * @param allOrNone the new value of the all-or-none bit.
+ * @return this.
+ */
+ public ReadFlags setAllOrNone(boolean allOrNone) {
+ return setFlag(FLAG_ALL_OR_NONE, allOrNone);
+ }
+
+ /**
+ * Change the query bit of this flag. If set query the number of elements available to read.
+ * Mutually exclusive with |dicard| and |allOrNone| is ignored if this flag is set.
+ *
+ * @param query the new value of the query bit.
+ * @return this.
+ */
+ public ReadFlags query(boolean query) {
+ return setFlag(FLAG_QUERY, query);
+ }
+
+ /**
+ * @return a flag with no bit set.
+ */
+ public static ReadFlags none() {
+ return new ReadFlags(FLAG_NONE);
+ }
+
+ }
+
+ /**
+ * Handle for the producer part of a data pipe.
+ */
+ public static interface ProducerHandle extends Handle {
+
+ /**
+ * Writes the given data to the data pipe producer. |elements| points to data; the buffer
+ * must be a direct ByteBuffer and the limit should be a multiple of the data pipe's element
+ * size. If |allOrNone| is set in |flags|, either all the data will be written or none is.
+ * <p>
+ * On success, returns the amount of data that was actually written.
+ * <p>
+ * Note: If the data pipe has the "may discard" option flag (specified on creation), this
+ * will discard as much data as required to write the given data, starting with the earliest
+ * written data that has not been consumed. However, even with "may discard", if the buffer
+ * limit is greater than the data pipe's capacity (and |allOrNone| is not set), this will
+ * write the maximum amount possible (namely, the data pipe's capacity) and return that
+ * amount. It will *not* discard data from |elements|.
+ *
+ * @return number of written bytes.
+ */
+ public int writeData(ByteBuffer elements, WriteFlags flags);
+
+ /**
+ * Begins a two-phase write to the data pipe producer . On success, returns a |ByteBuffer|
+ * to which the caller can write. If flags has |allOrNone| set, then the buffer capacity
+ * will be at least as large as |numBytes|, which must also be a multiple of the element
+ * size (if |allOrNone| is not set, |numBytes| is ignored and the caller must check the
+ * capacity of the buffer).
+ * <p>
+ * During a two-phase write, this handle is *not* writable. E.g., if another thread tries to
+ * write to it, it will throw a |MojoException| with code |MojoResult.BUSY|; that thread can
+ * then wait for this handle to become writable again.
+ * <p>
+ * Once the caller has finished writing data to the buffer, it should call |endWriteData()|
+ * to specify the amount written and to complete the two-phase write.
+ * <p>
+ * Note: If the data pipe has the "may discard" option flag (specified on creation) and
+ * |flags| has |allOrNone| set, this may discard some data.
+ *
+ * @return The buffer to write to.
+ */
+ public ByteBuffer beginWriteData(int numBytes, WriteFlags flags);
+
+ /**
+ * Ends a two-phase write to the data pipe producer that was begun by a call to
+ * |beginWriteData()| on the same handle. |numBytesWritten| should indicate the amount of
+ * data actually written; it must be less than or equal to the capacity of the buffer
+ * returned by |beginWriteData()| and must be a multiple of the element size. The buffer
+ * returned from |beginWriteData()| must have been filled with exactly |numBytesWritten|
+ * bytes of data.
+ * <p>
+ * On failure, the two-phase write (if any) is ended (so the handle may become writable
+ * again, if there's space available) but no data written to the buffer is "put into" the
+ * data pipe.
+ */
+ public void endWriteData(int numBytesWritten);
+ }
+
+ /**
+ * Handle for the consumer part of a data pipe.
+ */
+ public static interface ConsumerHandle extends Handle {
+
+ /**
+ * Discards data on the data pie consumer. This method discards up to |numBytes| (which
+ * again be a multiple of the element size) bytes of data, returning the amount actually
+ * discarded. if |flags| has |allOrNone|, it will either discard exactly |numBytes| bytes of
+ * data or none. In this case, |query| must not be set.
+ */
+ public int discardData(int numBytes, ReadFlags flags);
+
+ /**
+ * Reads data from the data pipe consumer. May also be used to query the amount of data
+ * available. If |flags| has not |query| set, this tries to read up to |elements| capacity
+ * (which must be a multiple of the data pipe's element size) bytes of data to |elements|
+ * and returns the amount actually read. |elements| must be a direct ByteBuffer. If flags
+ * has |allOrNone| set, it will either read exactly |elements| capacity bytes of data or
+ * none.
+ * <p>
+ * If flags has |query| set, it queries the amount of data available, returning the number
+ * of bytes available. In this case |allOrNone| is ignored, as are |elements|.
+ */
+ public int readData(ByteBuffer elements, ReadFlags flags);
+
+ /**
+ * Begins a two-phase read from the data pipe consumer. On success, returns a |ByteBuffer|
+ * from which the caller can read up to its limit bytes of data. If flags has |allOrNone|
+ * set, then the limit will be at least as large as |numBytes|, which must also be a
+ * multiple of the element size (if |allOrNone| is not set, |numBytes| is ignored). |flags|
+ * must not have |query| set.
+ * <p>
+ * During a two-phase read, this handle is *not* readable. E.g., if another thread tries to
+ * read from it, it will throw a |MojoException| with code |MojoResult.BUSY|; that thread
+ * can then wait for this handle to become readable again.
+ * <p>
+ * Once the caller has finished reading data from the buffer, it should call |endReadData()|
+ * to specify the amount read and to complete the two-phase read.
+ */
+ public ByteBuffer beginReadData(int numBytes, ReadFlags flags);
+
+ /**
+ * Ends a two-phase read from the data pipe consumer that was begun by a call to
+ * |beginReadData()| on the same handle. |numBytesRead| should indicate the amount of data
+ * actually read; it must be less than or equal to the limit of the buffer returned by
+ * |beginReadData()| and must be a multiple of the element size.
+ * <p>
+ * On failure, the two-phase read (if any) is ended (so the handle may become readable
+ * again) but no data is "removed" from the data pipe.
+ */
+ public void endReadData(int numBytesRead);
+ }
+
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/Flags.java b/mojo/public/java/src/org/chromium/mojo/system/Flags.java
new file mode 100644
index 0000000000..bfce6e4712
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/Flags.java
@@ -0,0 +1,48 @@
+// 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.system;
+
+/**
+ * Base class for bit field used as flags.
+ *
+ * @param <F> the type of the flags.
+ */
+public abstract class Flags<F extends Flags<F>> {
+ private int mFlags;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flag.
+ */
+ protected Flags(int flags) {
+ mFlags = flags;
+ }
+
+ /**
+ * @return the computed flag.
+ */
+ public int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * Change the given bit of this flag.
+ *
+ * @param value the new value of given bit.
+ * @return this.
+ */
+ protected F setFlag(int flag, boolean value) {
+ if (value) {
+ mFlags |= flag;
+ } else {
+ mFlags &= ~flag;
+ }
+ @SuppressWarnings("unchecked")
+ F f = (F) this;
+ return f;
+ }
+
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/Handle.java b/mojo/public/java/src/org/chromium/mojo/system/Handle.java
new file mode 100644
index 0000000000..6f60055d74
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/Handle.java
@@ -0,0 +1,36 @@
+// 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.system;
+
+import java.io.Closeable;
+
+/**
+ * A generic mojo handle.
+ */
+public interface Handle extends Closeable {
+
+ /**
+ * Closes the given |handle|.
+ * <p>
+ * Concurrent operations on |handle| may succeed (or fail as usual) if they happen before the
+ * close, be cancelled with result |MojoResult.CANCELLED| if they properly overlap (this is
+ * likely the case with |wait()|, etc.), or fail with |MojoResult.INVALID_ARGUMENT| if they
+ * happen after.
+ */
+ @Override
+ public void close();
+
+ /**
+ * @see Core#wait(Handle, Core.WaitFlags, long)
+ */
+ public int wait(Core.WaitFlags flags, long deadline);
+
+ /**
+ * @return whether the handle is valid. A handle is valid until it has been explicitly closed or
+ * send through a message pipe via |MessagePipeHandle.writeMessage|.
+ */
+ public boolean isValid();
+
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/MessagePipeHandle.java b/mojo/public/java/src/org/chromium/mojo/system/MessagePipeHandle.java
new file mode 100644
index 0000000000..c187497d3f
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/MessagePipeHandle.java
@@ -0,0 +1,181 @@
+// 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.system;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * Message pipes are bidirectional communication channel for framed data (i.e., messages). Messages
+ * can contain plain data and/or Mojo handles.
+ */
+public interface MessagePipeHandle extends Handle {
+ /**
+ * Flags for the write operations on MessagePipeHandle .
+ */
+ public static class WriteFlags extends Flags<WriteFlags> {
+ private static final int FLAG_NONE = 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flag.
+ */
+ private WriteFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * @return a flag with no bit set.
+ */
+ public static WriteFlags none() {
+ return new WriteFlags(FLAG_NONE);
+ }
+ }
+
+ /**
+ * Flags for the read operations on MessagePipeHandle.
+ */
+ public static class ReadFlags extends Flags<ReadFlags> {
+ private static final int FLAG_NONE = 0;
+ private static final int FLAG_MAY_DISCARD = 1 << 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flag.
+ */
+ private ReadFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * Change the may-discard bit of this flag. If set, if the message is unable to be read for
+ * whatever reason (e.g., the caller-supplied buffer is too small), discard the message
+ * (i.e., simply dequeue it).
+ *
+ * @param mayDiscard the new value of the may-discard bit.
+ * @return this.
+ */
+ public ReadFlags setMayDiscard(boolean mayDiscard) {
+ return setFlag(FLAG_MAY_DISCARD, mayDiscard);
+ }
+
+ /**
+ * @return a flag with no bit set.
+ */
+ public static ReadFlags none() {
+ return new ReadFlags(FLAG_NONE);
+ }
+
+ }
+
+ /**
+ * Writes a message to the message pipe endpoint, with message data specified by |bytes| and
+ * attached handles specified by |handles|, and options specified by |flags|. If there is no
+ * message data, |bytes| may be null, otherwise it must be a direct ByteBuffer. If there are no
+ * attached handles, |handles| may be null.
+ * <p>
+ * If handles are attached, on success the handles will no longer be valid (the receiver will
+ * receive equivalent, but logically different, handles). Handles to be sent should not be in
+ * simultaneous use (e.g., on another thread).
+ */
+ void writeMessage(ByteBuffer bytes, List<Handle> handles, WriteFlags flags);
+
+ /**
+ * Result of the |readMessage| method.
+ */
+ public static class ReadMessageResult {
+ /**
+ * <code>true</code> if a message was read.
+ */
+ private boolean mWasMessageRead;
+ /**
+ * If a message was read, the size in bytes of the message, otherwise the size in bytes of
+ * the next message.
+ */
+ private int mMessageSize;
+ /**
+ * If a message was read, the number of handles contained in the message, otherwise the
+ * number of handles contained in the next message.
+ */
+ private int mHandlesCount;
+ /**
+ * If a message was read, the handles contained in the message, undefined otherwise.
+ */
+ private List<UntypedHandle> mHandles;
+
+ /**
+ * @return the wasMessageRead
+ */
+ public boolean getWasMessageRead() {
+ return mWasMessageRead;
+ }
+
+ /**
+ * @param wasMessageRead the wasMessageRead to set
+ */
+ public void setWasMessageRead(boolean wasMessageRead) {
+ mWasMessageRead = wasMessageRead;
+ }
+
+ /**
+ * @return the messageSize
+ */
+ public int getMessageSize() {
+ return mMessageSize;
+ }
+
+ /**
+ * @param messageSize the messageSize to set
+ */
+ public void setMessageSize(int messageSize) {
+ mMessageSize = messageSize;
+ }
+
+ /**
+ * @return the handlesCount
+ */
+ public int getHandlesCount() {
+ return mHandlesCount;
+ }
+
+ /**
+ * @param handlesCount the handlesCount to set
+ */
+ public void setHandlesCount(int handlesCount) {
+ mHandlesCount = handlesCount;
+ }
+
+ /**
+ * @return the handles
+ */
+ public List<UntypedHandle> getHandles() {
+ return mHandles;
+ }
+
+ /**
+ * @param handles the handles to set
+ */
+ public void setHandles(List<UntypedHandle> handles) {
+ mHandles = handles;
+ }
+ }
+
+ /**
+ * Reads a message from the message pipe endpoint; also usable to query the size of the next
+ * message or discard the next message. |bytes| indicate the buffer/buffer size to receive the
+ * message data (if any) and |maxNumberOfHandles| indicate the maximum handle count to receive
+ * the attached handles (if any). |bytes| is optional. If null, |maxNumberOfHandles| must be
+ * zero, and the return value will indicate the size of the next message. If non-null, it must
+ * be a direct ByteBuffer and the return value will indicate if the message was read or not. If
+ * the message was read its content will be in |bytes|, and the attached handles will be in the
+ * return value. Partial reads are NEVER done. Either a full read is done and |wasMessageRead|
+ * will be true, or the read is NOT done and |wasMessageRead| will be false (if |mayDiscard| was
+ * set, the message is also discarded in this case).
+ */
+ ReadMessageResult readMessage(ByteBuffer bytes, int maxNumberOfHandles,
+ ReadFlags flags);
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/MojoException.java b/mojo/public/java/src/org/chromium/mojo/system/MojoException.java
new file mode 100644
index 0000000000..e06f647aeb
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/MojoException.java
@@ -0,0 +1,36 @@
+// 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.system;
+
+/**
+ * Exception for the core mojo API.
+ */
+public class MojoException extends RuntimeException {
+
+ private final int mCode;
+
+ /**
+ * Constructor.
+ */
+ public MojoException(int code) {
+ mCode = code;
+ }
+
+ /**
+ * The mojo result code associated with this exception. See {@link MojoResult} for possible
+ * values.
+ */
+ public int getMojoResult() {
+ return mCode;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "MojoResult(" + mCode + "): " + MojoResult.describe(mCode);
+ }
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/MojoResult.java b/mojo/public/java/src/org/chromium/mojo/system/MojoResult.java
new file mode 100644
index 0000000000..a829c8332a
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/MojoResult.java
@@ -0,0 +1,82 @@
+// 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.system;
+
+/**
+ * The different mojo result codes.
+ */
+public final class MojoResult {
+ public static final int OK = 0;
+ public static final int CANCELLED = -1;
+ public static final int UNKNOWN = -2;
+ public static final int INVALID_ARGUMENT = -3;
+ public static final int DEADLINE_EXCEEDED = -4;
+ public static final int NOT_FOUND = -5;
+ public static final int ALREADY_EXISTS = -6;
+ public static final int PERMISSION_DENIED = -7;
+ public static final int RESOURCE_EXHAUSTED = -8;
+ public static final int FAILED_PRECONDITION = -9;
+ public static final int ABORTED = -10;
+ public static final int OUT_OF_RANGE = -11;
+ public static final int UNIMPLEMENTED = -12;
+ public static final int INTERNAL = -13;
+ public static final int UNAVAILABLE = -14;
+ public static final int DATA_LOSS = -15;
+ public static final int BUSY = -16;
+ public static final int SHOULD_WAIT = -17;
+
+ /**
+ * never instantiate.
+ */
+ private MojoResult() {
+ }
+
+ /**
+ * Describes the given result code.
+ */
+ public static String describe(int mCode) {
+ switch (mCode) {
+ case OK:
+ return "OK";
+ case CANCELLED:
+ return "CANCELLED";
+ case UNKNOWN:
+ return "UNKNOWN";
+ case INVALID_ARGUMENT:
+ return "INVALID_ARGUMENT";
+ case DEADLINE_EXCEEDED:
+ return "DEADLINE_EXCEEDED";
+ case NOT_FOUND:
+ return "NOT_FOUND";
+ case ALREADY_EXISTS:
+ return "ALREADY_EXISTS";
+ case PERMISSION_DENIED:
+ return "PERMISSION_DENIED";
+ case RESOURCE_EXHAUSTED:
+ return "RESOURCE_EXHAUSTED";
+ case FAILED_PRECONDITION:
+ return "FAILED_PRECONDITION";
+ case ABORTED:
+ return "ABORTED";
+ case OUT_OF_RANGE:
+ return "OUT_OF_RANGE";
+ case UNIMPLEMENTED:
+ return "UNIMPLEMENTED";
+ case INTERNAL:
+ return "INTERNAL";
+ case UNAVAILABLE:
+ return "UNAVAILABLE";
+ case DATA_LOSS:
+ return "DATA_LOSS";
+ case BUSY:
+ return "BUSY";
+ case SHOULD_WAIT:
+ return "SHOULD_WAIT";
+ default:
+ return "UNKNOWN";
+ }
+
+ }
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/Pair.java b/mojo/public/java/src/org/chromium/mojo/system/Pair.java
new file mode 100644
index 0000000000..c302aed680
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/Pair.java
@@ -0,0 +1,61 @@
+// 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.system;
+
+import java.util.Objects;
+
+/**
+ * A pair of object.
+ *
+ * @param <F> Type of the first element.
+ * @param <S> Type of the second element.
+ */
+public class Pair<F, S> {
+
+ public final F first;
+ public final S second;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param first the first element of the pair.
+ * @param second the second element of the pair.
+ */
+ public Pair(F first, S second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ /**
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Pair)) {
+ return false;
+ }
+ Pair<?, ?> p = (Pair<?, ?>) o;
+ return Objects.equals(p.first, first) && Objects.equals(p.second, second);
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
+ }
+
+ /**
+ * Helper method for creating a pair.
+ *
+ * @param a the first element of the pair.
+ * @param b the second element of the pair.
+ * @return the pair containing a and b.
+ */
+ public static <A, B, C extends A, D extends B> Pair<A, B> create(C a, D b) {
+ return new Pair<A, B>(a, b);
+ }
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java b/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java
new file mode 100644
index 0000000000..908db9ef6c
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java
@@ -0,0 +1,139 @@
+// 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.system;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A buffer that can be shared between applications.
+ */
+public interface SharedBufferHandle extends Handle {
+
+ /**
+ * Flags for the shared buffer creation operation.
+ */
+ public static class CreateFlags extends Flags<CreateFlags> {
+ private static final int FLAG_NONE = 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flags.
+ */
+ protected CreateFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * @return flags with no bit set.
+ */
+ public static CreateFlags none() {
+ return new CreateFlags(FLAG_NONE);
+ }
+
+ }
+
+ /**
+ * Used to specify creation parameters for a shared buffer to |Core#createSharedBuffer()|.
+ */
+ public static class CreateOptions {
+ private CreateFlags mFlags = CreateFlags.none();
+
+ /**
+ * @return the flags
+ */
+ public CreateFlags getFlags() {
+ return mFlags;
+ }
+
+ }
+
+ /**
+ * Flags for the shared buffer duplication operation.
+ */
+ public static class DuplicateFlags extends Flags<DuplicateFlags> {
+ private static final int FLAG_NONE = 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flags.
+ */
+ protected DuplicateFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * @return flags with no bit set.
+ */
+ public static DuplicateFlags none() {
+ return new DuplicateFlags(FLAG_NONE);
+ }
+
+ }
+
+ /**
+ * Used to specify parameters in duplicating access to a shared buffer to
+ * |SharedBufferHandle#duplicate|
+ */
+ public static class DuplicateOptions {
+ private DuplicateFlags mFlags = DuplicateFlags.none();
+
+ /**
+ * @return the flags
+ */
+ public DuplicateFlags getFlags() {
+ return mFlags;
+ }
+
+ }
+
+ /**
+ * TODO(qsr): Insert description here.
+ */
+ public static class MapFlags extends Flags<MapFlags> {
+ private static final int FLAG_NONE = 0;
+
+ /**
+ * Dedicated constructor.
+ *
+ * @param flags initial value of the flags.
+ */
+ protected MapFlags(int flags) {
+ super(flags);
+ }
+
+ /**
+ * @return flags with no bit set.
+ */
+ public static MapFlags none() {
+ return new MapFlags(FLAG_NONE);
+ }
+
+ }
+
+ /**
+ * Duplicates the handle. This creates another handle (returned on success), which can then be
+ * sent to another application over a message pipe, while retaining access to this handle (and
+ * any mappings that it may have).
+ */
+ public SharedBufferHandle duplicate(DuplicateOptions options);
+
+ /**
+ * Map the part (at offset |offset| of length |numBytes|) of the buffer given by this handle
+ * into memory. |offset + numBytes| must be less than or equal to the size of the buffer. On
+ * success, the returned buffer points to memory with the requested part of the buffer. A single
+ * buffer handle may have multiple active mappings (possibly depending on the buffer type). The
+ * permissions (e.g., writable or executable) of the returned memory may depend on the
+ * properties of the buffer and properties attached to the buffer handle as well as |flags|.
+ */
+ public ByteBuffer map(long offset, long numBytes, MapFlags flags);
+
+ /**
+ * Unmap a buffer pointer that was mapped by |map()|.
+ */
+ public void unmap(ByteBuffer buffer);
+
+}
diff --git a/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java b/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java
new file mode 100644
index 0000000000..63b5f7c322
--- /dev/null
+++ b/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java
@@ -0,0 +1,41 @@
+// 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.system;
+
+
+/**
+ * TODO(qsr): Insert description here.
+ */
+public interface UntypedHandle extends Handle {
+
+ /**
+ * TODO(qsr):
+ *
+ * @return TODO(qsr)
+ */
+ public MessagePipeHandle toMessagePipeHandle();
+
+ /**
+ * TODO(qsr):
+ *
+ * @return TODO(qsr)
+ */
+ public DataPipe.ConsumerHandle toDataPipeConsumerHandle();
+
+ /**
+ * TODO(qsr):
+ *
+ * @return TODO(qsr)
+ */
+ public DataPipe.ProducerHandle toDataPipeProducerHandle();
+
+ /**
+ * TODO(qsr):
+ *
+ * @return TODO(qsr)
+ */
+ public SharedBufferHandle toSharedBufferHandle();
+
+}
diff --git a/mojo/public/js/bindings/codec.js b/mojo/public/js/bindings/codec.js
index f3d4b68ae5..ef2060e516 100644
--- a/mojo/public/js/bindings/codec.js
+++ b/mojo/public/js/bindings/codec.js
@@ -2,81 +2,111 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-define("mojo/public/js/bindings/codec", function() {
+define("mojo/public/js/bindings/codec", [
+ "mojo/public/js/bindings/unicode"
+], function(unicode) {
- // Memory -------------------------------------------------------------------
+ var kErrorUnsigned = "Passing negative value to unsigned";
- function store8(memory, pointer, val) {
- memory[pointer] = val;
- }
+ // Memory -------------------------------------------------------------------
- function store16(memory, pointer, val) {
- memory[pointer + 0] = val >> 0;
- memory[pointer + 1] = val >> 8;
- }
+ var kAlignment = 8;
+ var kHighWordMultiplier = 0x100000000;
+ var kHostIsLittleEndian = (function () {
+ var endianArrayBuffer = new ArrayBuffer(2);
+ var endianUint8Array = new Uint8Array(endianArrayBuffer);
+ var endianUint16Array = new Uint16Array(endianArrayBuffer);
+ endianUint16Array[0] = 1;
+ return endianUint8Array[0] == 1;
+ })();
- function store32(memory, pointer, val) {
- memory[pointer + 0] = val >> 0;
- memory[pointer + 1] = val >> 8;
- memory[pointer + 2] = val >> 16;
- memory[pointer + 3] = val >> 24;
+ function align(size) {
+ return size + (kAlignment - (size % kAlignment)) % kAlignment;
}
- function store64(memory, pointer, val) {
- store32(memory, pointer, val);
- var high = (val / 0x10000) | 0;
- store32(memory, pointer + 4, high);
+ function getInt64(dataView, byteOffset, value) {
+ var lo, hi;
+ if (kHostIsLittleEndian) {
+ lo = dataView.getUint32(byteOffset, kHostIsLittleEndian);
+ hi = dataView.getInt32(byteOffset + 4, kHostIsLittleEndian);
+ } else {
+ hi = dataView.getInt32(byteOffset, kHostIsLittleEndian);
+ lo = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian);
+ }
+ return lo + hi * kHighWordMultiplier;
}
- function load8(memory, pointer) {
- return memory[pointer];
+ function getUint64(dataView, byteOffset, value) {
+ var lo, hi;
+ if (kHostIsLittleEndian) {
+ lo = dataView.getUint32(byteOffset, kHostIsLittleEndian);
+ hi = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian);
+ } else {
+ hi = dataView.getUint32(byteOffset, kHostIsLittleEndian);
+ lo = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian);
+ }
+ return lo + hi * kHighWordMultiplier;
}
- function load16(memory, pointer) {
- return (memory[pointer + 0] << 0) +
- (memory[pointer + 1] << 8);
+ function setInt64(dataView, byteOffset, value) {
+ var hi = Math.floor(value / kHighWordMultiplier);
+ if (kHostIsLittleEndian) {
+ dataView.setInt32(byteOffset, value, kHostIsLittleEndian);
+ dataView.setInt32(byteOffset + 4, hi, kHostIsLittleEndian);
+ } else {
+ dataView.setInt32(byteOffset, hi, kHostIsLittleEndian);
+ dataView.setInt32(byteOffset + 4, value, kHostIsLittleEndian);
+ }
}
- function load32(memory, pointer) {
- return (memory[pointer + 0] << 0) +
- (memory[pointer + 1] << 8) +
- (memory[pointer + 2] << 16) +
- (memory[pointer + 3] << 24);
+ function setUint64(dataView, byteOffset, value) {
+ var hi = (value / kHighWordMultiplier) | 0;
+ if (kHostIsLittleEndian) {
+ dataView.setInt32(byteOffset, value, kHostIsLittleEndian);
+ dataView.setInt32(byteOffset + 4, hi, kHostIsLittleEndian);
+ } else {
+ dataView.setInt32(byteOffset, hi, kHostIsLittleEndian);
+ dataView.setInt32(byteOffset + 4, value, kHostIsLittleEndian);
+ }
}
- var kAlignment = 8;
-
- function align(size) {
- return size + (kAlignment - (size % kAlignment)) % kAlignment;
+ function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) {
+ (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer));
}
// Buffer -------------------------------------------------------------------
- function Buffer(size) {
- this.memory = new Uint8Array(size);
+ function Buffer(sizeOrArrayBuffer) {
+ if (sizeOrArrayBuffer instanceof ArrayBuffer) {
+ this.arrayBuffer = sizeOrArrayBuffer;
+ } else {
+ this.arrayBuffer = new ArrayBuffer(sizeOrArrayBuffer);
+ };
+
+ this.dataView = new DataView(this.arrayBuffer);
this.next = 0;
}
Buffer.prototype.alloc = function(size) {
var pointer = this.next;
this.next += size;
- if (this.next > this.memory.length) {
- var newSize = (1.5 * (this.memory.length + size)) | 0;
+ if (this.next > this.arrayBuffer.byteLength) {
+ var newSize = (1.5 * (this.arrayBuffer.byteLength + size)) | 0;
this.grow(newSize);
}
return pointer;
};
Buffer.prototype.grow = function(size) {
- var newMemory = new Uint8Array(size);
- var oldMemory = this.memory;
- for (var i = 0; i < oldMemory.length; ++i)
- newMemory[i] = oldMemory[i];
- this.memory = newMemory;
+ var newArrayBuffer = new ArrayBuffer(size);
+ copyArrayBuffer(newArrayBuffer, this.arrayBuffer);
+ this.arrayBuffer = newArrayBuffer;
+ this.dataView = new DataView(this.arrayBuffer);
};
- Buffer.prototype.createViewOfAllocatedMemory = function() {
- return new Uint8Array(this.memory.buffer, 0, this.next);
+ Buffer.prototype.trim = function() {
+ this.arrayBuffer = this.arrayBuffer.slice(0, this.next);
+ this.dataView = new DataView(this.arrayBuffer);
};
// Constants ----------------------------------------------------------------
@@ -88,50 +118,77 @@ define("mojo/public/js/bindings/codec", function() {
// Decoder ------------------------------------------------------------------
- function Decoder(memory, handles, base) {
- this.memory = memory;
+ function Decoder(buffer, handles, base) {
+ this.buffer = buffer;
this.handles = handles;
this.base = base;
this.next = base;
- this.viewU32 = new Uint32Array(
- this.memory.buffer, 0,
- Math.floor(this.memory.length / Uint32Array.BYTES_PER_ELEMENT));
- this.viewFloat = new Float32Array(
- this.memory.buffer, 0,
- Math.floor(this.memory.length / Float32Array.BYTES_PER_ELEMENT));
}
Decoder.prototype.skip = function(offset) {
this.next += offset;
};
- Decoder.prototype.read8 = function() {
- var result = load8(this.memory, this.next);
+ Decoder.prototype.readInt8 = function() {
+ var result = this.buffer.dataView.getInt8(this.next, kHostIsLittleEndian);
this.next += 1;
return result;
};
- Decoder.prototype.read16 = function() {
- var result = load16(this.memory, this.next);
+ Decoder.prototype.readUint8 = function() {
+ var result = this.buffer.dataView.getUint8(this.next, kHostIsLittleEndian);
+ this.next += 1;
+ return result;
+ };
+
+ Decoder.prototype.readInt16 = function() {
+ var result = this.buffer.dataView.getInt16(this.next, kHostIsLittleEndian);
this.next += 2;
return result;
};
- Decoder.prototype.read32 = function() {
- var result = this.viewU32[this.next / this.viewU32.BYTES_PER_ELEMENT];
- this.next += this.viewU32.BYTES_PER_ELEMENT;
+ Decoder.prototype.readUint16 = function() {
+ var result = this.buffer.dataView.getUint16(this.next, kHostIsLittleEndian);
+ this.next += 2;
return result;
};
- Decoder.prototype.read64 = function() {
- var low = this.read32();
- var high = this.read32();
- return low + high * 0x100000000;
+ Decoder.prototype.readInt32 = function() {
+ var result = this.buffer.dataView.getInt32(this.next, kHostIsLittleEndian);
+ this.next += 4;
+ return result;
};
- Decoder.prototype.decodeFloat = function() {
- var result = this.viewFloat[this.next / this.viewFloat.BYTES_PER_ELEMENT];
- this.next += this.viewFloat.BYTES_PER_ELEMENT;
+ Decoder.prototype.readUint32 = function() {
+ var result = this.buffer.dataView.getUint32(this.next, kHostIsLittleEndian);
+ this.next += 4;
+ return result;
+ };
+
+ Decoder.prototype.readInt64 = function() {
+ var result = getInt64(this.buffer.dataView, this.next, kHostIsLittleEndian);
+ this.next += 8;
+ return result;
+ };
+
+ Decoder.prototype.readUint64 = function() {
+ var result = getUint64(
+ this.buffer.dataView, this.next, kHostIsLittleEndian);
+ this.next += 8;
+ return result;
+ };
+
+ Decoder.prototype.readFloat32 = function() {
+ var result = this.buffer.dataView.readFloat32(
+ this.next, kHostIsLittleEndian);
+ this.next += 4;
+ return result;
+ };
+
+ Decoder.prototype.readFloat64 = function() {
+ var result = this.buffer.dataView.readFloat64(
+ this.next, kHostIsLittleEndian);
+ this.next += 8;
return result;
};
@@ -139,39 +196,32 @@ define("mojo/public/js/bindings/codec", function() {
// TODO(abarth): To correctly decode a pointer, we need to know the real
// base address of the array buffer.
var offsetPointer = this.next;
- var offset = this.read64();
+ var offset = this.readUint64();
if (!offset)
return 0;
return offsetPointer + offset;
};
Decoder.prototype.decodeAndCreateDecoder = function() {
- return new Decoder(this.memory, this.handles, this.decodePointer());
+ return new Decoder(this.buffer, this.handles, this.decodePointer());
};
Decoder.prototype.decodeHandle = function() {
- return this.handles[this.read32()];
+ return this.handles[this.readUint32()];
};
Decoder.prototype.decodeString = function() {
- // TODO(abarth): We should really support UTF-8. We might want to
- // jump out of the VM to decode the string directly from the array
- // buffer using v8::String::NewFromUtf8.
- var numberOfBytes = this.read32();
- var numberOfElements = this.read32();
- var val = new Array(numberOfElements);
- var memory = this.memory;
+ var numberOfBytes = this.readUint32();
+ var numberOfElements = this.readUint32();
var base = this.next;
- for (var i = 0; i < numberOfElements; ++i) {
- val[i] = String.fromCharCode(memory[base + i] & 0x7F);
- }
this.next += numberOfElements;
- return val.join('');
+ return unicode.decodeUtf8String(
+ new Uint8Array(this.buffer.arrayBuffer, base, numberOfElements));
};
Decoder.prototype.decodeArray = function(cls) {
- var numberOfBytes = this.read32();
- var numberOfElements = this.read32();
+ var numberOfBytes = this.readUint32();
+ var numberOfElements = this.readUint32();
var val = new Array(numberOfElements);
for (var i = 0; i < numberOfElements; ++i) {
val[i] = cls.decode(this);
@@ -204,41 +254,77 @@ define("mojo/public/js/bindings/codec", function() {
this.next += offset;
};
- Encoder.prototype.write8 = function(val) {
- store8(this.buffer.memory, this.next, val);
+ Encoder.prototype.writeInt8 = function(val) {
+ // NOTE: Endianness doesn't come into play for single bytes.
+ this.buffer.dataView.setInt8(this.next, val);
+ this.next += 1;
+ };
+
+ Encoder.prototype.writeUint8 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ // NOTE: Endianness doesn't come into play for single bytes.
+ this.buffer.dataView.setUint8(this.next, val);
this.next += 1;
};
- Encoder.prototype.write16 = function(val) {
- store16(this.buffer.memory, this.next, val);
+ Encoder.prototype.writeInt16 = function(val) {
+ this.buffer.dataView.setInt16(this.next, val, kHostIsLittleEndian);
this.next += 2;
};
- Encoder.prototype.write32 = function(val) {
- store32(this.buffer.memory, this.next, val);
+ Encoder.prototype.writeUint16 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ this.buffer.dataView.setUint16(this.next, val, kHostIsLittleEndian);
+ this.next += 2;
+ };
+
+ Encoder.prototype.writeInt32 = function(val) {
+ this.buffer.dataView.setInt32(this.next, val, kHostIsLittleEndian);
this.next += 4;
};
- Encoder.prototype.write64 = function(val) {
- store64(this.buffer.memory, this.next, val);
+ Encoder.prototype.writeUint32 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ this.buffer.dataView.setUint32(this.next, val, kHostIsLittleEndian);
+ this.next += 4;
+ };
+
+ Encoder.prototype.writeInt64 = function(val) {
+ setInt64(this.buffer.dataView, this.next, val);
this.next += 8;
};
- Encoder.prototype.encodeFloat = function(val) {
- var floatBuffer = new Float32Array(1);
- floatBuffer[0] = val;
- var buffer = new Uint8Array(floatBuffer.buffer, 0);
- for (var i = 0; i < buffer.length; ++i)
- this.buffer.memory[this.next++] = buffer[i];
+ Encoder.prototype.writeUint64 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ setUint64(this.buffer.dataView, this.next, val);
+ this.next += 8;
+ };
+
+ Encoder.prototype.writeFloat32 = function(val) {
+ this.buffer.dataView.setFloat32(val, kHostIsLittleEndian);
+ this.next += 4;
+ };
+
+ Encoder.prototype.writeFloat64 = function(val) {
+ this.buffer.dataView.setFloat64(val, kHostIsLittleEndian);
+ this.next += 8;
};
Encoder.prototype.encodePointer = function(pointer) {
if (!pointer)
- return this.write64(0);
+ return this.writeUint64(0);
// TODO(abarth): To correctly encode a pointer, we need to know the real
// base address of the array buffer.
var offset = pointer - this.next;
- this.write64(offset);
+ this.writeUint64(offset);
};
Encoder.prototype.createAndEncodeEncoder = function(size) {
@@ -249,31 +335,24 @@ define("mojo/public/js/bindings/codec", function() {
Encoder.prototype.encodeHandle = function(handle) {
this.handles.push(handle);
- this.write32(this.handles.length - 1);
+ this.writeUint32(this.handles.length - 1);
};
Encoder.prototype.encodeString = function(val) {
- var numberOfElements = val.length;
+ var base = this.next + kArrayHeaderSize;
+ var numberOfElements = unicode.encodeUtf8String(
+ val, new Uint8Array(this.buffer.arrayBuffer, base));
var numberOfBytes = kArrayHeaderSize + numberOfElements;
- this.write32(numberOfBytes);
- this.write32(numberOfElements);
- // TODO(abarth): We should really support UTF-8. We might want to
- // jump out of the VM to encode the string directly from the array
- // buffer using v8::String::WriteUtf8.
- var memory = this.buffer.memory;
- var base = this.next;
- var len = val.length;
- for (var i = 0; i < len; ++i) {
- memory[base + i] = val.charCodeAt(i) & 0x7F;
- }
- this.next += len;
+ this.writeUint32(numberOfBytes);
+ this.writeUint32(numberOfElements);
+ this.next += numberOfElements;
};
Encoder.prototype.encodeArray = function(cls, val) {
var numberOfElements = val.length;
var numberOfBytes = kArrayHeaderSize + cls.encodedSize * numberOfElements;
- this.write32(numberOfBytes);
- this.write32(numberOfElements);
+ this.writeUint32(numberOfBytes);
+ this.writeUint32(numberOfElements);
for (var i = 0; i < numberOfElements; ++i) {
cls.encode(this, val[i]);
}
@@ -291,8 +370,7 @@ define("mojo/public/js/bindings/codec", function() {
};
Encoder.prototype.encodeStringPointer = function(val) {
- // TODO(abarth): This won't be right once we support UTF-8.
- var encodedSize = kArrayHeaderSize + val.length;
+ var encodedSize = kArrayHeaderSize + unicode.utf8Length(val);
var encoder = this.createAndEncodeEncoder(encodedSize);
encoder.encodeString(val);
};
@@ -302,19 +380,24 @@ define("mojo/public/js/bindings/codec", function() {
var kMessageExpectsResponse = 1 << 0;
var kMessageIsResponse = 1 << 1;
- function Message(memory, handles) {
- this.memory = memory;
+ // Skip over num_bytes, num_fields, and message_name.
+ var kFlagsOffset = 4 + 4 + 4;
+
+ // Skip over num_bytes, num_fields, message_name, and flags.
+ var kRequestIDOffset = 4 + 4 + 4 + 4;
+
+ function Message(buffer, handles) {
+ this.buffer = buffer;
this.handles = handles;
}
Message.prototype.setRequestID = function(requestID) {
// TODO(darin): Verify that space was reserved for this field!
- store64(this.memory, 4 + 4 + 4 + 4, requestID);
+ setUint64(this.buffer.dataView, kRequestIDOffset, requestID);
};
Message.prototype.getFlags = function() {
- // Skip over num_bytes, num_fields, and message_name.
- return load32(this.memory, 4 + 4 + 4);
+ return this.buffer.dataView.getUint32(kFlagsOffset, kHostIsLittleEndian);
};
// MessageBuilder -----------------------------------------------------------
@@ -326,10 +409,10 @@ define("mojo/public/js/bindings/codec", function() {
this.buffer = new Buffer(numberOfBytes);
this.handles = [];
var encoder = this.createEncoder(kMessageHeaderSize);
- encoder.write32(kMessageHeaderSize);
- encoder.write32(2); // num_fields.
- encoder.write32(messageName);
- encoder.write32(0); // flags.
+ encoder.writeUint32(kMessageHeaderSize);
+ encoder.writeUint32(2); // num_fields.
+ encoder.writeUint32(messageName);
+ encoder.writeUint32(0); // flags.
}
MessageBuilder.prototype.createEncoder = function(size) {
@@ -344,8 +427,8 @@ define("mojo/public/js/bindings/codec", function() {
MessageBuilder.prototype.finish = function() {
// TODO(abarth): Rather than resizing the buffer at the end, we could
// compute the size we need ahead of time, like we do in C++.
- var memory = this.buffer.createViewOfAllocatedMemory();
- var message = new Message(memory, this.handles);
+ this.buffer.trim();
+ var message = new Message(this.buffer, this.handles);
this.buffer = null;
this.handles = null;
this.encoder = null;
@@ -362,29 +445,31 @@ define("mojo/public/js/bindings/codec", function() {
this.buffer = new Buffer(numberOfBytes);
this.handles = [];
var encoder = this.createEncoder(kMessageWithRequestIDHeaderSize);
- encoder.write32(kMessageWithRequestIDHeaderSize);
- encoder.write32(3); // num_fields.
- encoder.write32(messageName);
- encoder.write32(flags);
- encoder.write64(requestID);
+ encoder.writeUint32(kMessageWithRequestIDHeaderSize);
+ encoder.writeUint32(3); // num_fields.
+ encoder.writeUint32(messageName);
+ encoder.writeUint32(flags);
+ encoder.writeUint64(requestID);
}
MessageWithRequestIDBuilder.prototype =
Object.create(MessageBuilder.prototype);
+
MessageWithRequestIDBuilder.prototype.constructor =
MessageWithRequestIDBuilder;
// MessageReader ------------------------------------------------------------
function MessageReader(message) {
- this.decoder = new Decoder(message.memory, message.handles, 0);
- var messageHeaderSize = this.decoder.read32();
- this.payloadSize = message.memory.length - messageHeaderSize;
- var numFields = this.decoder.read32();
- this.messageName = this.decoder.read32();
- this.flags = this.decoder.read32();
+ this.decoder = new Decoder(message.buffer, message.handles, 0);
+ var messageHeaderSize = this.decoder.readUint32();
+ this.payloadSize =
+ message.buffer.arrayBuffer.byteLength - messageHeaderSize;
+ var numFields = this.decoder.readUint32();
+ this.messageName = this.decoder.readUint32();
+ this.flags = this.decoder.readUint32();
if (numFields >= 3)
- this.requestID = this.decoder.read64();
+ this.requestID = this.decoder.readUint64();
this.decoder.skip(messageHeaderSize - this.decoder.next);
}
@@ -394,17 +479,43 @@ define("mojo/public/js/bindings/codec", function() {
// Built-in types -----------------------------------------------------------
+ function Int8() {
+ }
+
+ Int8.encodedSize = 1;
+
+ Int8.decode = function(decoder) {
+ return decoder.readInt8();
+ };
+
+ Uint8.encode = function(encoder, val) {
+ encoder.writeUint8(val);
+ };
+
function Uint8() {
}
Uint8.encodedSize = 1;
Uint8.decode = function(decoder) {
- return decoder.read8();
+ return decoder.readUint8();
};
Uint8.encode = function(encoder, val) {
- encoder.write8(val);
+ encoder.writeUint8(val);
+ };
+
+ function Int16() {
+ }
+
+ Int16.encodedSize = 2;
+
+ Int16.decode = function(decoder) {
+ return decoder.readInt16();
+ };
+
+ Int16.encode = function(encoder, val) {
+ encoder.writeInt16(val);
};
function Uint16() {
@@ -413,11 +524,24 @@ define("mojo/public/js/bindings/codec", function() {
Uint16.encodedSize = 2;
Uint16.decode = function(decoder) {
- return decoder.read16();
+ return decoder.readUint16();
};
Uint16.encode = function(encoder, val) {
- encoder.write16(val);
+ encoder.writeUint16(val);
+ };
+
+ function Int32() {
+ }
+
+ Int32.encodedSize = 4;
+
+ Int32.decode = function(decoder) {
+ return decoder.readInt32();
+ };
+
+ Int32.encode = function(encoder, val) {
+ encoder.writeInt32(val);
};
function Uint32() {
@@ -426,11 +550,24 @@ define("mojo/public/js/bindings/codec", function() {
Uint32.encodedSize = 4;
Uint32.decode = function(decoder) {
- return decoder.read32();
+ return decoder.readUint32();
};
Uint32.encode = function(encoder, val) {
- encoder.write32(val);
+ encoder.writeUint32(val);
+ };
+
+ function Int64() {
+ };
+
+ Int64.encodedSize = 8;
+
+ Int64.decode = function(decoder) {
+ return decoder.readInt64();
+ };
+
+ Int64.encode = function(encoder, val) {
+ encoder.writeInt64(val);
};
function Uint64() {
@@ -439,11 +576,11 @@ define("mojo/public/js/bindings/codec", function() {
Uint64.encodedSize = 8;
Uint64.decode = function(decoder) {
- return decoder.read64();
+ return decoder.readUint64();
};
Uint64.encode = function(encoder, val) {
- encoder.write64(val);
+ encoder.writeUint64(val);
};
function PointerTo(cls) {
@@ -496,6 +633,7 @@ define("mojo/public/js/bindings/codec", function() {
var exports = {};
exports.align = align;
+ exports.Buffer = Buffer;
exports.Message = Message;
exports.MessageBuilder = MessageBuilder;
exports.MessageWithRequestIDBuilder = MessageWithRequestIDBuilder;
@@ -505,9 +643,13 @@ define("mojo/public/js/bindings/codec", function() {
exports.kMessageHeaderSize = kMessageHeaderSize;
exports.kMessageExpectsResponse = kMessageExpectsResponse;
exports.kMessageIsResponse = kMessageIsResponse;
+ exports.Int8 = Int8;
exports.Uint8 = Uint8;
+ exports.Int16 = Int16;
exports.Uint16 = Uint16;
+ exports.Int32 = Int32;
exports.Uint32 = Uint32;
+ exports.Int64 = Int64;
exports.Uint64 = Uint64;
exports.PointerTo = PointerTo;
exports.ArrayOf = ArrayOf;
diff --git a/mojo/public/js/bindings/connector.js b/mojo/public/js/bindings/connector.js
index f2ccb04c2e..51fb7fe96b 100644
--- a/mojo/public/js/bindings/connector.js
+++ b/mojo/public/js/bindings/connector.js
@@ -4,8 +4,8 @@
define("mojo/public/js/bindings/connector", [
"mojo/public/js/bindings/codec",
- "mojo/bindings/js/core",
- "mojo/bindings/js/support",
+ "mojo/public/js/bindings/core",
+ "mojo/public/js/bindings/support",
], function(codec, core, support) {
function Connector(handle) {
@@ -38,10 +38,9 @@ define("mojo/public/js/bindings/connector", [
return true;
var result = core.writeMessage(this.handle_,
- message.memory,
+ new Uint8Array(message.buffer.arrayBuffer),
message.handles,
core.WRITE_MESSAGE_FLAG_NONE);
-
switch (result) {
case core.RESULT_OK:
// The handles were successfully transferred, so we don't own them
@@ -96,11 +95,11 @@ define("mojo/public/js/bindings/connector", [
this.errorHandler_.onError(read.result);
return;
}
- // TODO(abarth): Should core.readMessage return a Uint8Array?
- var memory = new Uint8Array(read.buffer);
- var message = new codec.Message(memory, read.handles);
- if (this.incomingReceiver_)
- this.incomingReceiver_.accept(message);
+ var buffer = new codec.Buffer(read.buffer);
+ var message = new codec.Message(buffer, read.handles);
+ if (this.incomingReceiver_) {
+ this.incomingReceiver_.accept(message);
+ }
}
};
diff --git a/mojo/public/js/bindings/core.js b/mojo/public/js/bindings/core.js
new file mode 100644
index 0000000000..389681af2d
--- /dev/null
+++ b/mojo/public/js/bindings/core.js
@@ -0,0 +1,215 @@
+// 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/public/js/bindings/core"
+//
+// Note: This file is for documentation purposes only. The code here is not
+// actually executed. The real module is implemented natively in Mojo.
+//
+// This module provides the JavaScript bindings for mojo/public/c/system/core.h.
+// Refer to that file for more detailed documentation for equivalent methods.
+
+while (1);
+
+/**
+ * MojoHandle: An opaque handles to a Mojo object (e.g. a message pipe).
+ */
+var kInvalidHandle;
+
+/**
+ * MojoResult {number}: Result codes for Mojo operations.
+ * See core.h for more information.
+ */
+var RESULT_OK;
+var RESULT_CANCELLED;
+var RESULT_UNKNOWN;
+var RESULT_INVALID_ARGUMENT;
+var RESULT_DEADLINE_EXCEEDED;
+var RESULT_NOT_FOUND;
+var RESULT_ALREADY_EXISTS;
+var RESULT_PERMISSION_DENIED;
+var RESULT_RESOURCE_EXHAUSTED;
+var RESULT_FAILED_PRECONDITION;
+var RESULT_ABORTED;
+var RESULT_OUT_OF_RANGE;
+var RESULT_UNIMPLEMENTED;
+var RESULT_INTERNAL;
+var RESULT_UNAVAILABLE;
+var RESULT_DATA_LOSS;
+var RESULT_BUSY;
+var RESULT_SHOULD_WAIT;
+
+/**
+ * MojoDeadline {number}: Used to specify deadlines (timeouts), in microseconds.
+ * See core.h for more information.
+ */
+var DEADLINE_INDEFINITE;
+
+/**
+ * MojoWaitFlags: Used to specify the state of a handle to wait on (e.g., the
+ * ability to read or write to it).
+ * See core.h for more information.
+ */
+var WAIT_FLAG_NONE;
+var WAIT_FLAG_READABLE;
+var WAIT_FLAG_WRITABLE;
+var WAIT_FLAG_EVERYTHING;
+
+/*
+ * MojoWriteMessageFlags: Used to specify different modes to |writeMessage()|.
+ * See core.h for more information.
+ */
+var WRITE_MESSAGE_FLAG_NONE;
+
+/**
+ * MojoReadMessageFlags: Used to specify different modes to |readMessage()|.
+ * See core.h for more information.
+ */
+var READ_MESSAGE_FLAG_NONE;
+var READ_MESSAGE_FLAG_MAY_DISCARD;
+
+/**
+ * MojoCreateDataPipeOptions: Used to specify creation parameters for a data
+ * pipe to |createDataPipe()|.
+ * See core.h for more information.
+ */
+dictionary MojoCreateDataPipeOptions {
+ MojoCreateDataPipeOptionsFlags flags; // See below.
+ int32 elementNumBytes; // The size of an element, in bytes.
+ int32 capacityNumBytes; // The capacity of the data pipe, in bytes.
+};
+
+// MojoCreateDataPipeOptionsFlags
+var CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
+var CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD;
+
+/*
+ * MojoWriteDataFlags: Used to specify different modes to |writeData()|.
+ * See core.h for more information.
+ */
+var WRITE_DATA_FLAG_NONE;
+var WRITE_DATA_FLAG_ALL_OR_NONE;
+
+/**
+ * MojoReadDataFlags: Used to specify different modes to |readData()|.
+ * See core.h for more information.
+ */
+var READ_DATA_FLAG_NONE;
+var READ_DATA_FLAG_ALL_OR_NONE;
+var READ_DATA_FLAG_DISCARD;
+var READ_DATA_FLAG_QUERY;
+
+/**
+ * Closes the given |handle|. See MojoClose for more info.
+ * @param {MojoHandle} Handle to close.
+ * @return {MojoResult} Result code.
+ */
+function close(handle) { [native code] }
+
+/**
+ * Waits on the given handle until the state indicated by |waitFlags| is
+ * satisfied or until |deadline| is passed. See MojoWait for more information.
+ *
+ * @param {MojoHandle} handle Handle to wait on.
+ * @param {MojoWaitFlags} waitFlags Specifies the condition to wait for.
+ * @param {MojoDeadline} deadline Stops waiting if this is reached.
+ * @return {MojoResult} Result code.
+ */
+function wait(handle, waitFlags, deadline) { [native code] }
+
+/**
+ * Waits on |handles[0]|, ..., |handles[handles.length-1]| for at least one of
+ * them to satisfy the state indicated by |flags[0]|, ...,
+ * |flags[handles.length-1]|, respectively, or until |deadline| has passed.
+ * See MojoWaitMany for more information.
+ *
+ * @param {Array.MojoHandle} handles Handles to wait on.
+ * @param {Array.MojoWaitFlags} waitFlags Specifies the condition to wait for,
+ * for each corresponding handle. Must be the same length as |handles|.
+ * @param {MojoDeadline} deadline Stops waiting if this is reached.
+ * @return {MojoResult} Result code.
+ */
+function waitMany(handles, waitFlags, deadline) { [native code] }
+
+/**
+ * Creates a message pipe. This function always succeeds.
+ * See MojoCreateMessagePipe for more information on message pipes.
+ *
+ * @return {MessagePipe} An object of the form {
+ * handle0,
+ * handle1,
+ * }
+ * where |handle0| and |handle1| are MojoHandles to each end of the channel.
+ */
+function createMessagePipe() { [native code] }
+
+/**
+ * Writes a message to the message pipe endpoint given by |handle|. See
+ * MojoWriteMessage for more information, including return codes.
+ *
+ * @param {MojoHandle} handle The endpoint to write to.
+ * @param {ArrayBufferView} buffer The message data. May be empty.
+ * @param {Array.MojoHandle} handlesArray Any handles to attach. Handles are
+ * transferred on success and will no longer be valid. May be empty.
+ * @param {MojoWriteMessageFlags} flags Flags.
+ * @return {MojoResult} Result code.
+ */
+function writeMessage(handle, buffer, handlesArray, flags) { [native code] }
+
+/**
+ * Reads a message from the message pipe endpoint given by |handle|. See
+ * MojoReadMessage for more information, including return codes.
+ *
+ * @param {MojoHandle} handle The endpoint to read from.
+ * @param {MojoReadMessageFlags} flags Flags.
+ * @return {object} An object of the form {
+ * result, // |RESULT_OK| on success, error code otherwise.
+ * buffer, // An ArrayBufferView of the message data (only on success).
+ * handles // An array of MojoHandles transferred, if any.
+ * }
+ */
+function readMessage(handle, flags) { [native code] }
+
+/**
+ * Creates a data pipe, which is a unidirectional communication channel for
+ * unframed data, with the given options. See MojoCreateDataPipe for more
+ * more information, including return codes.
+ *
+ * @param {MojoCreateDataPipeOptions} optionsDict Options to control the data
+ * pipe parameters. May be null.
+ * @return {object} An object of the form {
+ * result, // |RESULT_OK| on success, error code otherwise.
+ * producerHandle, // MojoHandle to use with writeData (only on success).
+ * consumerHandle, // MojoHandle to use with readData (only on success).
+ * }
+ */
+function createDataPipe(optionsDict) { [native code] }
+
+/**
+ * Writes the given data to the data pipe producer given by |handle|. See
+ * MojoWriteData for more information, including return codes.
+ *
+ * @param {MojoHandle} handle A producerHandle returned by createDataPipe.
+ * @param {ArrayBufferView} buffer The data to write.
+ * @param {MojoWriteDataFlags} flags Flags.
+ * @return {object} An object of the form {
+ * result, // |RESULT_OK| on success, error code otherwise.
+ * numBytes, // The number of bytes written.
+ * }
+ */
+function writeData(handle, buffer, flags) { [native code] }
+
+/**
+ * Reads data from the data pipe consumer given by |handle|. May also
+ * be used to discard data. See MojoReadData for more information, including
+ * return codes.
+ *
+ * @param {MojoHandle} handle A consumerHandle returned by createDataPipe.
+ * @param {MojoReadDataFlags} flags Flags.
+ * @return {object} An object of the form {
+ * result, // |RESULT_OK| on success, error code otherwise.
+ * buffer, // An ArrayBufferView of the data read (only on success).
+ * }
+ */
+function readData(handle, flags) { [native code] }
diff --git a/mojo/public/js/bindings/support.js b/mojo/public/js/bindings/support.js
new file mode 100644
index 0000000000..756e7ba70c
--- /dev/null
+++ b/mojo/public/js/bindings/support.js
@@ -0,0 +1,30 @@
+// 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/public/js/bindings/support"
+//
+// Note: This file is for documentation purposes only. The code here is not
+// actually executed. The real module is implemented natively in Mojo.
+
+while (1);
+
+/*
+ * Waits on the given handle until the state indicated by |waitFlags| is
+ * satisfied.
+ *
+ * @param {MojoHandle} handle The handle to wait on.
+ * @param {MojoWaitFlags} waitFlags Flags.
+ * @param {function (mojoResult)} callback Called with the result the wait is
+ * complete. See MojoWait for possible result codes.
+ *
+ * @return {MojoWaitId} A waitId that can be passed to cancelWait to cancel the
+ * wait.
+ */
+function asyncWait(handle, waitFlags, callback) { [native code] }
+
+/*
+ * Cancels the asyncWait operation specified by the given |waitId|.
+ * @param {MojoWaitId} waitId The waitId returned by asyncWait.
+ */
+function cancelWait(waitId) { [native code] }
diff --git a/mojo/public/js/bindings/unicode.js b/mojo/public/js/bindings/unicode.js
new file mode 100644
index 0000000000..a42c710be4
--- /dev/null
+++ b/mojo/public/js/bindings/unicode.js
@@ -0,0 +1,33 @@
+// 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/public/js/bindings/unicode"
+//
+// Note: This file is for documentation purposes only. The code here is not
+// actually executed. The real module is implemented natively in Mojo.
+
+while (1);
+
+/**
+ * Decodes the UTF8 string from the given buffer.
+ * @param {ArrayBufferView} buffer The buffer containing UTF8 string data.
+ * @return {string} The corresponding JavaScript string.
+ */
+function decodeUtf8String(buffer) { [native code] }
+
+/**
+ * Encodes the given JavaScript string into UTF8.
+ * @param {string} str The string to encode.
+ * @param {ArrayBufferView} outputBuffer The buffer to contain the result.
+ * Should be pre-allocated to hold enough space. Use |utf8Length| to determine
+ * how much space is required.
+ * @return {number} The number of bytes written to |outputBuffer|.
+ */
+function encodeUtf8String(str, outputBuffer) { [native code] }
+
+/**
+ * Returns the number of bytes that a UTF8 encoding of the JavaScript string
+ * |str| would occupy.
+ */
+function utf8Length(str) { [native code] }
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl
new file mode 100644
index 0000000000..3096839321
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl
@@ -0,0 +1,5 @@
+template <> struct TypeTraits<{% for namespace in namespaces_as_array -%}
+{{namespace}}::{% endfor %}{{enum.name}}> {
+ static const bool kIsHandle = false;
+ static const bool kIsObject = false;
+};
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
index 5b61e173ca..60fbfc52c7 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
@@ -23,12 +23,6 @@ class {{interface.name}} {
{#--- Methods #}
{%- for method in interface.methods %}
- virtual void {{method.name}}({{interface_macros.declare_request_params(method)}}) = 0;
+ virtual void {{method.name}}({{interface_macros.declare_request_params("", method)}}) = 0;
{%- endfor %}
};
-
-// A typesafe variant of MessagePipeHandle.
-typedef mojo::Interface<{{interface.name}}>::Handle {{interface.name}}Handle;
-
-// A typesafe variant of ScopedMessagePipeHandle.
-typedef mojo::Interface<{{interface.name}}>::ScopedHandle Scoped{{interface.name}}Handle;
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index 906099cd18..4910463d80 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -97,7 +97,7 @@ bool {{class_name}}_{{method.name}}_ForwardToCallback::Accept(
{%- set params_name =
"internal::%s_%s_Params_Data"|format(interface.name, method.name) %}
void {{proxy_name}}::{{method.name}}(
- {{interface_macros.declare_request_params(method)}}) {
+ {{interface_macros.declare_request_params("in_", method)}}) {
{{compute_payload_size(params_name, method.parameters)}}
{%- if method.response_parameters != None %}
@@ -140,7 +140,7 @@ class {{class_name}}_{{method.name}}_ProxyToResponder
responder_(responder) {
}
- virtual void Run({{interface_macros.declare_params(method.response_parameters)}}) const;
+ virtual void Run({{interface_macros.declare_params("in_", method.response_parameters)}}) const;
private:
uint64_t request_id_;
@@ -148,7 +148,7 @@ class {{class_name}}_{{method.name}}_ProxyToResponder
MOJO_DISALLOW_COPY_AND_ASSIGN({{class_name}}_{{method.name}}_ProxyToResponder);
};
void {{class_name}}_{{method.name}}_ProxyToResponder::Run(
- {{interface_macros.declare_params(method.response_parameters)}}) const {
+ {{interface_macros.declare_params("in_", method.response_parameters)}}) const {
{{compute_payload_size(params_name, method.response_parameters)}}
mojo::internal::ResponseMessageBuilder builder(
{{message_name}}, payload_size, request_id_);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
index 70b6091821..fbefce2d39 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
@@ -1,6 +1,6 @@
-{%- macro declare_params(parameters) %}
+{%- macro declare_params(prefix, parameters) %}
{%- for param in parameters -%}
-{{param.kind|cpp_const_wrapper_type}} in_{{param.name}}
+{{param.kind|cpp_const_wrapper_type}} {{prefix}}{{param.name}}
{%- if not loop.last %}, {% endif %}
{%- endfor %}
{%- endmacro %}
@@ -14,8 +14,8 @@ mojo::Callback<void(
)>
{%- endmacro -%}
-{%- macro declare_request_params(method) -%}
-{{declare_params(method.parameters)}}
+{%- macro declare_request_params(prefix, method) -%}
+{{declare_params(prefix, method.parameters)}}
{%- if method.response_parameters != None -%}
{%- if method.parameters %}, {% endif %}
const {{declare_callback(method)}}& callback
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl
index ff7c327c6d..c4a8bed632 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl
@@ -5,7 +5,7 @@ class {{interface.name}}Proxy : public {{interface.name}} {
{%- for method in interface.methods %}
virtual void {{method.name}}(
- {{interface_macros.declare_request_params(method)}}
+ {{interface_macros.declare_request_params("", method)}}
) MOJO_OVERRIDE;
{%- endfor %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
index e804fc638d..df545a8810 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
@@ -13,9 +13,9 @@
#include "{{import.module.path}}-internal.h"
{%- endfor %}
-{%- if namespace %}
+{%- for namespace in namespaces_as_array %}
namespace {{namespace}} {
-{%- endif %}
+{%- endfor %}
{#--- Wrapper forward declarations #}
{% for struct in structs %}
@@ -34,8 +34,8 @@ namespace internal {
#pragma pack(pop)
} // namespace internal
-{%- if namespace %}
+{%- for namespace in namespaces_as_array|reverse %}
} // namespace {{namespace}}
-{%- endif %}
+{%- endfor %}
#endif // {{header_guard}}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index d99a3e2424..4e423aa844 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -12,9 +12,9 @@
#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
-{%- if namespace %}
+{%- for namespace in namespaces_as_array %}
namespace {{namespace}} {
-{%- endif %}
+{%- endfor %}
namespace internal {
namespace {
@@ -59,9 +59,9 @@ const uint32_t {{method_name}} = {{method.ordinal}};
{%- for interface in interfaces %}
{%- include "interface_definition.tmpl" %}
{%- endfor %}
-{%- if namespace %}
+{%- for namespace in namespaces_as_array|reverse %}
} // namespace {{namespace}}
-{%- endif %}
+{%- endfor %}
#if defined(__clang__)
#pragma clang diagnostic pop
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index c2233861c3..4c667aee9d 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -16,15 +16,24 @@
#include "{{import.module.path}}.h"
{%- endfor %}
-{%- if namespace %}
+{%- for namespace in namespaces_as_array %}
namespace {{namespace}} {
-{%- endif %}
+{%- endfor %}
{#--- Enums #}
{% for enum in enums %}
{% include "enum_declaration.tmpl" %}
{%- endfor %}
+{#--- Interface Forward Declarations -#}
+{% for interface in interfaces %}
+class {{interface.name}};
+// A typesafe variant of MessagePipeHandle:
+typedef mojo::Interface<{{interface.name}}>::Handle {{interface.name}}Handle;
+// A typesafe variant of ScopedMessagePipeHandle:
+typedef mojo::Interface<{{interface.name}}>::ScopedHandle Scoped{{interface.name}}Handle;
+{% endfor %}
+
{#--- Structs #}
{% for struct in structs %}
{% include "wrapper_class_declaration.tmpl" %}
@@ -45,8 +54,19 @@ namespace {{namespace}} {
{% include "interface_stub_declaration.tmpl" %}
{%- endfor %}
-{%- if namespace %}
+{%- for namespace in namespaces_as_array|reverse %}
} // namespace {{namespace}}
+{%- endfor %}
+
+{#--- Enum TypeTraits Specializations #}
+{% if enums %}
+namespace mojo {
+namespace internal {
+{% for enum in enums %}
+{% include "enum_traits.tmpl" %}
+{%- endfor %}
+} // namespace internal
+} // namespace mojo
{%- endif %}
#endif // {{header_guard}}
diff --git a/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl b/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl
index 08c5a9721f..9b3046825c 100644
--- a/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl
@@ -3,7 +3,7 @@
// found in the LICENSE file.
define("{{module.path}}", [
- "mojo/bindings/js/core",
+ "mojo/public/js/bindings/core",
"mojo/public/js/bindings/codec",
{%- for import in imports %}
"{{import.module.path}}",
diff --git a/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl
index 1686820a7e..6db102ce8e 100644
--- a/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl
@@ -74,11 +74,11 @@ this.{{packed_field.field.name}} = {{result}};
{{struct.name}}.decode = function(decoder) {
var packed;
var val = new {{struct.name}}();
- var numberOfBytes = decoder.read32();
- var numberOfFields = decoder.read32();
+ var numberOfBytes = decoder.readUint32();
+ var numberOfFields = decoder.readUint32();
{%- for byte in struct.bytes %}
{%- if byte.packed_fields|length > 1 %}
- packed = decoder.read8();
+ packed = decoder.readUint8();
{%- for packed_field in byte.packed_fields %}
val.{{packed_field.field.name}} = (packed >> {{packed_field.bit}}) & 1 ? true : false;
{%- endfor %}
@@ -96,8 +96,8 @@ this.{{packed_field.field.name}} = {{result}};
{{struct.name}}.encode = function(encoder, val) {
var packed;
- encoder.write32({{struct.name}}.encodedSize);
- encoder.write32({{struct.packed.packed_fields|length}});
+ encoder.writeUint32({{struct.name}}.encodedSize);
+ encoder.writeUint32({{struct.packed.packed_fields|length}});
{%- for byte in struct.bytes %}
{%- if byte.packed_fields|length > 1 %}
@@ -105,7 +105,7 @@ this.{{packed_field.field.name}} = {{result}};
{%- for packed_field in byte.packed_fields %}
packed |= (val.{{packed_field.field.name}} & 1) << {{packed_field.bit}}
{%- endfor %}
- encoder.write8(packed);
+ encoder.writeUint8(packed);
{%- else %}
{%- for packed_field in byte.packed_fields %}
encoder.{{packed_field.field.kind|encode_snippet}}val.{{packed_field.field.name}});
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index a95e711d85..8f48f8e06f 100644
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -4,11 +4,10 @@
"""Generates C++ source files from a mojom.Module."""
-from generate import mojom
-from generate import mojom_pack
-from generate import mojom_generator
-
-from generate.template_expander import UseJinja
+import mojom.generate.generator as generator
+import mojom.generate.module as mojom
+import mojom.generate.pack as pack
+from mojom.generate.template_expander import UseJinja
_kind_to_cpp_type = {
@@ -31,10 +30,13 @@ _kind_to_cpp_type = {
}
+def NamespaceToArray(namespace):
+ return namespace.split('.') if namespace else []
+
def GetNameForKind(kind, internal = False):
parts = []
if kind.imported_from:
- parts.append(kind.imported_from["namespace"])
+ parts.extend(NamespaceToArray(kind.imported_from["namespace"]))
if internal:
parts.append("internal")
if kind.parent_kind:
@@ -96,7 +98,7 @@ def GetCppWrapperType(kind):
return "mojo::Passable<%sHandle>" % kind.name
if kind.spec == 's':
return "mojo::String"
- if mojom_generator.IsHandleKind(kind):
+ if generator.IsHandleKind(kind):
return "mojo::Passable<%s>" % _kind_to_cpp_type[kind]
return _kind_to_cpp_type[kind]
@@ -141,7 +143,7 @@ def GetCppFieldType(kind):
def IsStructWithHandles(struct):
for pf in struct.packed.packed_fields:
- if mojom_generator.IsHandleKind(pf.field.kind):
+ if generator.IsHandleKind(pf.field.kind):
return True
return False
@@ -151,7 +153,7 @@ def TranslateConstants(token, module):
# Namespace::Struct::FIELD_NAME
name = []
if token.imported_from:
- name.append(token.namespace)
+ name.extend(NamespaceToArray(token.namespace))
if token.parent_kind:
name.append(token.parent_kind.name)
name.append(token.name[1])
@@ -161,12 +163,12 @@ def TranslateConstants(token, module):
def ExpressionToText(value, module):
if value[0] != "EXPRESSION":
raise Exception("Expected EXPRESSION, got" + value)
- return "".join(mojom_generator.ExpressionMapper(value,
+ return "".join(generator.ExpressionMapper(value,
lambda token: TranslateConstants(token, module)))
_HEADER_SIZE = 8
-class Generator(mojom_generator.Generator):
+class Generator(generator.Generator):
cpp_filters = {
"cpp_const_wrapper_type": GetCppConstWrapperType,
@@ -175,24 +177,25 @@ class Generator(mojom_generator.Generator):
"cpp_result_type": GetCppResultWrapperType,
"cpp_wrapper_type": GetCppWrapperType,
"expression_to_text": ExpressionToText,
- "get_pad": mojom_pack.GetPad,
- "is_enum_kind": mojom_generator.IsEnumKind,
- "is_handle_kind": mojom_generator.IsHandleKind,
- "is_object_kind": mojom_generator.IsObjectKind,
- "is_string_kind": mojom_generator.IsStringKind,
+ "get_pad": pack.GetPad,
+ "is_enum_kind": generator.IsEnumKind,
+ "is_handle_kind": generator.IsHandleKind,
+ "is_object_kind": generator.IsObjectKind,
+ "is_string_kind": generator.IsStringKind,
"is_array_kind": lambda kind: isinstance(kind, mojom.Array),
"is_struct_with_handles": IsStructWithHandles,
"struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE,
- "struct_from_method": mojom_generator.GetStructFromMethod,
- "response_struct_from_method": mojom_generator.GetResponseStructFromMethod,
- "stylize_method": mojom_generator.StudlyCapsToCamel,
- "verify_token_type": mojom_generator.VerifyTokenType,
+ "struct_from_method": generator.GetStructFromMethod,
+ "response_struct_from_method": generator.GetResponseStructFromMethod,
+ "stylize_method": generator.StudlyCapsToCamel,
+ "verify_token_type": generator.VerifyTokenType,
}
def GetJinjaExports(self):
return {
"module": self.module,
"namespace": self.module.namespace,
+ "namespaces_as_array": NamespaceToArray(self.module.namespace),
"imports": self.module.imports,
"kinds": self.module.kinds,
"enums": self.module.enums,
diff --git a/mojo/public/tools/bindings/generators/mojom_js_generator.py b/mojo/public/tools/bindings/generators/mojom_js_generator.py
index b3d572f27c..53672a2677 100644
--- a/mojo/public/tools/bindings/generators/mojom_js_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -4,11 +4,10 @@
"""Generates JavaScript source files from a mojom.Module."""
-from generate import mojom
-from generate import mojom_pack
-from generate import mojom_generator
-
-from generate.template_expander import UseJinja
+import mojom.generate.generator as generator
+import mojom.generate.module as mojom
+import mojom.generate.pack as pack
+from mojom.generate.template_expander import UseJinja
_kind_to_javascript_default_value = {
mojom.BOOL: "false",
@@ -52,7 +51,7 @@ def JavaScriptPayloadSize(packed):
return 0;
last_field = packed_fields[-1]
offset = last_field.offset + last_field.size
- pad = mojom_pack.GetPad(offset, 8)
+ pad = pack.GetPad(offset, 8)
return offset + pad;
@@ -92,21 +91,21 @@ def GetJavaScriptType(kind):
_kind_to_javascript_decode_snippet = {
- mojom.BOOL: "read8() & 1",
- mojom.INT8: "read8()",
- mojom.UINT8: "read8()",
- mojom.INT16: "read16()",
- mojom.UINT16: "read16()",
- mojom.INT32: "read32()",
- mojom.UINT32: "read32()",
+ mojom.BOOL: "readUint8() & 1",
+ mojom.INT8: "readInt8()",
+ mojom.UINT8: "readUint8()",
+ mojom.INT16: "readInt16()",
+ mojom.UINT16: "readUint16()",
+ mojom.INT32: "readInt32()",
+ mojom.UINT32: "readUint32()",
mojom.FLOAT: "decodeFloat()",
mojom.HANDLE: "decodeHandle()",
mojom.DCPIPE: "decodeHandle()",
mojom.DPPIPE: "decodeHandle()",
mojom.MSGPIPE: "decodeHandle()",
mojom.SHAREDBUFFER: "decodeHandle()",
- mojom.INT64: "read64()",
- mojom.UINT64: "read64()",
+ mojom.INT64: "readInt64()",
+ mojom.UINT64: "readUint64()",
mojom.DOUBLE: "decodeDouble()",
mojom.STRING: "decodeStringPointer()",
}
@@ -126,21 +125,21 @@ def JavaScriptDecodeSnippet(kind):
_kind_to_javascript_encode_snippet = {
- mojom.BOOL: "write8(1 & ",
- mojom.INT8: "write8(",
- mojom.UINT8: "write8(",
- mojom.INT16: "write16(",
- mojom.UINT16: "write16(",
- mojom.INT32: "write32(",
- mojom.UINT32: "write32(",
+ mojom.BOOL: "writeUint8(1 & ",
+ mojom.INT8: "writeInt8(",
+ mojom.UINT8: "writeUint8(",
+ mojom.INT16: "writeInt16(",
+ mojom.UINT16: "writeUint16(",
+ mojom.INT32: "writeInt32(",
+ mojom.UINT32: "writeUint32(",
mojom.FLOAT: "encodeFloat(",
mojom.HANDLE: "encodeHandle(",
mojom.DCPIPE: "encodeHandle(",
mojom.DPPIPE: "encodeHandle(",
mojom.MSGPIPE: "encodeHandle(",
mojom.SHAREDBUFFER: "encodeHandle(",
- mojom.INT64: "write64(",
- mojom.UINT64: "write64(",
+ mojom.INT64: "writeInt64(",
+ mojom.UINT64: "writeUint64(",
mojom.DOUBLE: "encodeDouble(",
mojom.STRING: "encodeStringPointer(",
}
@@ -177,7 +176,7 @@ def TranslateConstants(token, module):
def ExpressionToText(value, module):
if value[0] != "EXPRESSION":
raise Exception("Expected EXPRESSION, got" + value)
- return "".join(mojom_generator.ExpressionMapper(value,
+ return "".join(generator.ExpressionMapper(value,
lambda token: TranslateConstants(token, module)))
@@ -187,7 +186,7 @@ def JavascriptType(kind):
return kind.name
-class Generator(mojom_generator.Generator):
+class Generator(generator.Generator):
js_filters = {
"default_value": JavaScriptDefaultValue,
@@ -195,12 +194,12 @@ class Generator(mojom_generator.Generator):
"decode_snippet": JavaScriptDecodeSnippet,
"encode_snippet": JavaScriptEncodeSnippet,
"expression_to_text": ExpressionToText,
- "is_object_kind": mojom_generator.IsObjectKind,
- "is_string_kind": mojom_generator.IsStringKind,
+ "is_object_kind": generator.IsObjectKind,
+ "is_string_kind": generator.IsStringKind,
"is_array_kind": lambda kind: isinstance(kind, mojom.Array),
"js_type": JavascriptType,
- "stylize_method": mojom_generator.StudlyCapsToCamel,
- "verify_token_type": mojom_generator.VerifyTokenType,
+ "stylize_method": generator.StudlyCapsToCamel,
+ "verify_token_type": generator.VerifyTokenType,
}
@UseJinja("js_templates/module.js.tmpl", filters=js_filters)
diff --git a/mojo/public/tools/bindings/generators/run_cpp_generator.py b/mojo/public/tools/bindings/generators/run_cpp_generator.py
index 36ef8bc9ed..8a80a46839 100755
--- a/mojo/public/tools/bindings/generators/run_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/run_cpp_generator.py
@@ -10,7 +10,7 @@ import sys
script_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(script_dir, os.pardir, "pylib"))
-from generate import mojom_data
+from mojom.generate.data
import mojom_cpp_generator
def ReadDict(file):
@@ -20,7 +20,7 @@ def ReadDict(file):
return dict
dict = ReadDict(sys.argv[1])
-module = mojom_data.ModuleFromData(dict)
+module = mojom.generate.data.ModuleFromData(dict)
dir = None
if len(sys.argv) > 2:
dir = sys.argv[2]
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.gypi b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
index 5778c9ccc7..de20ce4b24 100644
--- a/mojo/public/tools/bindings/mojom_bindings_generator.gypi
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
@@ -39,16 +39,17 @@
'<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py',
'<(DEPTH)/mojo/public/tools/bindings/generators/mojom_js_generator.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/parse/__init__.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/parse/mojo_parser.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/parse/mojo_translate.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/generate/__init__.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/generate/mojom.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/generate/mojom_data.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/generate/mojom_generator.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/generate/mojom_pack.py',
- '<(DEPTH)/mojo/public/tools/bindings/pylib/generate/template_expander.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py',
+ '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom.cc',
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py
index a9d8b681e6..643f46840a 100755
--- a/mojo/public/tools/bindings/mojom_bindings_generator.py
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -12,13 +12,13 @@ import os
import pprint
import sys
-script_dir = os.path.dirname(os.path.realpath(__file__))
+script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(script_dir, "pylib"))
-from generate import mojom_data
-from parse import mojo_lexer
-from parse import mojo_parser
-from parse import mojo_translate
+from mojom.generate.data import OrderedModuleFromData
+from mojom.parse.lexer import LexError
+from mojom.parse.parser import Parse, ParseError
+from mojom.parse.translate import Translate
def LoadGenerators(generators_string):
@@ -46,11 +46,13 @@ def LoadGenerators(generators_string):
return generators
-def _PrintImportStack(imported_filename_stack):
- """Prints a chain of imports, given by imported_filename_stack."""
- for i in reversed(xrange(0, len(imported_filename_stack)-1)):
- print " %s was imported by %s" % (imported_filename_stack[i+1],
- imported_filename_stack[i])
+def MakeImportStackMessage(imported_filename_stack):
+ """Make a (human-readable) message listing a chain of imports. (Returned
+ string begins with a newline (if nonempty) and does not end with one.)"""
+ return ''.join(
+ reversed(["\n %s was imported by %s" % (a, b) for (a, b) in \
+ zip(imported_filename_stack[1:], imported_filename_stack)]))
+
def ProcessFile(args, generator_modules, filename, processed_files={},
imported_filename_stack=[]):
@@ -60,27 +62,26 @@ def ProcessFile(args, generator_modules, filename, processed_files={},
# Ensure we only visit each file once.
if filename in imported_filename_stack:
- print "%s: Error: Circular dependency" % filename
- _PrintImportStack(imported_filename_stack + [filename])
+ print "%s: Error: Circular dependency" % filename + \
+ MakeImportStackMessage(imported_filename_stack + [filename])
sys.exit(1)
try:
with open(filename) as f:
source = f.read()
except IOError as e:
- print "%s: Error: %s" % (e.filename, e.strerror)
- _PrintImportStack(imported_filename_stack + [filename])
+ print "%s: Error: %s" % (e.filename, e.strerror) + \
+ MakeImportStackMessage(imported_filename_stack + [filename])
sys.exit(1)
try:
- tree = mojo_parser.Parse(source, filename)
- except (mojo_lexer.LexError, mojo_parser.ParseError) as e:
- print e
- _PrintImportStack(imported_filename_stack + [filename])
+ tree = Parse(source, filename)
+ except (LexError, ParseError) as e:
+ print str(e) + MakeImportStackMessage(imported_filename_stack + [filename])
sys.exit(1)
dirname, name = os.path.split(filename)
- mojom = mojo_translate.Translate(tree, name)
+ mojom = Translate(tree, name)
if args.debug_print_intermediate:
pprint.PrettyPrinter().pprint(mojom)
@@ -93,7 +94,7 @@ def ProcessFile(args, generator_modules, filename, processed_files={},
processed_files=processed_files,
imported_filename_stack=imported_filename_stack + [filename])
- module = mojom_data.OrderedModuleFromData(mojom)
+ module = OrderedModuleFromData(mojom)
# Set the path as relative to the source root.
module.path = os.path.relpath(os.path.abspath(filename),
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py b/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py
new file mode 100644
index 0000000000..de388561cb
--- /dev/null
+++ b/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py
@@ -0,0 +1,23 @@
+# 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 unittest
+
+from mojom_bindings_generator import MakeImportStackMessage
+
+
+class MojoBindingsGeneratorTest(unittest.TestCase):
+ """Tests mojo_bindings_generator."""
+
+ def testMakeImportStackMessage(self):
+ """Tests MakeImportStackMessage()."""
+ self.assertEquals(MakeImportStackMessage(["x"]), "")
+ self.assertEquals(MakeImportStackMessage(["x", "y"]),
+ "\n y was imported by x")
+ self.assertEquals(MakeImportStackMessage(["x", "y", "z"]),
+ "\n z was imported by y\n y was imported by x")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/mojo/public/tools/bindings/pylib/parse/__init__.py b/mojo/public/tools/bindings/pylib/mojom/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/mojo/public/tools/bindings/pylib/parse/__init__.py
+++ b/mojo/public/tools/bindings/pylib/mojom/__init__.py
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py b/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_data.py b/mojo/public/tools/bindings/pylib/mojom/generate/data.py
index ce9bc182ce..ffbffde606 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_data.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/data.py
@@ -2,10 +2,13 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojom
+# TODO(vtl): "data" is a pretty vague name. Rename it?
+
import copy
-# mojom_data provides a mechanism to turn mojom Modules to dictionaries and
+import module as mojom
+
+# This module provides a mechanism to turn mojom Modules to dictionaries and
# back again. This can be used to persist a mojom Module created progromatically
# or to read a dictionary from code or a file.
# Example:
@@ -26,7 +29,7 @@ import copy
# {'name': 'bar', 'kind': 'a:x:teststruct'}],
# 'ordinal': 42}]}]
# }
-# test_module = mojom_data.ModuleFromData(test_dict)
+# test_module = data.ModuleFromData(test_dict)
# Used to create a subclass of str that supports sorting by index, to make
# pretty printing maintain the order.
@@ -133,8 +136,8 @@ def StructFromData(module, data):
module.kinds[struct.spec] = struct
struct.enums = map(lambda enum:
EnumFromData(module, enum, struct), data['enums'])
- struct.fields = map(lambda field:
- FieldFromData(module, field, struct), data['fields'])
+ # Stash fields data here temporarily.
+ struct.fields_data = data['fields']
return struct
def FieldToData(field):
@@ -231,8 +234,8 @@ def InterfaceFromData(module, data):
module.kinds[interface.spec] = interface
interface.enums = map(lambda enum:
EnumFromData(module, enum, interface), data['enums'])
- interface.methods = map(lambda method:
- MethodFromData(module, method, interface), data['methods'])
+ # Stash methods data here temporarily.
+ interface.methods_data = data['methods']
return interface
def EnumFieldFromData(module, enum, data, parent_kind):
@@ -286,6 +289,8 @@ def ModuleFromData(data):
module.imports = map(
lambda import_data: ImportFromData(module, import_data),
data['imports'])
+
+ # First pass collects kinds.
module.enums = map(
lambda enum: EnumFromData(module, enum, None), data['enums'])
module.structs = map(
@@ -294,6 +299,17 @@ def ModuleFromData(data):
lambda interface: InterfaceFromData(module, interface),
data['interfaces'])
+ # Second pass expands fields and methods. This allows fields and parameters
+ # to refer to kinds defined anywhere in the mojom.
+ for struct in module.structs:
+ struct.fields = map(lambda field:
+ FieldFromData(module, field, struct), struct.fields_data)
+ del struct.fields_data
+ for interface in module.interfaces:
+ interface.methods = map(lambda method:
+ MethodFromData(module, method, interface), interface.methods_data)
+ del interface.methods_data
+
return module
def OrderedModuleFromData(data):
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_data_tests.py b/mojo/public/tools/bindings/pylib/mojom/generate/data_tests.py
index 7f622e4adf..bca7ed83cc 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_data_tests.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/data_tests.py
@@ -2,13 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojom_data
-import mojom_test
import sys
-EXPECT_EQ = mojom_test.EXPECT_EQ
-EXPECT_TRUE = mojom_test.EXPECT_TRUE
-RunTest = mojom_test.RunTest
+import data
+import test_support
+
+EXPECT_EQ = test_support.EXPECT_EQ
+EXPECT_TRUE = test_support.EXPECT_TRUE
+RunTest = test_support.RunTest
def DeepEquals(d1, d2):
@@ -54,22 +55,22 @@ test_dict = {
def TestRead():
- module = mojom_data.ModuleFromData(test_dict)
- return mojom_test.TestTestModule(module)
+ module = data.ModuleFromData(test_dict)
+ return test_support.TestTestModule(module)
def TestWrite():
- module = mojom_test.BuildTestModule()
- d = mojom_data.ModuleToData(module)
+ module = test_support.BuildTestModule()
+ d = data.ModuleToData(module)
return EXPECT_TRUE(DeepEquals(test_dict, d))
def TestWriteRead():
- module1 = mojom_test.BuildTestModule()
+ module1 = test_support.BuildTestModule()
- dict1 = mojom_data.ModuleToData(module1)
- module2 = mojom_data.ModuleFromData(dict1)
- return EXPECT_TRUE(mojom_test.ModulesAreEqual(module1, module2))
+ dict1 = data.ModuleToData(module1)
+ module2 = data.ModuleFromData(dict1)
+ return EXPECT_TRUE(test_support.ModulesAreEqual(module1, module2))
def Main(args):
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_generator.py b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
index 131c248433..1984204d32 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_generator.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -4,11 +4,12 @@
"""Code shared by the various language-specific code generators."""
+from functools import partial
import os
-import mojom
-import mojom_pack
import re
-from functools import partial
+
+import module as mojom
+import pack
def GetStructFromMethod(interface, method):
"""Converts a method's parameters into the fields of a struct."""
@@ -16,7 +17,7 @@ def GetStructFromMethod(interface, method):
struct = mojom.Struct(params_class)
for param in method.parameters:
struct.AddField(param.name, param.kind, param.ordinal)
- struct.packed = mojom_pack.PackedStruct(struct)
+ struct.packed = pack.PackedStruct(struct)
return struct
def GetResponseStructFromMethod(interface, method):
@@ -25,12 +26,12 @@ def GetResponseStructFromMethod(interface, method):
struct = mojom.Struct(params_class)
for param in method.response_parameters:
struct.AddField(param.name, param.kind, param.ordinal)
- struct.packed = mojom_pack.PackedStruct(struct)
+ struct.packed = pack.PackedStruct(struct)
return struct
def GetStructInfo(exported, struct):
- struct.packed = mojom_pack.PackedStruct(struct)
- struct.bytes = mojom_pack.GetByteLayout(struct.packed)
+ struct.packed = pack.PackedStruct(struct)
+ struct.bytes = pack.GetByteLayout(struct.packed)
struct.exported = exported
return struct
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
index 4c5e413ebc..d24d36fbc0 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -2,11 +2,12 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-# mojom's classes provide an interface to mojo modules. Modules are collections
-# of interfaces and structs to be used by mojo ipc clients and servers.
+# This module's classes provide an interface to mojo modules. Modules are
+# collections of interfaces and structs to be used by mojo ipc clients and
+# servers.
#
# A simple interface would be created this way:
-# module = mojom.Module('Foo')
+# module = mojom.generate.module.Module('Foo')
# interface = module.AddInterface('Bar')
# method = interface.AddMethod('Tat', 0)
# method.AddParameter('baz', 0, mojom.INT32)
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_tests.py b/mojo/public/tools/bindings/pylib/mojom/generate/module_tests.py
index 58ef5fd60e..a887686e1b 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_tests.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/module_tests.py
@@ -2,15 +2,16 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojom_test
import sys
-EXPECT_EQ = mojom_test.EXPECT_EQ
-EXPECT_TRUE = mojom_test.EXPECT_TRUE
-RunTest = mojom_test.RunTest
-ModulesAreEqual = mojom_test.ModulesAreEqual
-BuildTestModule = mojom_test.BuildTestModule
-TestTestModule = mojom_test.TestTestModule
+import test_support
+
+EXPECT_EQ = test_support.EXPECT_EQ
+EXPECT_TRUE = test_support.EXPECT_TRUE
+RunTest = test_support.RunTest
+ModulesAreEqual = test_support.ModulesAreEqual
+BuildTestModule = test_support.BuildTestModule
+TestTestModule = test_support.TestTestModule
def BuildAndTestModule():
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_pack.py b/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
index c737eb651b..84378d7f1e 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_pack.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
@@ -2,12 +2,12 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojom
+import module as mojom
-# mojom_pack provides a mechanism for determining the packed order and offsets
+# This module provides a mechanism for determining the packed order and offsets
# of a mojom.Struct.
#
-# ps = mojom_pack.PackedStruct(struct)
+# ps = pack.PackedStruct(struct)
# ps.packed_fields will access a list of PackedField objects, each of which
# will have an offset, a size and a bit (for mojom.BOOLs).
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_pack_tests.py b/mojo/public/tools/bindings/pylib/mojom/generate/pack_tests.py
index 8b72562e39..4e61004e5f 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_pack_tests.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/pack_tests.py
@@ -2,14 +2,16 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojom
-import mojom_pack
-import mojom_test
import sys
-EXPECT_EQ = mojom_test.EXPECT_EQ
-EXPECT_TRUE = mojom_test.EXPECT_TRUE
-RunTest = mojom_test.RunTest
+import module as mojom
+import pack
+import test_support
+
+
+EXPECT_EQ = test_support.EXPECT_EQ
+EXPECT_TRUE = test_support.EXPECT_TRUE
+RunTest = test_support.RunTest
def TestOrdinalOrder():
@@ -17,7 +19,7 @@ def TestOrdinalOrder():
struct = mojom.Struct('test')
struct.AddField('testfield1', mojom.INT32, 2)
struct.AddField('testfield2', mojom.INT32, 1)
- ps = mojom_pack.PackedStruct(struct)
+ ps = pack.PackedStruct(struct)
errors += EXPECT_EQ(2, len(ps.packed_fields))
errors += EXPECT_EQ('testfield2', ps.packed_fields[0].field.name)
@@ -28,7 +30,7 @@ def TestOrdinalOrder():
def TestZeroFields():
errors = 0
struct = mojom.Struct('test')
- ps = mojom_pack.PackedStruct(struct)
+ ps = pack.PackedStruct(struct)
errors += EXPECT_EQ(0, len(ps.packed_fields))
return errors
@@ -37,7 +39,7 @@ def TestOneField():
errors = 0
struct = mojom.Struct('test')
struct.AddField('testfield1', mojom.INT8)
- ps = mojom_pack.PackedStruct(struct)
+ ps = pack.PackedStruct(struct)
errors += EXPECT_EQ(1, len(ps.packed_fields))
return errors
@@ -54,7 +56,7 @@ def TestSequence(kinds, fields, offsets):
for kind in kinds:
struct.AddField("%d" % index, kind)
index += 1
- ps = mojom_pack.PackedStruct(struct)
+ ps = pack.PackedStruct(struct)
num_fields = len(ps.packed_fields)
errors += EXPECT_EQ(len(kinds), num_fields)
for i in xrange(num_fields):
@@ -105,7 +107,7 @@ def TestPaddingPackedOutOfOrderByOrdinal():
struct.AddField('testfield1', mojom.INT8)
struct.AddField('testfield3', mojom.UINT8, 3)
struct.AddField('testfield2', mojom.INT32, 2)
- ps = mojom_pack.PackedStruct(struct)
+ ps = pack.PackedStruct(struct)
errors += EXPECT_EQ(3, len(ps.packed_fields))
# Second byte should be packed in behind first, altering order.
@@ -134,7 +136,7 @@ def TestBools():
struct.AddField('bit6', mojom.BOOL)
struct.AddField('bit7', mojom.BOOL)
struct.AddField('bit8', mojom.BOOL)
- ps = mojom_pack.PackedStruct(struct)
+ ps = pack.PackedStruct(struct)
errors += EXPECT_EQ(10, len(ps.packed_fields))
# First 8 bits packed together.
diff --git a/mojo/public/tools/bindings/pylib/generate/run_mojom_tests.py b/mojo/public/tools/bindings/pylib/mojom/generate/run_tests.py
index e57ef477e9..41f11a2b71 100755
--- a/mojo/public/tools/bindings/pylib/generate/run_mojom_tests.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/run_tests.py
@@ -22,9 +22,9 @@ def TestMojom(testname, args):
def main(args):
errors = 0
- errors += TestMojom('mojom_tests.py', ['--test'])
- errors += TestMojom('mojom_data_tests.py', ['--test'])
- errors += TestMojom('mojom_pack_tests.py', ['--test'])
+ errors += TestMojom('data_tests.py', ['--test'])
+ errors += TestMojom('module_tests.py', ['--test'])
+ errors += TestMojom('pack_tests.py', ['--test'])
if errors:
print '\nFailed tests.'
diff --git a/mojo/public/tools/bindings/pylib/generate/template_expander.py b/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py
index 1b3ee7489a..00c388e631 100644
--- a/mojo/public/tools/bindings/pylib/generate/template_expander.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py
@@ -9,12 +9,16 @@ import inspect
import os
import sys
-_current_dir = os.path.dirname(os.path.realpath(__file__))
-# jinja2 is in the third_party directory (current directory is
-# mojo/public/tools/bindings/pylib/generate).
-# Insert at front to override system libraries, and after path[0] == script dir
-sys.path.insert(1, os.path.join(_current_dir, os.pardir, os.pardir, os.pardir,
- os.pardir, os.pardir, os.pardir, 'third_party'))
+# jinja2 is in the third_party directory.
+# Insert at front to override system libraries, and after path[0] == script dir.
+path = os.path.abspath(__file__)
+while True:
+ path, tail = os.path.split(path)
+ assert tail
+ if tail == "mojo":
+ break
+sys.path.insert(1, os.path.join(path, "third_party"))
+del path, tail
import jinja2
diff --git a/mojo/public/tools/bindings/pylib/generate/mojom_test.py b/mojo/public/tools/bindings/pylib/mojom/generate/test_support.py
index a6b30a395a..93c8739cc7 100644
--- a/mojo/public/tools/bindings/pylib/generate/mojom_test.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/test_support.py
@@ -2,10 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojom
import sys
import traceback
+import module as mojom
+
# Support for writing mojom test cases.
# RunTest(fn) will execute fn, catching any exceptions. fn should return
# the number of errors that are encountered.
diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py b/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py
diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/ast.py b/mojo/public/tools/bindings/pylib/mojom/parse/ast.py
new file mode 100644
index 0000000000..bd398c18ec
--- /dev/null
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/ast.py
@@ -0,0 +1,25 @@
+# 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.
+
+"""Node objects for the AST for a Mojo IDL file."""
+
+# Note: For convenience of testing, you probably want to define __eq__() methods
+# for all node types; it's okay to be slightly lax (e.g., not compare filename
+# and lineno).
+
+
+class BaseNode(object):
+ def __init__(self, filename=None, lineno=None):
+ self.filename = filename
+ self.lineno = lineno
+
+
+class Ordinal(BaseNode):
+ """Represents an ordinal value labeling, e.g., a struct field."""
+ def __init__(self, value, **kwargs):
+ BaseNode.__init__(self, **kwargs)
+ self.value = value
+
+ def __eq__(self, other):
+ return self.value == other.value
diff --git a/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py b/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py
index 6704ae1d3f..10abedd451 100644
--- a/mojo/public/tools/bindings/pylib/parse/mojo_lexer.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py
@@ -2,9 +2,9 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import os.path
import re
import sys
-import os.path
# Try to load the ply module, if not, then assume it is in the third_party
# directory.
@@ -13,11 +13,16 @@ try:
# pylint: disable=F0401
from ply.lex import TOKEN
except ImportError:
- # This assumes this file is in src/mojo/public/tools/bindings/pylib/parse/.
- module_path, module_name = os.path.split(__file__)
- third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir,
- os.pardir, os.pardir, os.pardir, 'third_party')
- sys.path.append(third_party)
+ # Work our way up to the directory containing mojo/ (usually src/). (Note:
+ # Some builds don't check out into a directory called src/.)
+ path = os.path.abspath(__file__)
+ while True:
+ path, tail = os.path.split(path)
+ assert tail
+ if tail == "mojo":
+ break
+ sys.path.append(os.path.join(path, "third_party"))
+ del path, tail
# pylint: disable=F0401
from ply.lex import TOKEN
diff --git a/mojo/public/tools/bindings/pylib/parse/mojo_lexer_unittest.py b/mojo/public/tools/bindings/pylib/mojom/parse/lexer_unittest.py
index 18be667bef..a3b0222cbf 100644
--- a/mojo/public/tools/bindings/pylib/parse/mojo_lexer_unittest.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/lexer_unittest.py
@@ -2,7 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojo_lexer
+import os.path
+import sys
import unittest
# Try to load the ply module, if not, then assume it is in the third_party
@@ -12,14 +13,21 @@ try:
# pylint: disable=F0401
from ply import lex
except ImportError:
- # This assumes this file is in src/mojo/public/tools/bindings/pylib/parse/.
- module_path, module_name = os.path.split(__file__)
- third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir,
- os.pardir, os.pardir, os.pardir, 'third_party')
- sys.path.append(third_party)
+ # Work our way up to the directory containing mojo/ (usually src/). (Note:
+ # Some builds don't check out into a directory called src/.)
+ path = os.path.abspath(__file__)
+ while True:
+ path, tail = os.path.split(path)
+ assert tail
+ if tail == "mojo":
+ break
+ sys.path.append(os.path.join(path, "third_party"))
+ del path, tail
# pylint: disable=F0401
from ply import lex
+import lexer
+
# This (monkey-patching LexToken to make comparison value-based) is evil, but
# we'll do it anyway. (I'm pretty sure ply's lexer never cares about comparing
@@ -43,13 +51,13 @@ def _MakeLexTokenForKeyword(keyword, **kwargs):
return _MakeLexToken(keyword.upper(), keyword.lower(), **kwargs)
-class MojoLexerTest(unittest.TestCase):
- """Tests mojo_lexer (in particular, Lexer)."""
+class LexerTest(unittest.TestCase):
+ """Tests |lexer.Lexer|."""
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
# Clone all lexer instances from this one, since making a lexer is slow.
- self._zygote_lexer = lex.lex(mojo_lexer.Lexer("my_file.mojom"))
+ self._zygote_lexer = lex.lex(lexer.Lexer("my_file.mojom"))
def testValidSingleKeywords(self):
"""Tests valid, single keywords."""
diff --git a/mojo/public/tools/bindings/pylib/parse/mojo_parser.py b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
index c3c961ed0d..33af7d90c6 100755
--- a/mojo/public/tools/bindings/pylib/parse/mojo_parser.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
@@ -1,13 +1,13 @@
#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
+# 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.
"""Generates a syntax tree from a Mojo IDL file."""
-import sys
import os.path
+import sys
# Try to load the ply module, if not, then assume it is in the third_party
# directory.
@@ -17,16 +17,25 @@ try:
from ply import lex
from ply import yacc
except ImportError:
- # This assumes this file is in src/mojo/public/tools/bindings/pylib/parse/.
- module_path, module_name = os.path.split(__file__)
- third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir,
- os.pardir, os.pardir, os.pardir, 'third_party')
- sys.path.append(third_party)
+ # Work our way up to the directory containing mojo/ (usually src/). (Note:
+ # Some builds don't check out into a directory called src/.)
+ path = os.path.abspath(__file__)
+ while True:
+ path, tail = os.path.split(path)
+ assert tail
+ if tail == "mojo":
+ break
+ sys.path.append(os.path.join(path, "third_party"))
+ del path, tail
# pylint: disable=F0401
from ply import lex
from ply import yacc
-from mojo_lexer import Lexer
+import ast
+from lexer import Lexer
+
+
+_MAX_ORDINAL_VALUE = 0xffffffff
def _ListFromConcat(*items):
@@ -45,18 +54,18 @@ def _ListFromConcat(*items):
class ParseError(Exception):
- def __init__(self, filename, lineno=None, snippet=None, bad_char=None,
- eof=False):
+ def __init__(self, filename, message, lineno=None, snippet=None):
self.filename = filename
+ self.message = message
self.lineno = lineno
self.snippet = snippet
- self.bad_char = bad_char
- self.eof = eof
def __str__(self):
- return "%s: Error: Unexpected end of file" % self.filename if self.eof \
- else "%s:%d: Error: Unexpected %r:\n%s" % (
- self.filename, self.lineno, self.bad_char, self.snippet)
+ if self.lineno is None:
+ return "%s: Error: %s" % (self.filename, self.message)
+
+ s = "%s:%d: Error: %s" % (self.filename, self.lineno, self.message)
+ return s if self.snippet is None else s + "\n" + self.snippet
def __repr__(self):
return str(self)
@@ -76,6 +85,8 @@ class Parser(object):
if len(p) > 2:
p[0] = _ListFromConcat(p[1], p[2])
else:
+ # Generator expects a module. If one wasn't specified insert one with an
+ # empty name.
if p[1][0] != 'MODULE':
p[0] = [('MODULE', '', p[1])]
else:
@@ -87,7 +98,7 @@ class Parser(object):
p[0] = ('IMPORT', eval(p[2]))
def p_module(self, p):
- """module : MODULE NAME LBRACE definitions RBRACE"""
+ """module : MODULE identifier LBRACE definitions RBRACE"""
p[0] = ('MODULE', p[2], p[4])
def p_definitions(self, p):
@@ -204,14 +215,21 @@ class Parser(object):
p[0] = p[1]
def p_array(self, p):
- """array : basictypename LBRACKET RBRACKET"""
+ """array : typename LBRACKET RBRACKET"""
p[0] = p[1] + "[]"
def p_ordinal(self, p):
"""ordinal : ORDINAL
| """
if len(p) > 1:
- p[0] = p[1]
+ value = int(p[1][1:])
+ if value > _MAX_ORDINAL_VALUE:
+ raise ParseError(self.filename, "Ordinal value %d too large:" % value,
+ lineno=p.lineno(1),
+ snippet=self._GetSnippet(p.lineno(1)))
+ p[0] = ast.Ordinal(value, filename=self.filename, lineno=p.lineno(1))
+ else:
+ p[0] = ast.Ordinal(None)
def p_enum(self, p):
"""enum : ENUM NAME LBRACE enum_fields RBRACE SEMI"""
@@ -332,11 +350,13 @@ class Parser(object):
if e is None:
# Unexpected EOF.
# TODO(vtl): Can we figure out what's missing?
- raise ParseError(self.filename, eof=True)
+ raise ParseError(self.filename, "Unexpected end of file")
+
+ raise ParseError(self.filename, "Unexpected %r:" % e.value, lineno=e.lineno,
+ snippet=self._GetSnippet(e.lineno))
- snippet = self.source.split('\n')[e.lineno - 1]
- raise ParseError(self.filename, lineno=e.lineno, snippet=snippet,
- bad_char=e.value)
+ def _GetSnippet(self, lineno):
+ return self.source.split('\n')[lineno - 1]
def Parse(source, filename):
diff --git a/mojo/public/tools/bindings/pylib/parse/mojo_parser_unittest.py b/mojo/public/tools/bindings/pylib/mojom/parse/parser_unittest.py
index cc49c46c3d..fdce26c18f 100644
--- a/mojo/public/tools/bindings/pylib/parse/mojo_parser_unittest.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/parser_unittest.py
@@ -2,13 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mojo_lexer
-import mojo_parser
import unittest
+import ast
+import lexer
+import parser
-class MojoParserTest(unittest.TestCase):
- """Tests mojo_parser (in particular, Parse())."""
+
+class ParserTest(unittest.TestCase):
+ """Tests |parser.Parse()|."""
def testTrivialValidSource(self):
"""Tests a trivial, but valid, .mojom source."""
@@ -18,13 +20,13 @@ class MojoParserTest(unittest.TestCase):
module my_module {
}
"""
- self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"),
+ self.assertEquals(parser.Parse(source, "my_file.mojom"),
[("MODULE", "my_module", None)])
def testSourceWithCrLfs(self):
"""Tests a .mojom source with CR-LFs instead of LFs."""
source = "// This is a comment.\r\n\r\nmodule my_module {\r\n}\r\n";
- self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"),
+ self.assertEquals(parser.Parse(source, "my_file.mojom"),
[("MODULE", "my_module", None)])
def testUnexpectedEOF(self):
@@ -35,9 +37,9 @@ module my_module {
module my_module {
"""
with self.assertRaisesRegexp(
- mojo_parser.ParseError,
+ parser.ParseError,
r"^my_file\.mojom: Error: Unexpected end of file$"):
- mojo_parser.Parse(source, "my_file.mojom")
+ parser.Parse(source, "my_file.mojom")
def testSimpleStruct(self):
"""Tests a simple .mojom source that just defines a struct."""
@@ -57,9 +59,9 @@ struct MyStruct {
[('STRUCT',
'MyStruct',
None,
- [('FIELD', 'int32', 'a', None, None),
- ('FIELD', 'double', 'b', None, None)])])]
- self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"), expected)
+ [('FIELD', 'int32', 'a', ast.Ordinal(None), None),
+ ('FIELD', 'double', 'b', ast.Ordinal(None), None)])])]
+ self.assertEquals(parser.Parse(source, "my_file.mojom"), expected)
def testSimpleStructWithoutModule(self):
"""Tests a simple struct without an enclosing module."""
@@ -75,9 +77,9 @@ struct MyStruct {
[('STRUCT',
'MyStruct',
None,
- [('FIELD', 'int32', 'a', None, None),
- ('FIELD', 'double', 'b', None, None)])])]
- self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"), expected)
+ [('FIELD', 'int32', 'a', ast.Ordinal(None), None),
+ ('FIELD', 'double', 'b', ast.Ordinal(None), None)])])]
+ self.assertEquals(parser.Parse(source, "my_file.mojom"), expected)
def testMissingModuleName(self):
"""Tests an (invalid) .mojom with a missing module name."""
@@ -90,9 +92,9 @@ struct MyStruct {
}
"""
with self.assertRaisesRegexp(
- mojo_parser.ParseError,
+ parser.ParseError,
r"^my_file\.mojom:2: Error: Unexpected '{':\nmodule {$"):
- mojo_parser.Parse(source1, "my_file.mojom")
+ parser.Parse(source1, "my_file.mojom")
# Another similar case, but make sure that line-number tracking/reporting
# is correct.
@@ -104,9 +106,9 @@ module
}
"""
with self.assertRaisesRegexp(
- mojo_parser.ParseError,
+ parser.ParseError,
r"^my_file\.mojom:4: Error: Unexpected '{':\n{$"):
- mojo_parser.Parse(source2, "my_file.mojom")
+ parser.Parse(source2, "my_file.mojom")
def testEnumExpressions(self):
"""Tests an enum with values calculated using simple expressions."""
@@ -160,7 +162,7 @@ enum MyEnum {
('ENUM_FIELD',
'MY_ENUM_MINUS_1',
('EXPRESSION', ['~', ('EXPRESSION', ['0'])]))])])]
- self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"), expected)
+ self.assertEquals(parser.Parse(source, "my_file.mojom"), expected)
def testNoConditionals(self):
"""Tests that ?: is not allowed."""
@@ -174,9 +176,9 @@ enum MyEnum {
} // my_module
"""
with self.assertRaisesRegexp(
- mojo_lexer.LexError,
+ lexer.LexError,
r"^my_file\.mojom:4: Error: Illegal character '\?'$"):
- mojo_parser.Parse(source, "my_file.mojom")
+ parser.Parse(source, "my_file.mojom")
def testSimpleOrdinals(self):
"""Tests that (valid) ordinal values are scanned correctly."""
@@ -204,15 +206,15 @@ struct MyStruct {
[('STRUCT',
'MyStruct',
None,
- [('FIELD', 'int32', 'a0', '@0', None),
- ('FIELD', 'int32', 'a1', '@1', None),
- ('FIELD', 'int32', 'a2', '@2', None),
- ('FIELD', 'int32', 'a9', '@9', None),
- ('FIELD', 'int32', 'a10', '@10', None),
- ('FIELD', 'int32', 'a11', '@11', None),
- ('FIELD', 'int32', 'a29', '@29', None),
- ('FIELD', 'int32', 'a1234567890', '@1234567890', None)])])]
- self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"), expected)
+ [('FIELD', 'int32', 'a0', ast.Ordinal(0), None),
+ ('FIELD', 'int32', 'a1', ast.Ordinal(1), None),
+ ('FIELD', 'int32', 'a2', ast.Ordinal(2), None),
+ ('FIELD', 'int32', 'a9', ast.Ordinal(9), None),
+ ('FIELD', 'int32', 'a10', ast.Ordinal(10), None),
+ ('FIELD', 'int32', 'a11', ast.Ordinal(11), None),
+ ('FIELD', 'int32', 'a29', ast.Ordinal(29), None),
+ ('FIELD', 'int32', 'a1234567890', ast.Ordinal(1234567890), None)])])]
+ self.assertEquals(parser.Parse(source, "my_file.mojom"), expected)
def testInvalidOrdinals(self):
"""Tests that (lexically) invalid ordinals are correctly detected."""
@@ -226,9 +228,9 @@ struct MyStruct {
} // module my_module
"""
with self.assertRaisesRegexp(
- mojo_lexer.LexError,
+ lexer.LexError,
r"^my_file\.mojom:4: Error: Missing ordinal value$"):
- mojo_parser.Parse(source1, "my_file.mojom")
+ parser.Parse(source1, "my_file.mojom")
source2 = """\
module my_module {
@@ -240,37 +242,69 @@ struct MyStruct {
} // module my_module
"""
with self.assertRaisesRegexp(
- mojo_lexer.LexError,
+ lexer.LexError,
r"^my_file\.mojom:4: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
- mojo_parser.Parse(source2, "my_file.mojom")
+ parser.Parse(source2, "my_file.mojom")
source3 = """\
module my_module { struct MyStruct { int32 a_invalid_octal @08; }; }
"""
with self.assertRaisesRegexp(
- mojo_lexer.LexError,
+ lexer.LexError,
r"^my_file\.mojom:1: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
- mojo_parser.Parse(source3, "my_file.mojom")
+ parser.Parse(source3, "my_file.mojom")
source4 = """\
module my_module { struct MyStruct { int32 a_hex @0x1aB9; }; }
"""
with self.assertRaisesRegexp(
- mojo_lexer.LexError,
+ lexer.LexError,
r"^my_file\.mojom:1: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
- mojo_parser.Parse(source4, "my_file.mojom")
+ parser.Parse(source4, "my_file.mojom")
source5 = """\
module my_module { struct MyStruct { int32 a_hex @0X0; }; }
"""
with self.assertRaisesRegexp(
- mojo_lexer.LexError,
+ lexer.LexError,
r"^my_file\.mojom:1: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
- mojo_parser.Parse(source5, "my_file.mojom")
+ parser.Parse(source5, "my_file.mojom")
+
+ source6 = """\
+struct MyStruct {
+ int32 a_too_big @999999999999;
+};
+"""
+ with self.assertRaisesRegexp(
+ parser.ParseError,
+ r"^my_file\.mojom:2: Error: "
+ r"Ordinal value 999999999999 too large:\n"
+ r" int32 a_too_big @999999999999;$"):
+ parser.Parse(source6, "my_file.mojom")
+
+ def testNestedNamespace(self):
+ """Tests nested namespaces work."""
+ source = """\
+module my.mod {
+
+struct MyStruct {
+ int32 a;
+};
+
+} // module my.mod
+"""
+ expected = \
+[('MODULE',
+ 'my.mod',
+ [('STRUCT',
+ 'MyStruct',
+ None,
+ [('FIELD', 'int32', 'a', ast.Ordinal(None), None)])])]
+ self.assertEquals(parser.Parse(source, "my_file.mojom"), expected)
if __name__ == "__main__":
diff --git a/mojo/public/tools/bindings/pylib/parse/mojo_translate.py b/mojo/public/tools/bindings/pylib/mojom/parse/translate.py
index 9906ede8a5..6060c83bf9 100755
--- a/mojo/public/tools/bindings/pylib/parse/mojo_translate.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/translate.py
@@ -1,14 +1,16 @@
#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
+# 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.
-"""Translate parse tree to Mojom IR"""
+"""Translates parse tree to Mojom IR."""
-import os
+import os.path
import sys
+import ast
+
def MapTree(func, tree, name):
if not tree:
@@ -39,11 +41,6 @@ def MapKind(kind):
return map_to_kind[kind]
return 'x:' + kind
-def MapOrdinal(ordinal):
- if ordinal == None:
- return None
- return int(ordinal[1:]) # Strip leading '@'
-
def GetAttribute(attributes, name):
out = None
if attributes:
@@ -53,20 +50,23 @@ def GetAttribute(attributes, name):
return out
def MapField(tree):
+ assert type(tree[3]) is ast.Ordinal
return {'name': tree[2],
'kind': MapKind(tree[1]),
- 'ordinal': MapOrdinal(tree[3]),
+ 'ordinal': tree[3].value,
'default': tree[4]}
def MapParameter(tree):
+ assert type(tree[3]) is ast.Ordinal
return {'name': tree[2],
'kind': MapKind(tree[1]),
- 'ordinal': MapOrdinal(tree[3])}
+ 'ordinal': tree[3].value}
def MapMethod(tree):
+ assert type(tree[3]) is ast.Ordinal
method = {'name': tree[1],
'parameters': MapTree(MapParameter, tree[2], 'PARAM'),
- 'ordinal': MapOrdinal(tree[3])}
+ 'ordinal': tree[3].value}
if tree[4] != None:
method['response_parameters'] = MapTree(MapParameter, tree[4], 'PARAM')
return method
diff --git a/mojo/service_manager/service_manager.cc b/mojo/service_manager/service_manager.cc
index f12249ea66..c34e83f55a 100644
--- a/mojo/service_manager/service_manager.cc
+++ b/mojo/service_manager/service_manager.cc
@@ -9,6 +9,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/stl_util.h"
#include "mojo/public/cpp/bindings/allocation_scope.h"
#include "mojo/public/cpp/bindings/error_handler.h"
#include "mojo/public/cpp/bindings/remote_ptr.h"
@@ -71,16 +72,13 @@ bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
}
ServiceManager::ServiceManager()
- : default_loader_(NULL),
- interceptor_(NULL) {
+ : interceptor_(NULL) {
}
ServiceManager::~ServiceManager() {
- for (URLToServiceFactoryMap::iterator it = url_to_service_factory_.begin();
- it != url_to_service_factory_.end(); ++it) {
- delete it->second;
- }
- url_to_service_factory_.clear();
+ STLDeleteValues(&url_to_service_factory_);
+ STLDeleteValues(&url_to_loader_);
+ STLDeleteValues(&scheme_to_loader_);
}
// static
@@ -110,15 +108,20 @@ void ServiceManager::Connect(const GURL& url,
}
}
-void ServiceManager::SetLoaderForURL(ServiceLoader* loader, const GURL& url) {
- DCHECK(url_to_loader_.find(url) == url_to_loader_.end());
- url_to_loader_[url] = loader;
+void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader,
+ const GURL& url) {
+ URLToLoaderMap::iterator it = url_to_loader_.find(url);
+ if (it != url_to_loader_.end())
+ delete it->second;
+ url_to_loader_[url] = loader.release();
}
-void ServiceManager::SetLoaderForScheme(ServiceLoader* loader,
+void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader,
const std::string& scheme) {
- DCHECK(scheme_to_loader_.find(scheme) == scheme_to_loader_.end());
- scheme_to_loader_[scheme] = loader;
+ SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme);
+ if (it != scheme_to_loader_.end())
+ delete it->second;
+ scheme_to_loader_[scheme] = loader.release();
}
void ServiceManager::SetInterceptor(Interceptor* interceptor) {
@@ -134,7 +137,7 @@ ServiceLoader* ServiceManager::GetLoaderForURL(const GURL& url) {
if (scheme_it != scheme_to_loader_.end())
return scheme_it->second;
DCHECK(default_loader_);
- return default_loader_;
+ return default_loader_.get();
}
void ServiceManager::OnServiceFactoryError(ServiceFactory* service_factory) {
diff --git a/mojo/service_manager/service_manager.h b/mojo/service_manager/service_manager.h
index 6d9ab5de0d..40cb8cdb1f 100644
--- a/mojo/service_manager/service_manager.h
+++ b/mojo/service_manager/service_manager.h
@@ -10,7 +10,9 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
#include "mojo/public/interfaces/shell/shell.mojom.h"
+#include "mojo/service_manager/service_loader.h"
#include "mojo/service_manager/service_manager_export.h"
#include "url/gurl.h"
@@ -20,8 +22,6 @@ namespace content {
namespace mojo {
-class ServiceLoader;
-
class MOJO_SERVICE_MANAGER_EXPORT ServiceManager {
public:
// API for testing.
@@ -57,16 +57,16 @@ class MOJO_SERVICE_MANAGER_EXPORT ServiceManager {
// Loads a service if necessary and establishes a new client connection.
void Connect(const GURL& url, ScopedMessagePipeHandle client_handle);
- // Sets the default Loader to be used if not overridden by
- // SetLoaderForURL() or SetLoaderForScheme().
- // Does not take ownership of |loader|.
- void set_default_loader(ServiceLoader* loader) { default_loader_ = loader; }
+ // Sets the default Loader to be used if not overridden by SetLoaderForURL()
+ // or SetLoaderForScheme().
+ void set_default_loader(scoped_ptr<ServiceLoader> loader) {
+ default_loader_ = loader.Pass();
+ }
// Sets a Loader to be used for a specific url.
- // Does not take ownership of |loader|.
- void SetLoaderForURL(ServiceLoader* loader, const GURL& url);
+ void SetLoaderForURL(scoped_ptr<ServiceLoader> loader, const GURL& url);
// Sets a Loader to be used for a specific url scheme.
- // Does not take ownership of |loader|.
- void SetLoaderForScheme(ServiceLoader* loader, const std::string& scheme);
+ void SetLoaderForScheme(scoped_ptr<ServiceLoader> loader,
+ const std::string& scheme);
// Allows to interpose a debugger to service connections.
void SetInterceptor(Interceptor* interceptor);
@@ -87,7 +87,7 @@ class MOJO_SERVICE_MANAGER_EXPORT ServiceManager {
// Loader management.
URLToLoaderMap url_to_loader_;
SchemeToLoaderMap scheme_to_loader_;
- ServiceLoader* default_loader_;
+ scoped_ptr<ServiceLoader> default_loader_;
Interceptor* interceptor_;
URLToServiceFactoryMap url_to_service_factory_;
diff --git a/mojo/service_manager/service_manager_unittest.cc b/mojo/service_manager/service_manager_unittest.cc
index c7b3d2a608..54a6b7d5a6 100644
--- a/mojo/service_manager/service_manager_unittest.cc
+++ b/mojo/service_manager/service_manager_unittest.cc
@@ -19,18 +19,20 @@ namespace {
const char kTestURLString[] = "test:testService";
struct TestContext {
- TestContext() : num_impls(0) {}
+ TestContext() : num_impls(0), num_loader_deletes(0) {}
std::string last_test_string;
int num_impls;
+ int num_loader_deletes;
};
class TestServiceImpl :
- public Service<TestService, TestServiceImpl, TestContext> {
+ public ServiceConnection<TestService, TestServiceImpl, TestContext> {
public:
TestServiceImpl() {}
virtual ~TestServiceImpl() {
- --context()->num_impls;
+ if (context())
+ --context()->num_impls;
}
virtual void Test(const mojo::String& test_string) OVERRIDE {
@@ -38,11 +40,13 @@ class TestServiceImpl :
client()->AckTest();
}
- void Initialize(ServiceFactory<TestServiceImpl, TestContext>* service_factory,
- ScopedMessagePipeHandle client_handle) {
- Service<TestService, TestServiceImpl, TestContext>::Initialize(
+ void Initialize(
+ ServiceConnector<TestServiceImpl, TestContext>* service_factory,
+ ScopedMessagePipeHandle client_handle) {
+ ServiceConnection<TestService, TestServiceImpl, TestContext>::Initialize(
service_factory, client_handle.Pass());
- ++context()->num_impls;
+ if (context())
+ ++context()->num_impls;
}
};
@@ -71,74 +75,51 @@ class TestClientImpl : public TestClient {
bool quit_after_ack_;
DISALLOW_COPY_AND_ASSIGN(TestClientImpl);
};
-} // namespace
-class ServiceManagerTest : public testing::Test, public ServiceLoader {
+class TestServiceLoader : public ServiceLoader {
public:
- ServiceManagerTest() {}
-
- virtual ~ServiceManagerTest() {}
-
- virtual void SetUp() OVERRIDE {
- GURL test_url(kTestURLString);
- service_manager_.reset(new ServiceManager);
- service_manager_->SetLoaderForURL(this, test_url);
-
- InterfacePipe<TestService, AnyInterface> pipe;
- test_client_.reset(new TestClientImpl(pipe.handle_to_self.Pass()));
- service_manager_->Connect(test_url, pipe.handle_to_peer.Pass());
+ TestServiceLoader()
+ : context_(NULL),
+ num_loads_(0),
+ quit_after_error_(false) {
}
- virtual void TearDown() OVERRIDE {
- test_client_.reset(NULL);
+ virtual ~TestServiceLoader() {
+ if (context_)
+ ++context_->num_loader_deletes;
test_app_.reset(NULL);
- service_manager_.reset(NULL);
}
+ void set_context(TestContext* context) { context_ = context; }
+ void set_quit_after_error(bool quit_after_error) {
+ quit_after_error_ = quit_after_error;
+ }
+
+ int num_loads() const { return num_loads_; }
+
+ private:
virtual void LoadService(ServiceManager* manager,
const GURL& url,
ScopedShellHandle shell_handle) OVERRIDE {
+ ++num_loads_;
test_app_.reset(new Application(shell_handle.Pass()));
- test_app_->AddServiceFactory(
- new ServiceFactory<TestServiceImpl, TestContext>(&context_));
+ test_app_->AddServiceConnector(
+ new ServiceConnector<TestServiceImpl, TestContext>(context_));
}
virtual void OnServiceError(ServiceManager* manager,
const GURL& url) OVERRIDE {
- base::MessageLoop::current()->PostTask(FROM_HERE,
- base::MessageLoop::QuitClosure());
+ if (quit_after_error_) {
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
+ }
}
- bool HasFactoryForTestURL() {
- ServiceManager::TestAPI manager_test_api(service_manager_.get());
- return manager_test_api.HasFactoryForURL(GURL(kTestURLString));
- }
- protected:
- mojo::Environment env_;
- base::MessageLoop loop_;
- TestContext context_;
scoped_ptr<Application> test_app_;
- scoped_ptr<TestClientImpl> test_client_;
- scoped_ptr<ServiceManager> service_manager_;
- DISALLOW_COPY_AND_ASSIGN(ServiceManagerTest);
-};
-
-class TestServiceLoader : public ServiceLoader {
- public:
- TestServiceLoader() : num_loads_(0) {}
- int num_loads() const { return num_loads_; }
-
- private:
- virtual void LoadService(ServiceManager* manager,
- const GURL& url,
- ScopedShellHandle service_handle) OVERRIDE {
- ++num_loads_;
- }
- virtual void OnServiceError(ServiceManager* manager, const GURL& url)
- OVERRIDE {}
-
+ TestContext* context_;
int num_loads_;
+ bool quit_after_error_;
DISALLOW_COPY_AND_ASSIGN(TestServiceLoader);
};
@@ -169,6 +150,47 @@ class TestServiceInterceptor : public ServiceManager::Interceptor {
DISALLOW_COPY_AND_ASSIGN(TestServiceInterceptor);
};
+} // namespace
+
+class ServiceManagerTest : public testing::Test {
+ public:
+ ServiceManagerTest() {}
+
+ virtual ~ServiceManagerTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ GURL test_url(kTestURLString);
+ service_manager_.reset(new ServiceManager);
+
+ InterfacePipe<TestService, AnyInterface> pipe;
+ test_client_.reset(new TestClientImpl(pipe.handle_to_self.Pass()));
+ TestServiceLoader* default_loader = new TestServiceLoader;
+ default_loader->set_context(&context_);
+ default_loader->set_quit_after_error(true);
+ service_manager_->set_default_loader(
+ scoped_ptr<ServiceLoader>(default_loader));
+ service_manager_->Connect(test_url, pipe.handle_to_peer.Pass());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ test_client_.reset(NULL);
+ service_manager_.reset(NULL);
+ }
+
+ bool HasFactoryForTestURL() {
+ ServiceManager::TestAPI manager_test_api(service_manager_.get());
+ return manager_test_api.HasFactoryForURL(GURL(kTestURLString));
+ }
+
+ protected:
+ mojo::Environment env_;
+ base::MessageLoop loop_;
+ TestContext context_;
+ scoped_ptr<TestClientImpl> test_client_;
+ scoped_ptr<ServiceManager> service_manager_;
+ DISALLOW_COPY_AND_ASSIGN(ServiceManagerTest);
+};
+
TEST_F(ServiceManagerTest, Basic) {
test_client_->Test("test");
loop_.Run();
@@ -186,43 +208,67 @@ TEST_F(ServiceManagerTest, ClientError) {
EXPECT_FALSE(HasFactoryForTestURL());
}
+TEST_F(ServiceManagerTest, Deletes) {
+ {
+ ServiceManager sm;
+ TestServiceLoader* default_loader = new TestServiceLoader;
+ default_loader->set_context(&context_);
+ TestServiceLoader* url_loader1 = new TestServiceLoader;
+ TestServiceLoader* url_loader2 = new TestServiceLoader;
+ url_loader1->set_context(&context_);
+ url_loader2->set_context(&context_);
+ TestServiceLoader* scheme_loader1 = new TestServiceLoader;
+ TestServiceLoader* scheme_loader2 = new TestServiceLoader;
+ scheme_loader1->set_context(&context_);
+ scheme_loader2->set_context(&context_);
+ sm.set_default_loader(scoped_ptr<ServiceLoader>(default_loader));
+ sm.SetLoaderForURL(scoped_ptr<ServiceLoader>(url_loader1),
+ GURL("test:test1"));
+ sm.SetLoaderForURL(scoped_ptr<ServiceLoader>(url_loader2),
+ GURL("test:test1"));
+ sm.SetLoaderForScheme(scoped_ptr<ServiceLoader>(scheme_loader1), "test");
+ sm.SetLoaderForScheme(scoped_ptr<ServiceLoader>(scheme_loader2), "test");
+ }
+ EXPECT_EQ(5, context_.num_loader_deletes);
+}
+
// Confirm that both urls and schemes can have their loaders explicitly set.
TEST_F(ServiceManagerTest, SetLoaders) {
ServiceManager sm;
- TestServiceLoader default_loader;
- TestServiceLoader url_loader;
- TestServiceLoader scheme_loader;
- sm.set_default_loader(&default_loader);
- sm.SetLoaderForURL(&url_loader, GURL("test:test1"));
- sm.SetLoaderForScheme(&scheme_loader, "test");
+ TestServiceLoader* default_loader = new TestServiceLoader;
+ TestServiceLoader* url_loader = new TestServiceLoader;
+ TestServiceLoader* scheme_loader = new TestServiceLoader;
+ sm.set_default_loader(scoped_ptr<ServiceLoader>(default_loader));
+ sm.SetLoaderForURL(scoped_ptr<ServiceLoader>(url_loader), GURL("test:test1"));
+ sm.SetLoaderForScheme(scoped_ptr<ServiceLoader>(scheme_loader), "test");
// test::test1 should go to url_loader.
InterfacePipe<TestService, AnyInterface> pipe1;
sm.Connect(GURL("test:test1"), pipe1.handle_to_peer.Pass());
- EXPECT_EQ(1, url_loader.num_loads());
- EXPECT_EQ(0, scheme_loader.num_loads());
- EXPECT_EQ(0, default_loader.num_loads());
+ EXPECT_EQ(1, url_loader->num_loads());
+ EXPECT_EQ(0, scheme_loader->num_loads());
+ EXPECT_EQ(0, default_loader->num_loads());
// test::test2 should go to scheme loader.
InterfacePipe<TestService, AnyInterface> pipe2;
sm.Connect(GURL("test:test2"), pipe2.handle_to_peer.Pass());
- EXPECT_EQ(1, url_loader.num_loads());
- EXPECT_EQ(1, scheme_loader.num_loads());
- EXPECT_EQ(0, default_loader.num_loads());
+ EXPECT_EQ(1, url_loader->num_loads());
+ EXPECT_EQ(1, scheme_loader->num_loads());
+ EXPECT_EQ(0, default_loader->num_loads());
// http::test1 should go to default loader.
InterfacePipe<TestService, AnyInterface> pipe3;
sm.Connect(GURL("http:test1"), pipe3.handle_to_peer.Pass());
- EXPECT_EQ(1, url_loader.num_loads());
- EXPECT_EQ(1, scheme_loader.num_loads());
- EXPECT_EQ(1, default_loader.num_loads());
+ EXPECT_EQ(1, url_loader->num_loads());
+ EXPECT_EQ(1, scheme_loader->num_loads());
+ EXPECT_EQ(1, default_loader->num_loads());
}
TEST_F(ServiceManagerTest, Interceptor) {
ServiceManager sm;
- TestServiceLoader default_loader;
TestServiceInterceptor interceptor;
- sm.set_default_loader(&default_loader);
+ TestServiceLoader* default_loader = new TestServiceLoader;
+ sm.set_default_loader(scoped_ptr<ServiceLoader>(default_loader));
sm.SetInterceptor(&interceptor);
std::string url("test:test3");
@@ -230,7 +276,7 @@ TEST_F(ServiceManagerTest, Interceptor) {
sm.Connect(GURL(url), pipe1.handle_to_peer.Pass());
EXPECT_EQ(1, interceptor.call_count());
EXPECT_EQ(url, interceptor.url_spec());
- EXPECT_EQ(1, default_loader.num_loads());
+ EXPECT_EQ(1, default_loader->num_loads());
}
} // namespace mojo
diff --git a/mojo/services/native_viewport/native_viewport_android.h b/mojo/services/native_viewport/native_viewport_android.h
index 96ecd1f226..c24e38e785 100644
--- a/mojo/services/native_viewport/native_viewport_android.h
+++ b/mojo/services/native_viewport/native_viewport_android.h
@@ -5,7 +5,7 @@
#ifndef MOJO_SERVICES_NATIVE_VIEWPORT_NATIVE_VIEWPORT_ANDROID_H_
#define MOJO_SERVICES_NATIVE_VIEWPORT_NATIVE_VIEWPORT_ANDROID_H_
-#include "base/android/jni_helper.h"
+#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/memory/weak_ptr.h"
#include "mojo/services/native_viewport/native_viewport.h"
diff --git a/mojo/services/native_viewport/native_viewport_export.h b/mojo/services/native_viewport/native_viewport_export.h
index 647b6892e3..4870c566f9 100644
--- a/mojo/services/native_viewport/native_viewport_export.h
+++ b/mojo/services/native_viewport/native_viewport_export.h
@@ -5,6 +5,8 @@
#ifndef MOJO_SERVICES_NATIVE_VIEWPORT_EXPORT_H_
#define MOJO_SERVICES_NATIVE_VIEWPORT_EXPORT_H_
+#if defined(COMPONENT_BUILD)
+
#if defined(WIN32)
#if defined(MOJO_NATIVE_VIEWPORT_IMPLEMENTATION)
@@ -23,4 +25,8 @@
#endif // defined(WIN32)
+#else // !defined(COMPONENT_BUILD)
+#define MOJO_NATIVE_VIEWPORT_EXPORT
+#endif
+
#endif // MOJO_SERVICES_NATIVE_VIEWPORT_EXPORT_H_
diff --git a/mojo/services/native_viewport/native_viewport_service.cc b/mojo/services/native_viewport/native_viewport_service.cc
index 024a3bbc56..5625aa1393 100644
--- a/mojo/services/native_viewport/native_viewport_service.cc
+++ b/mojo/services/native_viewport/native_viewport_service.cc
@@ -28,7 +28,9 @@ bool IsRateLimitedEventType(ui::Event* event) {
}
class NativeViewportImpl
- : public Service<mojo::NativeViewport, NativeViewportImpl, shell::Context>,
+ : public ServiceConnection<mojo::NativeViewport,
+ NativeViewportImpl,
+ shell::Context>,
public NativeViewportDelegate {
public:
NativeViewportImpl()
@@ -186,9 +188,9 @@ MOJO_NATIVE_VIEWPORT_EXPORT mojo::Application*
CreateNativeViewportService(mojo::shell::Context* context,
mojo::ScopedShellHandle shell_handle) {
mojo::Application* app = new mojo::Application(shell_handle.Pass());
- app->AddServiceFactory(
- new mojo::ServiceFactory<mojo::services::NativeViewportImpl,
- mojo::shell::Context>(context));
+ app->AddServiceConnector(
+ new mojo::ServiceConnector<mojo::services::NativeViewportImpl,
+ mojo::shell::Context>(context));
return app;
}
diff --git a/mojo/services/public/cpp/view_manager/lib/view.cc b/mojo/services/public/cpp/view_manager/lib/view.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view.cc
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager.cc b/mojo/services/public/cpp/view_manager/lib/view_manager.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager.cc
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_host.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_host.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_host.cc
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
new file mode 100644
index 0000000000..9194dc4e3a
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
@@ -0,0 +1,144 @@
+// 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/services/public/cpp/view_manager/view_tree_node.h"
+
+#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
+#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+void NotifyViewTreeChangeAtReceiver(
+ ViewTreeNode* receiver,
+ const ViewTreeNodeObserver::TreeChangeParams& params) {
+ ViewTreeNodeObserver::TreeChangeParams local_params = params;
+ local_params.receiver = receiver;
+ FOR_EACH_OBSERVER(ViewTreeNodeObserver,
+ *ViewTreeNodePrivate(receiver).observers(),
+ OnTreeChange(local_params));
+}
+
+void NotifyViewTreeChangeUp(
+ ViewTreeNode* start_at,
+ const ViewTreeNodeObserver::TreeChangeParams& params) {
+ for (ViewTreeNode* current = start_at; current; current = current->parent())
+ NotifyViewTreeChangeAtReceiver(current, params);
+}
+
+void NotifyViewTreeChangeDown(
+ ViewTreeNode* start_at,
+ const ViewTreeNodeObserver::TreeChangeParams& params) {
+ NotifyViewTreeChangeAtReceiver(start_at, params);
+ ViewTreeNode::Children::const_iterator it = start_at->children().begin();
+ for (; it != start_at->children().end(); ++it)
+ NotifyViewTreeChangeDown(*it, params);
+}
+
+void NotifyViewTreeChange(
+ const ViewTreeNodeObserver::TreeChangeParams& params) {
+ NotifyViewTreeChangeDown(params.target, params);
+ switch (params.phase) {
+ case ViewTreeNodeObserver::DISPOSITION_CHANGING:
+ if (params.old_parent)
+ NotifyViewTreeChangeUp(params.old_parent, params);
+ break;
+ case ViewTreeNodeObserver::DISPOSITION_CHANGED:
+ if (params.new_parent)
+ NotifyViewTreeChangeUp(params.new_parent, params);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+class ScopedTreeNotifier {
+ public:
+ ScopedTreeNotifier(ViewTreeNode* target,
+ ViewTreeNode* old_parent,
+ ViewTreeNode* new_parent) {
+ params_.target = target;
+ params_.old_parent = old_parent;
+ params_.new_parent = new_parent;
+ NotifyViewTreeChange(params_);
+ }
+ ~ScopedTreeNotifier() {
+ params_.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ NotifyViewTreeChange(params_);
+ }
+
+ private:
+ ViewTreeNodeObserver::TreeChangeParams params_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier);
+};
+
+void RemoveChildImpl(ViewTreeNode* child, ViewTreeNode::Children* children) {
+ ViewTreeNode::Children::iterator it =
+ std::find(children->begin(), children->end(), child);
+ if (it != children->end()) {
+ children->erase(it);
+ ViewTreeNodePrivate(child).ClearParent();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ViewTreeNode, public:
+
+ViewTreeNode::ViewTreeNode() : owned_by_parent_(true), parent_(NULL) {}
+
+ViewTreeNode::~ViewTreeNode() {
+ while (!children_.empty()) {
+ ViewTreeNode* child = children_.front();
+ if (child->owned_by_parent_) {
+ delete child;
+ // Deleting the child also removes it from our child list.
+ DCHECK(std::find(children_.begin(), children_.end(), child) ==
+ children_.end());
+ } else {
+ RemoveChild(child);
+ }
+ }
+
+ if (parent_)
+ parent_->RemoveChild(this);
+
+}
+
+void ViewTreeNode::AddObserver(ViewTreeNodeObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void ViewTreeNode::RemoveObserver(ViewTreeNodeObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void ViewTreeNode::AddChild(ViewTreeNode* child) {
+ ScopedTreeNotifier notifier(child, child->parent(), this);
+ if (child->parent())
+ RemoveChildImpl(child, &child->parent_->children_);
+ children_.push_back(child);
+ child->parent_ = this;
+}
+
+void ViewTreeNode::RemoveChild(ViewTreeNode* child) {
+ DCHECK_EQ(this, child->parent());
+ ScopedTreeNotifier(child, this, NULL);
+ RemoveChildImpl(child, &children_);
+}
+
+bool ViewTreeNode::Contains(ViewTreeNode* child) const {
+ for (ViewTreeNode* p = child->parent(); p; p = p->parent()) {
+ if (p == this)
+ return true;
+ }
+ return false;
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node_observer.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node_observer.cc
new file mode 100644
index 0000000000..607269c66d
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node_observer.cc
@@ -0,0 +1,26 @@
+// 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/services/public/cpp/view_manager/view_tree_node_observer.h"
+
+#include "base/basictypes.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+////////////////////////////////////////////////////////////////////////////////
+// ViewTreeNodeObserver, public:
+
+ViewTreeNodeObserver::TreeChangeParams::TreeChangeParams()
+ : target(NULL),
+ old_parent(NULL),
+ new_parent(NULL),
+ receiver(NULL),
+ phase(ViewTreeNodeObserver::DISPOSITION_CHANGING) {}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.cc
new file mode 100644
index 0000000000..a1c3a40ac9
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.cc
@@ -0,0 +1,20 @@
+// 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/services/public/cpp/view_manager/lib/view_tree_node_private.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+ViewTreeNodePrivate::ViewTreeNodePrivate(ViewTreeNode* node)
+ : node_(node) {
+}
+
+ViewTreeNodePrivate::~ViewTreeNodePrivate() {
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
new file mode 100644
index 0000000000..33be9f087d
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
@@ -0,0 +1,37 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_TREE_NODE_PRIVATE_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_TREE_NODE_PRIVATE_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+
+#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewTreeNodePrivate {
+ public:
+ explicit ViewTreeNodePrivate(ViewTreeNode* node);
+ ~ViewTreeNodePrivate();
+
+ ObserverList<ViewTreeNodeObserver>* observers() { return &node_->observers_; }
+
+ void ClearParent() { node_->parent_ = NULL; }
+
+ private:
+ ViewTreeNode* node_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewTreeNodePrivate);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_TREE_NODE_PRIVATE_H_
diff --git a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
diff --git a/mojo/services/public/cpp/view_manager/tests/view_tree_host_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_tree_host_unittest.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/tests/view_tree_host_unittest.cc
diff --git a/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
new file mode 100644
index 0000000000..54349eeadd
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
@@ -0,0 +1,330 @@
+// 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/services/public/cpp/view_manager/view_tree_node.h"
+
+#include "base/logging.h"
+#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+// ViewTreeNode ----------------------------------------------------------------
+
+typedef testing::Test ViewTreeNodeTest;
+
+TEST_F(ViewTreeNodeTest, AddChild) {
+ ViewTreeNode v1;
+ ViewTreeNode* v11 = new ViewTreeNode;
+ v1.AddChild(v11);
+ EXPECT_EQ(1U, v1.children().size());
+}
+
+TEST_F(ViewTreeNodeTest, RemoveChild) {
+ ViewTreeNode v1;
+ ViewTreeNode* v11 = new ViewTreeNode;
+ v1.AddChild(v11);
+ EXPECT_EQ(1U, v1.children().size());
+ v1.RemoveChild(v11);
+ EXPECT_EQ(0U, v1.children().size());
+}
+
+TEST_F(ViewTreeNodeTest, Reparent) {
+ ViewTreeNode v1;
+ ViewTreeNode v2;
+ ViewTreeNode* v11 = new ViewTreeNode;
+ v1.AddChild(v11);
+ EXPECT_EQ(1U, v1.children().size());
+ v2.AddChild(v11);
+ EXPECT_EQ(1U, v2.children().size());
+ EXPECT_EQ(0U, v1.children().size());
+}
+
+TEST_F(ViewTreeNodeTest, Contains) {
+ ViewTreeNode v1;
+
+ // Direct descendant.
+ ViewTreeNode* v11 = new ViewTreeNode;
+ v1.AddChild(v11);
+ EXPECT_TRUE(v1.Contains(v11));
+
+ // Indirect descendant.
+ ViewTreeNode* v111 = new ViewTreeNode;
+ v11->AddChild(v111);
+ EXPECT_TRUE(v1.Contains(v111));
+}
+
+// ViewTreeNodeObserver --------------------------------------------------------
+
+typedef testing::Test ViewTreeNodeObserverTest;
+
+bool TreeChangeParamsMatch(const ViewTreeNodeObserver::TreeChangeParams& lhs,
+ const ViewTreeNodeObserver::TreeChangeParams& rhs) {
+ return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent &&
+ lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver &&
+ lhs.phase == rhs.phase;
+}
+
+class TreeChangeObserver : public ViewTreeNodeObserver {
+ public:
+ explicit TreeChangeObserver(ViewTreeNode* observee) : observee_(observee) {
+ observee_->AddObserver(this);
+ }
+ virtual ~TreeChangeObserver() {
+ observee_->RemoveObserver(this);
+ }
+
+ void Reset() {
+ received_params_.clear();
+ }
+
+ const std::vector<TreeChangeParams>& received_params() {
+ return received_params_;
+ }
+
+ private:
+ // Overridden from ViewTreeNodeObserver:
+ virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE {
+ received_params_.push_back(params);
+ }
+
+ ViewTreeNode* observee_;
+ std::vector<TreeChangeParams> received_params_;
+
+ DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver);
+};
+
+// Adds/Removes v11 to v1.
+TEST_F(ViewTreeNodeObserverTest, TreeChange_SimpleAddRemove) {
+ ViewTreeNode v1;
+ TreeChangeObserver o1(&v1);
+ EXPECT_TRUE(o1.received_params().empty());
+
+ ViewTreeNode v11;
+ v11.set_owned_by_parent(false);
+ TreeChangeObserver o11(&v11);
+ EXPECT_TRUE(o11.received_params().empty());
+
+ // Add.
+
+ v1.AddChild(&v11);
+
+ EXPECT_EQ(1U, o1.received_params().size());
+ ViewTreeNodeObserver::TreeChangeParams p1;
+ p1.target = &v11;
+ p1.receiver = &v1;
+ p1.old_parent = NULL;
+ p1.new_parent = &v1;
+ p1.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ EXPECT_EQ(2U, o11.received_params().size());
+ ViewTreeNodeObserver::TreeChangeParams p11 = p1;
+ p11.receiver = &v11;
+ p11.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
+ p11.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+
+ o1.Reset();
+ o11.Reset();
+ EXPECT_TRUE(o1.received_params().empty());
+ EXPECT_TRUE(o11.received_params().empty());
+
+ // Remove.
+
+ v1.RemoveChild(&v11);
+
+ EXPECT_EQ(1U, o1.received_params().size());
+ p1.target = &v11;
+ p1.receiver = &v1;
+ p1.old_parent = &v1;
+ p1.new_parent = NULL;
+ p1.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ EXPECT_EQ(2U, o11.received_params().size());
+ p11 = p1;
+ p11.receiver = &v11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
+ p11.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+}
+
+// Creates these two trees:
+// v1
+// +- v11
+// v111
+// +- v1111
+// +- v1112
+// Then adds/removes v111 from v11.
+TEST_F(ViewTreeNodeObserverTest, TreeChange_NestedAddRemove) {
+ ViewTreeNode v1, v11, v111, v1111, v1112;
+
+ // Root tree.
+ v11.set_owned_by_parent(false);
+ v1.AddChild(&v11);
+
+ // Tree to be attached.
+ v111.set_owned_by_parent(false);
+ v1111.set_owned_by_parent(false);
+ v111.AddChild(&v1111);
+ v1112.set_owned_by_parent(false);
+ v111.AddChild(&v1112);
+
+ TreeChangeObserver o1(&v1), o11(&v11), o111(&v111), o1111(&v1111),
+ o1112(&v1112);
+ ViewTreeNodeObserver::TreeChangeParams p1, p11, p111, p1111, p1112;
+
+ // Add.
+
+ v11.AddChild(&v111);
+
+ EXPECT_EQ(1U, o1.received_params().size());
+ p1.target = &v111;
+ p1.receiver = &v1;
+ p1.old_parent = NULL;
+ p1.new_parent = &v11;
+ p1.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ EXPECT_EQ(1U, o11.received_params().size());
+ p11 = p1;
+ p11.receiver = &v11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+
+ EXPECT_EQ(2U, o111.received_params().size());
+ p111 = p11;
+ p111.receiver = &v111;
+ p111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
+ p111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
+
+ EXPECT_EQ(2U, o1111.received_params().size());
+ p1111 = p111;
+ p1111.receiver = &v1111;
+ p1111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
+ p1111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
+
+ EXPECT_EQ(2U, o1112.received_params().size());
+ p1112 = p111;
+ p1112.receiver = &v1112;
+ p1112.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
+ p1112.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
+
+ // Remove.
+ o1.Reset();
+ o11.Reset();
+ o111.Reset();
+ o1111.Reset();
+ o1112.Reset();
+ EXPECT_TRUE(o1.received_params().empty());
+ EXPECT_TRUE(o11.received_params().empty());
+ EXPECT_TRUE(o111.received_params().empty());
+ EXPECT_TRUE(o1111.received_params().empty());
+ EXPECT_TRUE(o1112.received_params().empty());
+
+ v11.RemoveChild(&v111);
+
+ EXPECT_EQ(1U, o1.received_params().size());
+ p1.target = &v111;
+ p1.receiver = &v1;
+ p1.old_parent = &v11;
+ p1.new_parent = NULL;
+ p1.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ EXPECT_EQ(1U, o11.received_params().size());
+ p11 = p1;
+ p11.receiver = &v11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+
+ EXPECT_EQ(2U, o111.received_params().size());
+ p111 = p11;
+ p111.receiver = &v111;
+ p111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
+ p111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
+
+ EXPECT_EQ(2U, o1111.received_params().size());
+ p1111 = p111;
+ p1111.receiver = &v1111;
+ p1111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
+ p1111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
+
+ EXPECT_EQ(2U, o1112.received_params().size());
+ p1112 = p111;
+ p1112.receiver = &v1112;
+ p1112.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
+ p1112.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
+}
+
+TEST_F(ViewTreeNodeObserverTest, TreeChange_Reparent) {
+ ViewTreeNode v1, v11, v12, v111;
+ v11.set_owned_by_parent(false);
+ v111.set_owned_by_parent(false);
+ v12.set_owned_by_parent(false);
+ v1.AddChild(&v11);
+ v1.AddChild(&v12);
+ v11.AddChild(&v111);
+
+ TreeChangeObserver o1(&v1), o11(&v11), o12(&v12), o111(&v111);
+
+ // Reparent.
+ v12.AddChild(&v111);
+
+ // v1 (root) should see both changing and changed notifications.
+ EXPECT_EQ(2U, o1.received_params().size());
+ ViewTreeNodeObserver::TreeChangeParams p1;
+ p1.target = &v111;
+ p1.receiver = &v1;
+ p1.old_parent = &v11;
+ p1.new_parent = &v12;
+ p1.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
+ p1.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ // v11 should see changing notifications.
+ EXPECT_EQ(1U, o11.received_params().size());
+ ViewTreeNodeObserver::TreeChangeParams p11;
+ p11 = p1;
+ p11.receiver = &v11;
+ p11.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+
+ // v12 should see changed notifications.
+ EXPECT_EQ(1U, o12.received_params().size());
+ ViewTreeNodeObserver::TreeChangeParams p12;
+ p12 = p1;
+ p12.receiver = &v12;
+ p12.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back()));
+
+ // v111 should see both changing and changed notifications.
+ EXPECT_EQ(2U, o111.received_params().size());
+ ViewTreeNodeObserver::TreeChangeParams p111;
+ p111 = p1;
+ p111.receiver = &v111;
+ p111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGING;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
+ p111.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/tests/view_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_unittest.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/tests/view_unittest.cc
diff --git a/mojo/services/public/cpp/view_manager/view.h b/mojo/services/public/cpp/view_manager/view.h
new file mode 100644
index 0000000000..a0bba82054
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view.h
@@ -0,0 +1,24 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_H_
+
+#include "base/basictypes.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class View {
+ public:
+ private:
+ DISALLOW_COPY_AND_ASSIGN(View);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_H_
diff --git a/mojo/services/public/cpp/view_manager/view_manager.h b/mojo/services/public/cpp/view_manager/view_manager.h
new file mode 100644
index 0000000000..45ab0e2f58
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_manager.h
@@ -0,0 +1,24 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_H_
+
+#include "base/basictypes.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewManager {
+ public:
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ViewManager);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_H_
diff --git a/mojo/services/public/cpp/view_manager/view_tree_host.h b/mojo/services/public/cpp/view_manager/view_tree_host.h
new file mode 100644
index 0000000000..13fb6dd1f5
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_tree_host.h
@@ -0,0 +1,24 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_HOST_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_HOST_H_
+
+#include "base/basictypes.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewTreeHost {
+ public:
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ViewTreeHost);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_HOST_H_
diff --git a/mojo/services/public/cpp/view_manager/view_tree_node.h b/mojo/services/public/cpp/view_manager/view_tree_node.h
new file mode 100644
index 0000000000..42f27e71f3
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_tree_node.h
@@ -0,0 +1,61 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_NODE_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_NODE_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/observer_list.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewTreeNodeObserver;
+
+class ViewTreeNode {
+ public:
+ typedef std::vector<ViewTreeNode*> Children;
+
+ ViewTreeNode();
+ ~ViewTreeNode();
+
+ // Configuration.
+ void set_owned_by_parent(bool owned_by_parent) {
+ owned_by_parent_ = owned_by_parent;
+ }
+
+ // Observation.
+ void AddObserver(ViewTreeNodeObserver* observer);
+ void RemoveObserver(ViewTreeNodeObserver* observer);
+
+ // Tree.
+ ViewTreeNode* parent() { return parent_; }
+ const ViewTreeNode* parent() const { return parent_; }
+ const Children& children() const { return children_; }
+
+ void AddChild(ViewTreeNode* child);
+ void RemoveChild(ViewTreeNode* child);
+
+ bool Contains(ViewTreeNode* child) const;
+
+ private:
+ friend class ViewTreeNodePrivate;
+
+ bool owned_by_parent_;
+ ViewTreeNode* parent_;
+ Children children_;
+
+ ObserverList<ViewTreeNodeObserver> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewTreeNode);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_NODE_H_
diff --git a/mojo/services/public/cpp/view_manager/view_tree_node_observer.h b/mojo/services/public/cpp/view_manager/view_tree_node_observer.h
new file mode 100644
index 0000000000..4b4e6e0c17
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_tree_node_observer.h
@@ -0,0 +1,44 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_NODE_OBSERVER_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_NODE_OBSERVER_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewTreeNode;
+
+class ViewTreeNodeObserver {
+ public:
+ enum DispositionChangePhase {
+ DISPOSITION_CHANGING,
+ DISPOSITION_CHANGED
+ };
+
+ struct TreeChangeParams {
+ TreeChangeParams();
+ ViewTreeNode* target;
+ ViewTreeNode* old_parent;
+ ViewTreeNode* new_parent;
+ ViewTreeNode* receiver;
+ DispositionChangePhase phase;
+ };
+
+ virtual void OnTreeChange(const TreeChangeParams& params) {}
+
+ protected:
+ virtual ~ViewTreeNodeObserver() {}
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TREE_NODE_OBSERVER_H_
diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom
new file mode 100644
index 0000000000..ef5dcf3c34
--- /dev/null
+++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom
@@ -0,0 +1,54 @@
+// 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.services.view_manager {
+
+// Functions that mutate the hierarchy take a |change_id|. |change_id| is an
+// arbitrary value assigned by the client originating the change. It may be
+// used by the client originating the change to later identify the change in
+// an OnNodeHierarchyChanged callback. |change_id| is only passed to the client
+// that originated the change; all other clients get a value of 0.
+//
+// Nodes are identified by a uint32. The upper 16 bits are the connection id,
+// and the lower 16 the id assigned by the client. CreateNode() only takes a
+// uint16 as the connection id of the originating connection is used.
+//
+// The root node is identified with a connection id of 0, and value of 1.
+[Peer=ViewManagerClient]
+interface ViewManager {
+ // Creates a new node with the specified id. It is up to the client to ensure
+ // the id is unique to the connection (the id need not be globally unique).
+ CreateNode(uint16 node_id) => (bool success);
+
+ // Reparents a node. See description above class for details of |change_id|.
+ AddNode(uint32 parent, uint32 child, int32 change_id) => (bool success);
+
+ // Removes a view from its current parent. See description above class for
+ // details of |change_id|.
+ RemoveNodeFromParent(uint32 node_id, int32 change_id) => (bool success);
+
+ // Creates a new view with the specified id. It is up to the client to ensure
+ // the id is unique to the connection (the id need not be globally unique).
+ // CreateView(uint16 view_id) => (bool success);
+
+ // Sets the view a node is showing.
+ // SetView(uint32 node, uint32 view) => (bool success);
+};
+
+[Peer=ViewManager]
+interface ViewManagerClient {
+ // Invoked once the connection has been established. |connection_id| is the id
+ // used to uniquely identify the connection.
+ OnConnectionEstablished(uint16 connection_id);
+
+ // Invoked when a change is done to the hierarchy. A value of 0 is used to
+ // identify a null node. For example, if the old_parent is NULL, 0 is
+ // supplied. See description above ViewManager for details on |change_id|.
+ OnNodeHierarchyChanged(uint32 node,
+ uint32 new_parent,
+ uint32 old_parent,
+ int32 change_id);
+};
+
+}
diff --git a/mojo/examples/view_manager/DEPS b/mojo/services/view_manager/DEPS
index 8cb61f5e0a..05af088e23 100644
--- a/mojo/examples/view_manager/DEPS
+++ b/mojo/services/view_manager/DEPS
@@ -1,4 +1,6 @@
include_rules = [
+ "+mojo/services",
+ "+ui/aura",
"+ui/events",
"+ui/gfx",
]
diff --git a/mojo/services/view_manager/ids.h b/mojo/services/view_manager/ids.h
new file mode 100644
index 0000000000..257402bb91
--- /dev/null
+++ b/mojo/services/view_manager/ids.h
@@ -0,0 +1,71 @@
+// 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_SERVICES_VIEW_MANAGER_IDS_H_
+#define MOJO_SERVICES_VIEW_MANAGER_IDS_H_
+
+#include "mojo/services/view_manager/view_manager_export.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+// Adds a bit of type safety to node ids.
+struct MOJO_VIEW_MANAGER_EXPORT NodeId {
+ NodeId(uint16_t connection_id, uint16_t node_id)
+ : connection_id(connection_id),
+ node_id(node_id) {}
+ NodeId() : connection_id(0), node_id(0) {}
+
+ bool operator==(const NodeId& other) const {
+ return other.connection_id == connection_id &&
+ other.node_id == node_id;
+ }
+
+ uint16_t connection_id;
+ uint16_t node_id;
+};
+
+// Adds a bit of type safety to view ids.
+struct MOJO_VIEW_MANAGER_EXPORT ViewId {
+ ViewId(uint16_t connection_id, uint16_t view_id)
+ : connection_id(connection_id),
+ view_id(view_id) {}
+ ViewId() : connection_id(0), view_id(0) {}
+
+ bool operator==(const ViewId& other) const {
+ return other.connection_id == connection_id &&
+ other.view_id == view_id;
+ }
+
+ uint16_t connection_id;
+ uint16_t view_id;
+};
+
+// Functions for converting to/from structs and transport values.
+inline uint16_t FirstIdFromTransportId(uint32_t id) {
+ return static_cast<uint16_t>((id >> 16) & 0xFFFF);
+}
+
+inline uint16_t SecondIdFromTransportId(uint32_t id) {
+ return static_cast<uint16_t>(id & 0xFFFF);
+}
+
+inline NodeId NodeIdFromTransportId(uint32_t id) {
+ return NodeId(FirstIdFromTransportId(id), SecondIdFromTransportId(id));
+}
+
+inline uint32_t NodeIdToTransportId(const NodeId& id) {
+ return (id.connection_id << 16) | id.node_id;
+}
+
+inline ViewId ViewIdFromTransportId(uint32_t id) {
+ return ViewId(FirstIdFromTransportId(id), SecondIdFromTransportId(id));
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_VIEW_MANAGER_IDS_H_
diff --git a/mojo/services/view_manager/node.cc b/mojo/services/view_manager/node.cc
new file mode 100644
index 0000000000..1457a7ee6b
--- /dev/null
+++ b/mojo/services/view_manager/node.cc
@@ -0,0 +1,60 @@
+// 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/services/view_manager/node.h"
+
+#include "mojo/services/view_manager/node_delegate.h"
+#include "ui/aura/window_property.h"
+
+DECLARE_WINDOW_PROPERTY_TYPE(mojo::services::view_manager::Node*);
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+DEFINE_WINDOW_PROPERTY_KEY(Node*, kNodeKey, NULL);
+
+Node::Node(NodeDelegate* delegate, const NodeId& id)
+ : delegate_(delegate),
+ id_(id),
+ window_(NULL) {
+ DCHECK(delegate); // Must provide a delegate.
+ window_.set_owned_by_parent(false);
+ window_.AddObserver(this);
+ window_.SetProperty(kNodeKey, this);
+}
+
+Node::~Node() {
+}
+
+Node* Node::GetParent() {
+ if (!window_.parent())
+ return NULL;
+ return window_.parent()->GetProperty(kNodeKey);
+}
+
+void Node::Add(Node* child) {
+ window_.AddChild(&child->window_);
+}
+
+void Node::Remove(Node* child) {
+ window_.RemoveChild(&child->window_);
+}
+
+void Node::OnWindowHierarchyChanged(
+ const aura::WindowObserver::HierarchyChangeParams& params) {
+ if (params.target != &window_ || params.receiver != &window_)
+ return;
+ NodeId new_parent_id;
+ if (params.new_parent)
+ new_parent_id = params.new_parent->GetProperty(kNodeKey)->id();
+ NodeId old_parent_id;
+ if (params.old_parent)
+ old_parent_id = params.old_parent->GetProperty(kNodeKey)->id();
+ delegate_->OnNodeHierarchyChanged(id_, new_parent_id, old_parent_id);
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/view_manager/node.h b/mojo/services/view_manager/node.h
new file mode 100644
index 0000000000..5892af058e
--- /dev/null
+++ b/mojo/services/view_manager/node.h
@@ -0,0 +1,53 @@
+// 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_SERVICES_VIEW_MANAGER_NODE_H_
+#define MOJO_SERVICES_VIEW_MANAGER_NODE_H_
+
+#include "base/logging.h"
+#include "mojo/services/view_manager/ids.h"
+#include "mojo/services/view_manager/view_manager_export.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class NodeDelegate;
+
+// Represents a node in the graph. Delegate is informed of interesting events.
+class MOJO_VIEW_MANAGER_EXPORT Node : public aura::WindowObserver {
+ public:
+ Node(NodeDelegate* delegate, const NodeId& id);
+ virtual ~Node();
+
+ void set_view_id(const ViewId& view_id) { view_id_ = view_id; }
+ const ViewId& view_id() const { return view_id_; }
+
+ const NodeId& id() const { return id_; }
+
+ void Add(Node* child);
+ void Remove(Node* child);
+
+ Node* GetParent();
+
+ private:
+ // WindowObserver overrides:
+ virtual void OnWindowHierarchyChanged(
+ const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE;
+
+ NodeDelegate* delegate_;
+ const NodeId id_;
+ ViewId view_id_;
+ aura::Window window_;
+
+ DISALLOW_COPY_AND_ASSIGN(Node);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_VIEW_MANAGER_NODE_H_
diff --git a/mojo/services/view_manager/node_delegate.h b/mojo/services/view_manager/node_delegate.h
new file mode 100644
index 0000000000..3e34940ffc
--- /dev/null
+++ b/mojo/services/view_manager/node_delegate.h
@@ -0,0 +1,31 @@
+// 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_SERVICES_VIEW_MANAGER_NODE_DELEGATE_H_
+#define MOJO_SERVICES_VIEW_MANAGER_NODE_DELEGATE_H_
+
+#include "mojo/services/view_manager/view_manager_export.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+struct NodeId;
+
+class MOJO_VIEW_MANAGER_EXPORT NodeDelegate {
+ public:
+ // Invoked when the hierarchy has changed.
+ virtual void OnNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent) = 0;
+
+ protected:
+ virtual ~NodeDelegate() {}
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_VIEW_MANAGER_NODE_DELEGATE_H_
diff --git a/mojo/services/view_manager/root_node_manager.cc b/mojo/services/view_manager/root_node_manager.cc
new file mode 100644
index 0000000000..f35df3da29
--- /dev/null
+++ b/mojo/services/view_manager/root_node_manager.cc
@@ -0,0 +1,106 @@
+// 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/services/view_manager/root_node_manager.h"
+
+#include "base/logging.h"
+#include "mojo/services/view_manager/view_manager_connection.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+namespace {
+
+// Id for the root node.
+const uint16_t kRootId = 1;
+
+} // namespace
+
+RootNodeManager::ScopedChange::ScopedChange(ViewManagerConnection* connection,
+ RootNodeManager* root,
+ int32_t change_id)
+ : root_(root) {
+ root_->PrepareForChange(connection, change_id);
+}
+
+RootNodeManager::ScopedChange::~ScopedChange() {
+ root_->FinishChange();
+}
+
+RootNodeManager::RootNodeManager()
+ : next_connection_id_(1),
+ root_(this, NodeId(0, kRootId)) {
+}
+
+RootNodeManager::~RootNodeManager() {
+}
+
+uint16_t RootNodeManager::GetAndAdvanceNextConnectionId() {
+ const uint16_t id = next_connection_id_++;
+ DCHECK_LT(id, next_connection_id_);
+ return id;
+}
+
+void RootNodeManager::AddConnection(ViewManagerConnection* connection) {
+ DCHECK_EQ(0u, connection_map_.count(connection->id()));
+ connection_map_[connection->id()] = connection;
+}
+
+void RootNodeManager::RemoveConnection(ViewManagerConnection* connection) {
+ connection_map_.erase(connection->id());
+}
+
+Node* RootNodeManager::GetNode(const NodeId& id) {
+ if (id == root_.id())
+ return &root_;
+ ConnectionMap::iterator i = connection_map_.find(id.connection_id);
+ return i == connection_map_.end() ? NULL : i->second->GetNode(id);
+}
+
+void RootNodeManager::NotifyNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent) {
+ for (ConnectionMap::iterator i = connection_map_.begin();
+ i != connection_map_.end(); ++i) {
+ const int32_t change_id = (change_ && i->first == change_->connection_id) ?
+ change_->change_id : 0;
+ i->second->NotifyNodeHierarchyChanged(
+ node, new_parent, old_parent, change_id);
+ }
+}
+
+void RootNodeManager::PrepareForChange(ViewManagerConnection* connection,
+ int32_t change_id) {
+ DCHECK(!change_.get()); // Should only ever have one change in flight.
+ change_.reset(new Change(connection->id(), change_id));
+}
+
+void RootNodeManager::FinishChange() {
+ DCHECK(change_.get()); // PrepareForChange/FinishChange should be balanced.
+ change_.reset();
+}
+
+void RootNodeManager::OnCreated() {
+}
+
+void RootNodeManager::OnDestroyed() {
+}
+
+void RootNodeManager::OnBoundsChanged(const Rect& bounds) {
+}
+
+void RootNodeManager::OnEvent(const Event& event,
+ const mojo::Callback<void()>& callback) {
+ callback.Run();
+}
+
+void RootNodeManager::OnNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent) {
+ NotifyNodeHierarchyChanged(node, new_parent, old_parent);
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/view_manager/root_node_manager.h b/mojo/services/view_manager/root_node_manager.h
new file mode 100644
index 0000000000..aecfa8b738
--- /dev/null
+++ b/mojo/services/view_manager/root_node_manager.h
@@ -0,0 +1,117 @@
+// 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_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_
+#define MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "mojo/services/native_viewport/native_viewport.mojom.h"
+#include "mojo/services/view_manager/node.h"
+#include "mojo/services/view_manager/node_delegate.h"
+#include "mojo/services/view_manager/view_manager_export.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class View;
+class ViewManagerConnection;
+
+// RootNodeManager is responsible for managing the set of ViewManagerConnections
+// as well as providing the root of the node hierarchy.
+class MOJO_VIEW_MANAGER_EXPORT RootNodeManager
+ : public NativeViewportClient,
+ public NodeDelegate {
+ public:
+ // Create when a ViewManagerConnection is about to make a change. Ensures
+ // clients are notified of the correct change id.
+ class ScopedChange {
+ public:
+ ScopedChange(ViewManagerConnection* connection,
+ RootNodeManager* root,
+ int32_t change_id);
+ ~ScopedChange();
+
+ private:
+ RootNodeManager* root_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedChange);
+ };
+
+ RootNodeManager();
+ virtual ~RootNodeManager();
+
+ // Returns the id for the next ViewManagerConnection.
+ uint16_t GetAndAdvanceNextConnectionId();
+
+ void AddConnection(ViewManagerConnection* connection);
+ void RemoveConnection(ViewManagerConnection* connection);
+
+ // Returns the Node identified by |id|.
+ Node* GetNode(const NodeId& id);
+
+ // Notifies all ViewManagerConnections of a hierarchy change.
+ void NotifyNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent);
+
+ private:
+ // Tracks a change.
+ struct Change {
+ Change(int32_t connection_id, int32_t change_id)
+ : connection_id(connection_id),
+ change_id(change_id) {
+ }
+
+ int32_t connection_id;
+ int32_t change_id;
+ };
+
+ typedef std::map<uint16_t, ViewManagerConnection*> ConnectionMap;
+
+ // Invoked when a particular connection is about to make a change. Records
+ // the |change_id| so that it can be supplied to the clients by way of
+ // OnNodeHierarchyChanged().
+ // Changes should never nest, meaning each PrepareForChange() must be
+ // balanced with a call to FinishChange() with no PrepareForChange()
+ // in between.
+ void PrepareForChange(ViewManagerConnection* connection, int32_t change_id);
+
+ // Balances a call to PrepareForChange().
+ void FinishChange();
+
+ // Overridden from NativeViewportClient:
+ virtual void OnCreated() OVERRIDE;
+ virtual void OnDestroyed() OVERRIDE;
+ virtual void OnBoundsChanged(const Rect& bounds) OVERRIDE;
+ virtual void OnEvent(const Event& event,
+ const mojo::Callback<void()>& callback) OVERRIDE;
+
+ // Overriden from NodeDelegate:
+ virtual void OnNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent) OVERRIDE;
+
+ // ID to use for next ViewManagerConnection.
+ uint16_t next_connection_id_;
+
+ // Set of ViewManagerConnections.
+ ConnectionMap connection_map_;
+
+ // Root node.
+ Node root_;
+
+ // If non-null we're processing a change.
+ scoped_ptr<Change> change_;
+
+ DISALLOW_COPY_AND_ASSIGN(RootNodeManager);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_
diff --git a/mojo/services/view_manager/view_manager.cc b/mojo/services/view_manager/view_manager.cc
new file mode 100644
index 0000000000..e2e09f5cb2
--- /dev/null
+++ b/mojo/services/view_manager/view_manager.cc
@@ -0,0 +1,32 @@
+// 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/message_loop/message_loop.h"
+#include "mojo/public/cpp/shell/application.h"
+#include "mojo/services/view_manager/root_node_manager.h"
+#include "mojo/services/view_manager/view_manager_connection.h"
+
+#if defined(WIN32)
+#if !defined(CDECL)
+#define CDECL __cdecl)
+#endif
+#define VIEW_MANAGER_EXPORT __declspec(dllexport)
+#else
+#define CDECL
+#define VIEW_MANAGER_EXPORT __attribute__((visibility("default")))
+#endif
+
+extern "C" VIEW_MANAGER_EXPORT MojoResult CDECL MojoMain(
+ MojoHandle shell_handle) {
+ base::MessageLoop loop;
+ mojo::Application app(shell_handle);
+ mojo::services::view_manager::RootNodeManager root_node_manager;
+ app.AddServiceConnector(new mojo::ServiceConnector
+ <mojo::services::view_manager::ViewManagerConnection,
+ mojo::services::view_manager::RootNodeManager>(
+ &root_node_manager));
+ loop.Run();
+
+ return MOJO_RESULT_OK;
+}
diff --git a/mojo/services/view_manager/view_manager_connection.cc b/mojo/services/view_manager/view_manager_connection.cc
new file mode 100644
index 0000000000..83c061b497
--- /dev/null
+++ b/mojo/services/view_manager/view_manager_connection.cc
@@ -0,0 +1,101 @@
+// 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/services/view_manager/view_manager_connection.h"
+
+#include "base/stl_util.h"
+#include "mojo/services/view_manager/node.h"
+#include "mojo/services/view_manager/root_node_manager.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+ViewManagerConnection::ViewManagerConnection() : id_(0) {
+}
+
+ViewManagerConnection::~ViewManagerConnection() {
+ STLDeleteContainerPairSecondPointers(node_map_.begin(), node_map_.end());
+ context()->RemoveConnection(this);
+}
+
+void ViewManagerConnection::Initialize(
+ ServiceConnector<ViewManagerConnection, RootNodeManager>* service_factory,
+ ScopedMessagePipeHandle client_handle) {
+ DCHECK_EQ(0, id_); // Should only get Initialize() once.
+ ServiceConnection<ViewManager, ViewManagerConnection, RootNodeManager>::
+ Initialize(service_factory, client_handle.Pass());
+ id_ = context()->GetAndAdvanceNextConnectionId();
+ context()->AddConnection(this);
+ client()->OnConnectionEstablished(id_);
+}
+
+Node* ViewManagerConnection::GetNode(const NodeId& id) {
+ if (id_ == id.connection_id) {
+ NodeMap::iterator i = node_map_.find(id.node_id);
+ return i == node_map_.end() ? NULL : i->second;
+ }
+ return context()->GetNode(id);
+}
+
+void ViewManagerConnection::NotifyNodeHierarchyChanged(
+ const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent,
+ int32_t change_id) {
+ client()->OnNodeHierarchyChanged(NodeIdToTransportId(node),
+ NodeIdToTransportId(new_parent),
+ NodeIdToTransportId(old_parent),
+ change_id);
+}
+
+void ViewManagerConnection::CreateNode(
+ uint16_t node_id,
+ const Callback<void(bool)>& callback) {
+ // Negative values are reserved.
+ if (node_map_.find(node_id) != node_map_.end()) {
+ callback.Run(false);
+ return;
+ }
+ node_map_[node_id] = new Node(this, NodeId(id_, node_id));
+ callback.Run(true);
+}
+
+void ViewManagerConnection::AddNode(
+ uint32_t parent_id,
+ uint32_t child_id,
+ int32_t change_id,
+ const Callback<void(bool)>& callback) {
+ Node* parent = GetNode(NodeIdFromTransportId(parent_id));
+ Node* child = GetNode(NodeIdFromTransportId(child_id));
+ const bool success = parent && child && parent != child;
+ if (success) {
+ RootNodeManager::ScopedChange change(this, context(), change_id);
+ parent->Add(child);
+ }
+ callback.Run(success);
+}
+
+void ViewManagerConnection::RemoveNodeFromParent(
+ uint32_t node_id,
+ int32_t change_id,
+ const Callback<void(bool)>& callback) {
+ Node* node = GetNode(NodeIdFromTransportId(node_id));
+ const bool success = (node && node->GetParent());
+ if (success) {
+ RootNodeManager::ScopedChange change(this, context(), change_id);
+ node->GetParent()->Remove(node);
+ }
+ callback.Run(success);
+}
+
+void ViewManagerConnection::OnNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent) {
+ context()->NotifyNodeHierarchyChanged(node, new_parent, old_parent);
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/view_manager/view_manager_connection.h b/mojo/services/view_manager/view_manager_connection.h
new file mode 100644
index 0000000000..a03ef6ae0b
--- /dev/null
+++ b/mojo/services/view_manager/view_manager_connection.h
@@ -0,0 +1,81 @@
+// 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_SERVICES_VIEW_MANAGER_VIEW_MANAGER_CONNECTION_H_
+#define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_CONNECTION_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "mojo/public/cpp/shell/service.h"
+#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
+#include "mojo/services/view_manager/node_delegate.h"
+#include "mojo/services/view_manager/view_manager_export.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class Node;
+class RootNodeManager;
+
+// Manages a connection from the client.
+class MOJO_VIEW_MANAGER_EXPORT ViewManagerConnection
+ : public ServiceConnection<ViewManager, ViewManagerConnection,
+ RootNodeManager>,
+ public NodeDelegate {
+ public:
+ ViewManagerConnection();
+ virtual ~ViewManagerConnection();
+
+ uint16_t id() const { return id_; }
+
+ // Invoked from Service when connection is established.
+ void Initialize(
+ ServiceConnector<ViewManagerConnection, RootNodeManager>* service_factory,
+ ScopedMessagePipeHandle client_handle);
+
+ // Returns the Node by id.
+ Node* GetNode(const NodeId& id);
+
+ // Notifies the client of a hierarchy change.
+ void NotifyNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent,
+ int32_t change_id);
+
+ private:
+ typedef std::map<uint16_t, Node*> NodeMap;
+
+ // Overridden from ViewManager:
+ virtual void CreateNode(uint16_t node_id,
+ const Callback<void(bool)>& callback) OVERRIDE;
+ virtual void AddNode(uint32_t parent_id,
+ uint32_t child_id,
+ int32_t change_id,
+ const Callback<void(bool)>& callback) OVERRIDE;
+ virtual void RemoveNodeFromParent(
+ uint32_t node_id,
+ int32_t change_id,
+ const Callback<void(bool)>& callback) OVERRIDE;
+
+ // Overriden from NodeDelegate:
+ virtual void OnNodeHierarchyChanged(const NodeId& node,
+ const NodeId& new_parent,
+ const NodeId& old_parent) OVERRIDE;
+
+ // Id of this connection as assigned by RootNodeManager. Assigned in
+ // Initialize().
+ uint16_t id_;
+
+ NodeMap node_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewManagerConnection);
+};
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_CONNECTION_H_
diff --git a/mojo/services/view_manager/view_manager_connection_unittest.cc b/mojo/services/view_manager/view_manager_connection_unittest.cc
new file mode 100644
index 0000000000..88bf323ea3
--- /dev/null
+++ b/mojo/services/view_manager/view_manager_connection_unittest.cc
@@ -0,0 +1,307 @@
+// 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/services/view_manager/view_manager_connection.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "mojo/public/cpp/bindings/allocation_scope.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/services/view_manager/root_node_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+namespace {
+
+base::RunLoop* current_run_loop = NULL;
+
+// Sets |current_run_loop| and runs it. It is expected that someone else quits
+// the loop.
+void DoRunLoop() {
+ base::RunLoop run_loop;
+ current_run_loop = &run_loop;
+ current_run_loop->Run();
+ current_run_loop = NULL;
+}
+
+// Converts |id| into a string.
+std::string NodeIdToString(uint32_t id) {
+ return (id == 0) ? "null" :
+ base::StringPrintf("%d,%d", FirstIdFromTransportId(id),
+ SecondIdFromTransportId(id));
+}
+
+// Boolean callback. Sets |result_cache| to the value of |result| and quits
+// the run loop.
+void BooleanCallback(bool* result_cache, bool result) {
+ *result_cache = result;
+ current_run_loop->Quit();
+}
+
+// Creates an id used for transport from the specified parameters.
+uint32_t CreateNodeId(uint16_t connection_id, uint16_t node_id) {
+ return NodeIdToTransportId(NodeId(connection_id, node_id));
+}
+
+// Creates a node with the specified id. Returns true on success. Blocks until
+// we get back result from server.
+bool CreateNode(ViewManager* view_manager, uint16_t id) {
+ bool result = false;
+ view_manager->CreateNode(id, base::Bind(&BooleanCallback, &result));
+ DoRunLoop();
+ return result;
+}
+
+// Adds a node, blocking until done.
+bool AddNode(ViewManager* view_manager,
+ uint32_t parent,
+ uint32_t child,
+ int32_t change_id) {
+ bool result = false;
+ view_manager->AddNode(parent, child, change_id,
+ base::Bind(&BooleanCallback, &result));
+ DoRunLoop();
+ return result;
+}
+
+// Removes a node, blocking until done.
+bool RemoveNodeFromParent(ViewManager* view_manager,
+ uint32_t node_id,
+ int32_t change_id) {
+ bool result = false;
+ view_manager->RemoveNodeFromParent(node_id, change_id,
+ base::Bind(&BooleanCallback, &result));
+ DoRunLoop();
+ return result;
+}
+
+} // namespace
+
+typedef std::vector<std::string> Changes;
+
+class ViewManagerClientImpl : public ViewManagerClient {
+ public:
+ ViewManagerClientImpl() : id_(0), quit_count_(0) {}
+
+ void set_quit_count(int count) { quit_count_ = count; }
+
+ uint16_t id() const { return id_; }
+
+ Changes GetAndClearChanges() {
+ Changes changes;
+ changes.swap(changes_);
+ return changes;
+ }
+
+ private:
+ // ViewManagerClient overrides:
+ virtual void OnConnectionEstablished(uint16_t connection_id) OVERRIDE {
+ id_ = connection_id;
+ current_run_loop->Quit();
+ }
+ virtual void OnNodeHierarchyChanged(uint32_t node,
+ uint32_t new_parent,
+ uint32_t old_parent,
+ int32_t change_id) OVERRIDE {
+ changes_.push_back(
+ base::StringPrintf(
+ "change_id=%d node=%s new_parent=%s old_parent=%s",
+ change_id, NodeIdToString(node).c_str(),
+ NodeIdToString(new_parent).c_str(),
+ NodeIdToString(old_parent).c_str()));
+ if (quit_count_ > 0) {
+ if (--quit_count_ == 0)
+ current_run_loop->Quit();
+ }
+ }
+
+ uint16_t id_;
+
+ // Used to determine when/if to quit the run loop.
+ int quit_count_;
+
+ Changes changes_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewManagerClientImpl);
+};
+
+class ViewManagerConnectionTest : public testing::Test {
+ public:
+ ViewManagerConnectionTest() : service_factory_(&root_node_manager_) {}
+
+ virtual void SetUp() OVERRIDE {
+ InterfacePipe<ViewManagerClient, ViewManager> pipe;
+ view_manager_.reset(pipe.handle_to_peer.Pass(), &client_);
+ connection_.Initialize(
+ &service_factory_,
+ ScopedMessagePipeHandle::From(pipe.handle_to_self.Pass()));
+ // Wait for the id.
+ DoRunLoop();
+ }
+
+ protected:
+ // Creates a second connection to the viewmanager.
+ void EstablishSecondConnection() {
+ connection2_.reset(new ViewManagerConnection);
+ InterfacePipe<ViewManagerClient, ViewManager> pipe;
+ view_manager2_.reset(pipe.handle_to_peer.Pass(), &client2_);
+ connection2_->Initialize(
+ &service_factory_,
+ ScopedMessagePipeHandle::From(pipe.handle_to_self.Pass()));
+ // Wait for the id.
+ DoRunLoop();
+ }
+
+ Environment env_;
+ base::MessageLoop loop_;
+ RootNodeManager root_node_manager_;
+ ServiceConnector<ViewManagerConnection, RootNodeManager> service_factory_;
+ ViewManagerConnection connection_;
+ ViewManagerClientImpl client_;
+ RemotePtr<ViewManager> view_manager_;
+
+ ViewManagerClientImpl client2_;
+ RemotePtr<ViewManager> view_manager2_;
+ scoped_ptr<ViewManagerConnection> connection2_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewManagerConnectionTest);
+};
+
+// Verifies client gets a valid id.
+TEST_F(ViewManagerConnectionTest, ValidId) {
+ EXPECT_NE(0, client_.id());
+}
+
+// Verifies two clients/connections get different ids.
+TEST_F(ViewManagerConnectionTest, TwoClientsGetDifferentConnectionIds) {
+ EstablishSecondConnection();
+ EXPECT_NE(0, client2_.id());
+ EXPECT_NE(client_.id(), client2_.id());
+}
+
+// Verifies client gets a valid id.
+TEST_F(ViewManagerConnectionTest, CreateNode) {
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1));
+
+ // Can't create a node with the same id.
+ ASSERT_FALSE(CreateNode(view_manager_.get(), 1));
+}
+
+// Verifies hierarchy changes.
+TEST_F(ViewManagerConnectionTest, AddRemoveNotify) {
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1));
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 2));
+
+ EXPECT_TRUE(client_.GetAndClearChanges().empty());
+
+ // Make 2 a child of 1.
+ {
+ AllocationScope scope;
+ ASSERT_TRUE(AddNode(view_manager_.get(),
+ CreateNodeId(client_.id(), 1),
+ CreateNodeId(client_.id(), 2),
+ 11));
+ Changes changes(client_.GetAndClearChanges());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("change_id=11 node=1,2 new_parent=1,1 old_parent=null",
+ changes[0]);
+ }
+
+ // Remove 2 from its parent.
+ {
+ AllocationScope scope;
+ ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(),
+ CreateNodeId(client_.id(), 2),
+ 101));
+ Changes changes(client_.GetAndClearChanges());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("change_id=101 node=1,2 new_parent=null old_parent=1,1",
+ changes[0]);
+ }
+}
+
+// Verifies hierarchy changes are sent to multiple clients.
+TEST_F(ViewManagerConnectionTest, AddRemoveNotifyMultipleConnections) {
+ EstablishSecondConnection();
+
+ // Create two nodes in first connection.
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1));
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 2));
+
+ EXPECT_TRUE(client_.GetAndClearChanges().empty());
+ EXPECT_TRUE(client2_.GetAndClearChanges().empty());
+
+ // Make 2 a child of 1.
+ {
+ AllocationScope scope;
+ ASSERT_TRUE(AddNode(view_manager_.get(),
+ CreateNodeId(client_.id(), 1),
+ CreateNodeId(client_.id(), 2),
+ 11));
+ Changes changes(client_.GetAndClearChanges());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("change_id=11 node=1,2 new_parent=1,1 old_parent=null",
+ changes[0]);
+ }
+
+ // Second client should also have received the change.
+ {
+ Changes changes(client2_.GetAndClearChanges());
+ if (changes.empty()) {
+ client2_.set_quit_count(1);
+ DoRunLoop();
+ changes = client2_.GetAndClearChanges();
+ }
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("change_id=0 node=1,2 new_parent=1,1 old_parent=null",
+ changes[0]);
+ }
+}
+
+// Verifies adding to root sends right notifications.
+TEST_F(ViewManagerConnectionTest, AddToRoot) {
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 21));
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 3));
+
+ EXPECT_TRUE(client_.GetAndClearChanges().empty());
+
+ // Make 3 a child of 21.
+ {
+ AllocationScope scope;
+ ASSERT_TRUE(AddNode(view_manager_.get(),
+ CreateNodeId(client_.id(), 21),
+ CreateNodeId(client_.id(), 3),
+ 11));
+ Changes changes(client_.GetAndClearChanges());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("change_id=11 node=1,3 new_parent=1,21 old_parent=null",
+ changes[0]);
+ }
+
+ // Make 21 a child of the root.
+ {
+ AllocationScope scope;
+ ASSERT_TRUE(AddNode(view_manager_.get(),
+ CreateNodeId(0, 1),
+ CreateNodeId(client_.id(), 21),
+ 44));
+ Changes changes(client_.GetAndClearChanges());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("change_id=44 node=1,21 new_parent=0,1 old_parent=null",
+ changes[0]);
+ }
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/view_manager/view_manager_export.h b/mojo/services/view_manager/view_manager_export.h
new file mode 100644
index 0000000000..29b0e6219c
--- /dev/null
+++ b/mojo/services/view_manager/view_manager_export.h
@@ -0,0 +1,31 @@
+// 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_SERVICES_VIEW_MANAGER_VIEW_MANAGER_EXPORT_H_
+#define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(MOJO_VIEW_MANAGER_IMPLEMENTATION)
+#define MOJO_VIEW_MANAGER_EXPORT __declspec(dllexport)
+#else
+#define MOJO_VIEW_MANAGER_EXPORT __declspec(dllimport)
+#endif
+
+#else // !defined(WIN32)
+
+#if defined(MOJO_VIEW_MANAGER_IMPLEMENTATION)
+#define MOJO_VIEW_MANAGER_EXPORT __attribute__((visibility("default")))
+#else
+#define MOJO_VIEW_MANAGER_EXPORT
+#endif
+
+#endif // defined(WIN32)
+
+#else // defined(COMPONENT_BUILD)
+#define MOJO_VIEW_MANAGER_EXPORT
+#endif
+
+#endif // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_EXPORT_H_
diff --git a/mojo/shell/android/mojo_main.cc b/mojo/shell/android/mojo_main.cc
index a9128646e4..9d70c8fecd 100644
--- a/mojo/shell/android/mojo_main.cc
+++ b/mojo/shell/android/mojo_main.cc
@@ -13,10 +13,10 @@
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "jni/MojoMain_jni.h"
+#include "mojo/public/cpp/environment/environment.h"
#include "mojo/public/cpp/shell/application.h"
#include "mojo/service_manager/service_loader.h"
#include "mojo/service_manager/service_manager.h"
-#include "mojo/services/native_viewport/native_viewport_service.h"
#include "mojo/shell/context.h"
#include "mojo/shell/init.h"
#include "mojo/shell/run.h"
@@ -34,28 +34,9 @@ LazyInstance<scoped_ptr<base::MessageLoop> > g_java_message_loop =
LazyInstance<scoped_ptr<shell::Context> > g_context =
LAZY_INSTANCE_INITIALIZER;
-class NativeViewportServiceLoader : public ServiceLoader {
- public:
- NativeViewportServiceLoader() {}
- virtual ~NativeViewportServiceLoader() {}
-
- private:
- virtual void LoadService(ServiceManager* manager,
- const GURL& url,
- ScopedShellHandle service_handle) OVERRIDE {
- app_.reset(CreateNativeViewportService(g_context.Get().get(),
- service_handle.Pass()));
- }
-
- virtual void OnServiceError(ServiceManager* manager,
- const GURL& url) OVERRIDE {
- }
- scoped_ptr<Application> app_;
-};
-
-LazyInstance<scoped_ptr<NativeViewportServiceLoader> >
- g_viewport_service_loader = LAZY_INSTANCE_INITIALIZER;
+LazyInstance<scoped_ptr<mojo::Environment> > g_env =
+ LAZY_INSTANCE_INITIALIZER;
} // namspace
@@ -93,15 +74,13 @@ static void Start(JNIEnv* env, jclass clazz, jobject context, jstring jurl) {
CommandLine::ForCurrentProcess()->InitFromArgv(argv);
}
+ g_env.Get().reset(new Environment);
+
base::android::ScopedJavaGlobalRef<jobject> activity;
activity.Reset(env, context);
shell::Context* shell_context = new shell::Context();
shell_context->set_activity(activity.obj());
- g_viewport_service_loader.Get().reset(new NativeViewportServiceLoader());
- shell_context->service_manager()->SetLoaderForURL(
- g_viewport_service_loader.Get().get(),
- GURL("mojo:mojo_native_viewport_service"));
g_context.Get().reset(shell_context);
shell::Run(shell_context);
diff --git a/mojo/shell/context.cc b/mojo/shell/context.cc
index 2ba4aef4f1..df86d14bfc 100644
--- a/mojo/shell/context.cc
+++ b/mojo/shell/context.cc
@@ -59,12 +59,12 @@ Context::Context()
else
runner_factory.reset(new InProcessDynamicServiceRunnerFactory());
- dynamic_service_loader_.reset(
- new DynamicServiceLoader(this, runner_factory.Pass()));
- service_manager_.set_default_loader(dynamic_service_loader_.get());
- native_viewport_service_loader_.reset(new NativeViewportServiceLoader(this));
- service_manager_.SetLoaderForURL(native_viewport_service_loader_.get(),
- GURL("mojo:mojo_native_viewport_service"));
+ service_manager_.set_default_loader(
+ scoped_ptr<ServiceLoader>(
+ new DynamicServiceLoader(this, runner_factory.Pass())));
+ service_manager_.SetLoaderForURL(
+ scoped_ptr<ServiceLoader>(new NativeViewportServiceLoader(this)),
+ GURL("mojo:mojo_native_viewport_service"));
if (cmdline->HasSwitch(switches::kSpy)) {
spy_.reset(new mojo::Spy(&service_manager_,
@@ -73,7 +73,7 @@ Context::Context()
}
Context::~Context() {
- service_manager_.set_default_loader(NULL);
+ service_manager_.set_default_loader(scoped_ptr<ServiceLoader>());
}
} // namespace shell
diff --git a/mojo/shell/context.h b/mojo/shell/context.h
index 57ed5d508a..c9acdc4fb1 100644
--- a/mojo/shell/context.h
+++ b/mojo/shell/context.h
@@ -46,9 +46,7 @@ class Context {
Storage storage_;
Loader loader_;
ServiceManager service_manager_;
- scoped_ptr<DynamicServiceLoader> dynamic_service_loader_;
scoped_ptr<Spy> spy_;
- scoped_ptr<NativeViewportServiceLoader> native_viewport_service_loader_;
#if defined(OS_ANDROID)
base::android::ScopedJavaGlobalRef<jobject> activity_;
#endif // defined(OS_ANDROID)
diff --git a/mojo/system/channel.cc b/mojo/system/channel.cc
index 770275a1a8..b0b9df93cf 100644
--- a/mojo/system/channel.cc
+++ b/mojo/system/channel.cc
@@ -4,11 +4,14 @@
#include "mojo/system/channel.h"
+#include <algorithm>
+
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h" // TODO(vtl): Remove this.
#include "mojo/system/message_pipe_endpoint.h"
namespace mojo {
@@ -21,12 +24,15 @@ COMPILE_ASSERT(Channel::kBootstrapEndpointId !=
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId
Channel::kBootstrapEndpointId;
-Channel::EndpointInfo::EndpointInfo() {
+Channel::EndpointInfo::EndpointInfo()
+ : state(STATE_NORMAL),
+ port() {
}
Channel::EndpointInfo::EndpointInfo(scoped_refptr<MessagePipe> message_pipe,
unsigned port)
- : message_pipe(message_pipe),
+ : state(STATE_NORMAL),
+ message_pipe(message_pipe),
port(port) {
}
@@ -34,7 +40,8 @@ Channel::EndpointInfo::~EndpointInfo() {
}
Channel::Channel()
- : next_local_id_(kBootstrapEndpointId) {
+ : is_running_(false),
+ next_local_id_(kBootstrapEndpointId) {
}
bool Channel::Init(scoped_ptr<RawChannel> raw_channel) {
@@ -43,7 +50,7 @@ bool Channel::Init(scoped_ptr<RawChannel> raw_channel) {
// No need to take |lock_|, since this must be called before this object
// becomes thread-safe.
- DCHECK(!raw_channel_);
+ DCHECK(!is_running_no_lock());
raw_channel_ = raw_channel.Pass();
if (!raw_channel_->Init(this)) {
@@ -51,34 +58,50 @@ bool Channel::Init(scoped_ptr<RawChannel> raw_channel) {
return false;
}
+ is_running_ = true;
return true;
}
void Channel::Shutdown() {
DCHECK(creation_thread_checker_.CalledOnValidThread());
- base::AutoLock locker(lock_);
- DCHECK(raw_channel_.get());
- raw_channel_->Shutdown();
- raw_channel_.reset();
-
- // This should not occur, but it probably mostly results in leaking;
- // (Explicitly clearing the |local_id_to_endpoint_info_map_| would likely put
- // things in an inconsistent state, which is worse. Note that if the map is
- // nonempty, we probably won't be destroyed, since the endpoints have a
- // reference to us.)
- LOG_IF(ERROR, !local_id_to_endpoint_info_map_.empty())
- << "Channel shutting down with endpoints still attached";
- // TODO(vtl): This currently blows up, but the fix will be nontrivial.
- // crbug.com/360081
- //DCHECK(local_id_to_endpoint_info_map_.empty());
+ IdToEndpointInfoMap to_destroy;
+ {
+ base::AutoLock locker(lock_);
+ if (!is_running_no_lock())
+ return;
+
+ // Note: Don't reset |raw_channel_|, in case we're being called from within
+ // |OnReadMessage()| or |OnFatalError()|.
+ raw_channel_->Shutdown();
+ is_running_ = false;
+
+ // We need to deal with it outside the lock.
+ std::swap(to_destroy, local_id_to_endpoint_info_map_);
+ }
+
+ size_t num_live = 0;
+ size_t num_zombies = 0;
+ for (IdToEndpointInfoMap::iterator it = to_destroy.begin();
+ it != to_destroy.end();
+ ++it) {
+ if (it->second.state == EndpointInfo::STATE_NORMAL) {
+ it->second.message_pipe->OnRemove(it->second.port);
+ num_live++;
+ } else {
+ DCHECK(!it->second.message_pipe.get());
+ num_zombies++;
+ }
+ }
+ DVLOG(2) << "Shut down Channel with " << num_live << " live endpoints and "
+ << num_zombies << " zombies";
}
MessageInTransit::EndpointId Channel::AttachMessagePipeEndpoint(
- scoped_refptr<MessagePipe> message_pipe, unsigned port) {
+ scoped_refptr<MessagePipe> message_pipe,
+ unsigned port) {
+ DCHECK(message_pipe);
DCHECK(port == 0 || port == 1);
- // Note: This assertion must *not* be done under |lock_|.
- DCHECK_EQ(message_pipe->GetType(port), MessagePipeEndpoint::kTypeProxy);
MessageInTransit::EndpointId local_id;
{
@@ -98,8 +121,32 @@ MessageInTransit::EndpointId Channel::AttachMessagePipeEndpoint(
local_id_to_endpoint_info_map_[local_id] = EndpointInfo(message_pipe, port);
}
- message_pipe->Attach(port, scoped_refptr<Channel>(this), local_id);
- return local_id;
+ // This might fail if that port got an |OnPeerClose()| before attaching.
+ if (message_pipe->Attach(port, scoped_refptr<Channel>(this), local_id))
+ return local_id;
+
+ // Note: If it failed, quite possibly the endpoint info was removed from that
+ // map (there's a race between us adding it to the map above and calling
+ // |Attach()|). And even if an entry exists for |local_id|, we need to check
+ // that it's the one we added (and not some other one that was added since).
+ {
+ base::AutoLock locker(lock_);
+ IdToEndpointInfoMap::iterator it =
+ local_id_to_endpoint_info_map_.find(local_id);
+ if (it != local_id_to_endpoint_info_map_.end() &&
+ it->second.message_pipe.get() == message_pipe.get() &&
+ it->second.port == port) {
+ DCHECK_EQ(it->second.state, EndpointInfo::STATE_NORMAL);
+ // TODO(vtl): FIXME -- This is wrong. We need to specify (to
+ // |AttachMessagePipeEndpoint()| who's going to be responsible for calling
+ // |RunMessagePipeEndpoint()| ("us", or the remote by sending us a
+ // |kSubtypeChannelRunMessagePipeEndpoint|). If the remote is going to
+ // run, then we'll get messages to an "invalid" local ID (for running, for
+ // removal).
+ local_id_to_endpoint_info_map_.erase(it);
+ }
+ }
+ return MessageInTransit::kInvalidEndpointId;
}
bool Channel::RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
@@ -115,6 +162,14 @@ bool Channel::RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
endpoint_info = it->second;
}
+ // Assume that this was in response to |kSubtypeChannelRunMessagePipeEndpoint|
+ // and ignore it.
+ if (endpoint_info.state != EndpointInfo::STATE_NORMAL) {
+ DVLOG(2) << "Ignoring run message pipe endpoint for zombie endpoint "
+ "(local ID " << local_id << ", remote ID " << remote_id << ")";
+ return true;
+ }
+
// TODO(vtl): FIXME -- We need to handle the case that message pipe is already
// running when we're here due to |kSubtypeChannelRunMessagePipeEndpoint|).
endpoint_info.message_pipe->Run(endpoint_info.port, remote_id);
@@ -124,27 +179,27 @@ bool Channel::RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
void Channel::RunRemoteMessagePipeEndpoint(
MessageInTransit::EndpointId local_id,
MessageInTransit::EndpointId remote_id) {
- base::AutoLock locker(lock_);
-
- DCHECK(local_id_to_endpoint_info_map_.find(local_id) !=
- local_id_to_endpoint_info_map_.end());
+#if DCHECK_IS_ON
+ {
+ base::AutoLock locker(lock_);
+ DCHECK(local_id_to_endpoint_info_map_.find(local_id) !=
+ local_id_to_endpoint_info_map_.end());
+ }
+#endif
- scoped_ptr<MessageInTransit> message(new MessageInTransit(
- MessageInTransit::kTypeChannel,
- MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint,
- 0, 0, NULL));
- message->set_source_id(local_id);
- message->set_destination_id(remote_id);
- if (!raw_channel_->WriteMessage(message.Pass())) {
- // TODO(vtl): FIXME -- I guess we should report the error back somehow so
- // that the dispatcher can be closed?
- CHECK(false) << "Not yet handled";
+ if (!SendControlMessage(
+ MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint,
+ local_id, remote_id)) {
+ HandleLocalError(base::StringPrintf(
+ "Failed to send message to run remote message pipe endpoint (local ID "
+ "%u, remote ID %u)",
+ static_cast<unsigned>(local_id), static_cast<unsigned>(remote_id)));
}
}
bool Channel::WriteMessage(scoped_ptr<MessageInTransit> message) {
base::AutoLock locker(lock_);
- if (!raw_channel_.get()) {
+ if (!is_running_no_lock()) {
// TODO(vtl): I think this is probably not an error condition, but I should
// think about it (and the shutdown sequence) more carefully.
LOG(WARNING) << "WriteMessage() after shutdown";
@@ -156,24 +211,60 @@ bool Channel::WriteMessage(scoped_ptr<MessageInTransit> message) {
bool Channel::IsWriteBufferEmpty() {
base::AutoLock locker(lock_);
- DCHECK(raw_channel_.get());
+ if (!is_running_no_lock())
+ return true;
return raw_channel_->IsWriteBufferEmpty();
}
-void Channel::DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id) {
+void Channel::DetachMessagePipeEndpoint(
+ MessageInTransit::EndpointId local_id,
+ MessageInTransit::EndpointId remote_id) {
DCHECK_NE(local_id, MessageInTransit::kInvalidEndpointId);
- base::AutoLock locker_(lock_);
- local_id_to_endpoint_info_map_.erase(local_id);
+ bool should_send_remove_message = false;
+ {
+ base::AutoLock locker_(lock_);
+ if (!is_running_no_lock())
+ return;
+
+ IdToEndpointInfoMap::iterator it =
+ local_id_to_endpoint_info_map_.find(local_id);
+ DCHECK(it != local_id_to_endpoint_info_map_.end());
+
+ switch (it->second.state) {
+ case EndpointInfo::STATE_NORMAL:
+ it->second.state = EndpointInfo::STATE_WAIT_REMOTE_REMOVE_ACK;
+ it->second.message_pipe = NULL;
+ should_send_remove_message =
+ (remote_id != MessageInTransit::kInvalidEndpointId);
+ break;
+ case EndpointInfo::STATE_WAIT_LOCAL_DETACH:
+ local_id_to_endpoint_info_map_.erase(it);
+ break;
+ case EndpointInfo::STATE_WAIT_REMOTE_REMOVE_ACK:
+ NOTREACHED();
+ break;
+ case EndpointInfo::STATE_WAIT_LOCAL_DETACH_AND_REMOTE_REMOVE_ACK:
+ it->second.state = EndpointInfo::STATE_WAIT_REMOTE_REMOVE_ACK;
+ break;
+ }
+ }
+ if (!should_send_remove_message)
+ return;
+
+ if (!SendControlMessage(
+ MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint,
+ local_id, remote_id)) {
+ HandleLocalError(base::StringPrintf(
+ "Failed to send message to remove remote message pipe endpoint (local "
+ "ID %u, remote ID %u)",
+ static_cast<unsigned>(local_id), static_cast<unsigned>(remote_id)));
+ }
}
Channel::~Channel() {
// The channel should have been shut down first.
- DCHECK(!raw_channel_.get());
-
- DLOG_IF(WARNING, !local_id_to_endpoint_info_map_.empty())
- << "Destroying Channel with " << local_id_to_endpoint_info_map_.size()
- << " endpoints still present";
+ DCHECK(!is_running_no_lock());
}
void Channel::OnReadMessage(const MessageInTransit::View& message_view) {
@@ -198,8 +289,13 @@ void Channel::OnReadMessage(const MessageInTransit::View& message_view) {
}
void Channel::OnFatalError(FatalError fatal_error) {
- // TODO(vtl): IMPORTANT. Notify all our endpoints that they're dead.
- NOTIMPLEMENTED();
+ LOG(ERROR) << "RawChannel fatal error (type " << fatal_error << ")";
+ // TODO(vtl): We have some nested-deletion bugs on Windows, so this crashes.
+#if defined(OS_WIN)
+ LOG(ERROR) << "Not shutting down due Windows-only bug";
+#else
+ Shutdown();
+#endif
}
bool Channel::ValidateReadMessage(const MessageInTransit::View& message_view) {
@@ -231,7 +327,7 @@ void Channel::OnReadMessageForDownstream(
// Since we own |raw_channel_|, and this method and |Shutdown()| should only
// be called from the creation thread, |raw_channel_| should never be null
// here.
- DCHECK(raw_channel_.get());
+ DCHECK(is_running_no_lock());
IdToEndpointInfoMap::const_iterator it =
local_id_to_endpoint_info_map_.find(local_id);
@@ -249,6 +345,13 @@ void Channel::OnReadMessageForDownstream(
endpoint_info = it->second;
}
+ // Ignore messages for zombie endpoints (not an error).
+ if (endpoint_info.state != EndpointInfo::STATE_NORMAL) {
+ DVLOG(2) << "Ignoring downstream message for zombie endpoint (local ID = "
+ << local_id << ", remote ID = " << message_view.source_id() << ")";
+ return;
+ }
+
// We need to duplicate the message, because |EnqueueMessage()| will take
// ownership of it.
scoped_ptr<MessageInTransit> message(new MessageInTransit(message_view));
@@ -261,7 +364,7 @@ void Channel::OnReadMessageForDownstream(
// error, e.g., if the remote side is sending invalid control messages (to
// the message pipe).
HandleLocalError(base::StringPrintf(
- "Failed to enqueue message to local destination ID %u (result %d)",
+ "Failed to enqueue message to local ID %u (result %d)",
static_cast<unsigned>(local_id), static_cast<int>(result)));
return;
}
@@ -273,14 +376,35 @@ void Channel::OnReadMessageForChannel(
switch (message_view.subtype()) {
case MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint:
- // TODO(vtl): FIXME -- Error handling (also validation of
- // source/destination IDs).
- DVLOG(2) << "Handling channel message to run message pipe (local ID = "
- << message_view.destination_id() << ", remote ID = "
+ DVLOG(2) << "Handling channel message to run message pipe (local ID "
+ << message_view.destination_id() << ", remote ID "
<< message_view.source_id() << ")";
if (!RunMessagePipeEndpoint(message_view.destination_id(),
- message_view.source_id()))
- HandleRemoteError("Received invalid channel run message pipe message");
+ message_view.source_id())) {
+ HandleRemoteError(
+ "Received invalid channel message to run message pipe");
+ }
+ break;
+ case MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint:
+ DVLOG(2) << "Handling channel message to remove message pipe (local ID "
+ << message_view.destination_id() << ", remote ID "
+ << message_view.source_id() << ")";
+ if (!RemoveMessagePipeEndpoint(message_view.destination_id(),
+ message_view.source_id())) {
+ HandleRemoteError(
+ "Received invalid channel message to remove message pipe");
+ }
+ break;
+ case MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck:
+ DVLOG(2) << "Handling channel message to ack remove message pipe (local "
+ "ID "
+ << message_view.destination_id() << ", remote ID "
+ << message_view.source_id() << ")";
+ if (!RemoveMessagePipeEndpoint(message_view.destination_id(),
+ message_view.source_id())) {
+ HandleRemoteError(
+ "Received invalid channel message to ack remove message pipe");
+ }
break;
default:
HandleRemoteError("Received invalid channel message");
@@ -289,6 +413,62 @@ void Channel::OnReadMessageForChannel(
}
}
+bool Channel::RemoveMessagePipeEndpoint(
+ MessageInTransit::EndpointId local_id,
+ MessageInTransit::EndpointId remote_id) {
+ EndpointInfo endpoint_info;
+ {
+ base::AutoLock locker(lock_);
+
+ IdToEndpointInfoMap::iterator it =
+ local_id_to_endpoint_info_map_.find(local_id);
+ if (it == local_id_to_endpoint_info_map_.end()) {
+ DVLOG(2) << "Remove message pipe error: not found";
+ return false;
+ }
+
+ // If it's waiting for the remove ack, just do it and return.
+ if (it->second.state == EndpointInfo::STATE_WAIT_REMOTE_REMOVE_ACK) {
+ local_id_to_endpoint_info_map_.erase(it);
+ return true;
+ }
+
+ if (it->second.state != EndpointInfo::STATE_NORMAL) {
+ DVLOG(2) << "Remove message pipe error: wrong state";
+ return false;
+ }
+
+ it->second.state = EndpointInfo::STATE_WAIT_LOCAL_DETACH;
+ endpoint_info = it->second;
+ it->second.message_pipe = NULL;
+ }
+
+ if (!SendControlMessage(
+ MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck,
+ local_id, remote_id)) {
+ HandleLocalError(base::StringPrintf(
+ "Failed to send message to remove remote message pipe endpoint ack "
+ "(local ID %u, remote ID %u)",
+ static_cast<unsigned>(local_id), static_cast<unsigned>(remote_id)));
+ }
+
+ endpoint_info.message_pipe->OnRemove(endpoint_info.port);
+
+ return true;
+}
+
+bool Channel::SendControlMessage(MessageInTransit::Subtype subtype,
+ MessageInTransit::EndpointId local_id,
+ MessageInTransit::EndpointId remote_id) {
+ DVLOG(2) << "Sending channel control message: subtype " << subtype
+ << ", local ID " << local_id << ", remote ID " << remote_id;
+ scoped_ptr<MessageInTransit> message(new MessageInTransit(
+ MessageInTransit::kTypeChannel, subtype, 0, 0, NULL));
+ message->set_source_id(local_id);
+ message->set_destination_id(remote_id);
+ return WriteMessage(message.Pass());
+}
+
void Channel::HandleRemoteError(const base::StringPiece& error_message) {
// TODO(vtl): Is this how we really want to handle this? Probably we want to
// terminate the connection, since it's spewing invalid stuff.
@@ -297,6 +477,10 @@ void Channel::HandleRemoteError(const base::StringPiece& error_message) {
void Channel::HandleLocalError(const base::StringPiece& error_message) {
// TODO(vtl): Is this how we really want to handle this?
+ // Sometimes we'll want to propagate the error back to the message pipe
+ // (endpoint), and notify it that the remote is (effectively) closed.
+ // Sometimes we'll want to kill the channel (and notify all the endpoints that
+ // their remotes are dead.
LOG(WARNING) << error_message;
}
diff --git a/mojo/system/channel.h b/mojo/system/channel.h
index 1e66a8804e..7b30dbb4f3 100644
--- a/mojo/system/channel.h
+++ b/mojo/system/channel.h
@@ -72,11 +72,12 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
// which it returns. The first message pipe endpoint attached will always have
// |kBootstrapEndpointId| as its local ID. (For bootstrapping, this occurs on
// both sides, so one should use |kBootstrapEndpointId| for the remote ID for
- // the first message pipe across a channel.)
- // TODO(vtl): Maybe limit the number of attached message pipes and allow this
- // to fail.
+ // the first message pipe across a channel.) Returns |kInvalidEndpointId| on
+ // failure.
+ // TODO(vtl): Maybe limit the number of attached message pipes.
MessageInTransit::EndpointId AttachMessagePipeEndpoint(
- scoped_refptr<MessagePipe> message_pipe, unsigned port);
+ scoped_refptr<MessagePipe> message_pipe,
+ unsigned port);
// Runs the message pipe with the given |local_id| (previously attached), with
// the given |remote_id| (negotiated using some other means, e.g., over an
@@ -103,12 +104,37 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
// |FlushWriteBufferAndShutdown()| or something like that.
bool IsWriteBufferEmpty();
- // This removes the message pipe/port's endpoint (with the given local ID,
+ // This removes the message pipe/port's endpoint (with the given local ID and
+ // given remote ID, which should be |kInvalidEndpointId| if not yet running),
// returned by |AttachMessagePipeEndpoint()| from this channel. After this is
// called, |local_id| may be reused for another message pipe.
- void DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id);
+ void DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
+ MessageInTransit::EndpointId remote_id);
private:
+ struct EndpointInfo {
+ enum State {
+ // Attached, possibly running or not.
+ STATE_NORMAL,
+ // "Zombie" states:
+ // Waiting for |DetachMessagePipeEndpoint()| before removing.
+ STATE_WAIT_LOCAL_DETACH,
+ // Waiting for a |kSubtypeChannelRemoveMessagePipeEndpointAck| before
+ // removing.
+ STATE_WAIT_REMOTE_REMOVE_ACK,
+ // Waiting for both of the above conditions before removing.
+ STATE_WAIT_LOCAL_DETACH_AND_REMOTE_REMOVE_ACK,
+ };
+
+ EndpointInfo();
+ EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port);
+ ~EndpointInfo();
+
+ State state;
+ scoped_refptr<MessagePipe> message_pipe;
+ unsigned port;
+ };
+
friend class base::RefCountedThreadSafe<Channel>;
virtual ~Channel();
@@ -122,19 +148,24 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
void OnReadMessageForDownstream(const MessageInTransit::View& message_view);
void OnReadMessageForChannel(const MessageInTransit::View& message_view);
+ // Removes the message pipe endpoint with the given local ID, which must exist
+ // and be a zombie, and given remote ID. Returns false on failure, in
+ // particular if no message pipe with |local_id| is attached.
+ bool RemoveMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
+ MessageInTransit::EndpointId remote_id);
+
// Handles errors (e.g., invalid messages) from the remote side.
void HandleRemoteError(const base::StringPiece& error_message);
// Handles internal errors/failures from the local side.
void HandleLocalError(const base::StringPiece& error_message);
- struct EndpointInfo {
- EndpointInfo();
- EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port);
- ~EndpointInfo();
+ // Helper to send channel control messages. Returns true on success. Should be
+ // called *without* |lock_| held.
+ bool SendControlMessage(MessageInTransit::Subtype subtype,
+ MessageInTransit::EndpointId source_id,
+ MessageInTransit::EndpointId destination_id);
- scoped_refptr<MessagePipe> message_pipe;
- unsigned port;
- };
+ bool is_running_no_lock() const { return is_running_; }
base::ThreadChecker creation_thread_checker_;
@@ -146,6 +177,7 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
base::Lock lock_; // Protects the members below.
scoped_ptr<RawChannel> raw_channel_;
+ bool is_running_;
typedef base::hash_map<MessageInTransit::EndpointId, EndpointInfo>
IdToEndpointInfoMap;
diff --git a/mojo/system/local_message_pipe_endpoint.cc b/mojo/system/local_message_pipe_endpoint.cc
index ece8e03190..b5b6bd0223 100644
--- a/mojo/system/local_message_pipe_endpoint.cc
+++ b/mojo/system/local_message_pipe_endpoint.cc
@@ -27,13 +27,7 @@ MessagePipeEndpoint::Type LocalMessagePipeEndpoint::GetType() const {
return kTypeLocal;
}
-void LocalMessagePipeEndpoint::Close() {
- DCHECK(is_open_);
- is_open_ = false;
- message_queue_.Clear();
-}
-
-void LocalMessagePipeEndpoint::OnPeerClose() {
+bool LocalMessagePipeEndpoint::OnPeerClose() {
DCHECK(is_open_);
DCHECK(is_peer_open_);
@@ -48,6 +42,8 @@ void LocalMessagePipeEndpoint::OnPeerClose() {
waiter_list_.AwakeWaitersForStateChange(new_satisfied_flags,
new_satisfiable_flags);
}
+
+ return true;
}
void LocalMessagePipeEndpoint::EnqueueMessage(
@@ -63,6 +59,12 @@ void LocalMessagePipeEndpoint::EnqueueMessage(
}
}
+void LocalMessagePipeEndpoint::Close() {
+ DCHECK(is_open_);
+ is_open_ = false;
+ message_queue_.Clear();
+}
+
void LocalMessagePipeEndpoint::CancelAllWaiters() {
DCHECK(is_open_);
waiter_list_.CancelAllWaiters();
diff --git a/mojo/system/local_message_pipe_endpoint.h b/mojo/system/local_message_pipe_endpoint.h
index 9e200f16f7..963188f1df 100644
--- a/mojo/system/local_message_pipe_endpoint.h
+++ b/mojo/system/local_message_pipe_endpoint.h
@@ -24,12 +24,12 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalMessagePipeEndpoint
// |MessagePipeEndpoint| implementation:
virtual Type GetType() const OVERRIDE;
- virtual void Close() OVERRIDE;
- virtual void OnPeerClose() OVERRIDE;
+ virtual bool OnPeerClose() OVERRIDE;
virtual void EnqueueMessage(scoped_ptr<MessageInTransit> message) OVERRIDE;
// There's a dispatcher for |LocalMessagePipeEndpoint|s, so we have to
// implement/override these:
+ virtual void Close() OVERRIDE;
virtual void CancelAllWaiters() OVERRIDE;
virtual MojoResult ReadMessage(
void* bytes, uint32_t* num_bytes,
diff --git a/mojo/system/message_in_transit.cc b/mojo/system/message_in_transit.cc
index 73cefe38dd..442cd7142d 100644
--- a/mojo/system/message_in_transit.cc
+++ b/mojo/system/message_in_transit.cc
@@ -49,7 +49,11 @@ STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
MessageInTransit::kSubtypeMessagePipeEndpointData;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
- MessageInTransit::kSubtypeMessagePipePeerClosed;
+ MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint;
+STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
+ MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint;
+STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
+ MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck;
STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId
MessageInTransit::kInvalidEndpointId;
STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment;
diff --git a/mojo/system/message_in_transit.h b/mojo/system/message_in_transit.h
index bf8d5cf186..9e578afddf 100644
--- a/mojo/system/message_in_transit.h
+++ b/mojo/system/message_in_transit.h
@@ -54,9 +54,11 @@ class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit {
// Subtypes for type |kTypeMessagePipeEndpoint|:
static const Subtype kSubtypeMessagePipeEndpointData = 0;
// Subtypes for type |kTypeMessagePipe|:
- static const Subtype kSubtypeMessagePipePeerClosed = 0;
+ // Nothing currently.
// Subtypes for type |kTypeChannel|:
static const Subtype kSubtypeChannelRunMessagePipeEndpoint = 0;
+ static const Subtype kSubtypeChannelRemoveMessagePipeEndpoint = 1;
+ static const Subtype kSubtypeChannelRemoveMessagePipeEndpointAck = 2;
typedef uint32_t EndpointId;
// Never a valid endpoint ID.
diff --git a/mojo/system/message_pipe.cc b/mojo/system/message_pipe.cc
index 6f2e5cbb66..975293442a 100644
--- a/mojo/system/message_pipe.cc
+++ b/mojo/system/message_pipe.cc
@@ -57,8 +57,10 @@ void MessagePipe::Close(unsigned port) {
DCHECK(endpoints_[port].get());
endpoints_[port]->Close();
- if (endpoints_[destination_port].get())
- endpoints_[destination_port]->OnPeerClose();
+ if (endpoints_[destination_port].get()) {
+ if (!endpoints_[destination_port]->OnPeerClose())
+ endpoints_[destination_port].reset();
+ }
endpoints_[port].reset();
}
@@ -223,7 +225,7 @@ MojoResult MessagePipe::EnqueueMessage(
return MOJO_RESULT_OK;
}
-void MessagePipe::Attach(unsigned port,
+bool MessagePipe::Attach(unsigned port,
scoped_refptr<Channel> channel,
MessageInTransit::EndpointId local_id) {
DCHECK(port == 0 || port == 1);
@@ -231,9 +233,12 @@ void MessagePipe::Attach(unsigned port,
DCHECK_NE(local_id, MessageInTransit::kInvalidEndpointId);
base::AutoLock locker(lock_);
- DCHECK(endpoints_[port].get());
+ if (!endpoints_[port].get())
+ return false;
+ DCHECK_EQ(endpoints_[port]->GetType(), MessagePipeEndpoint::kTypeProxy);
endpoints_[port]->Attach(channel, local_id);
+ return true;
}
void MessagePipe::Run(unsigned port, MessageInTransit::EndpointId remote_id) {
@@ -242,7 +247,24 @@ void MessagePipe::Run(unsigned port, MessageInTransit::EndpointId remote_id) {
base::AutoLock locker(lock_);
DCHECK(endpoints_[port].get());
- endpoints_[port]->Run(remote_id);
+ if (!endpoints_[port]->Run(remote_id))
+ endpoints_[port].reset();
+}
+
+void MessagePipe::OnRemove(unsigned port) {
+ unsigned destination_port = GetPeerPort(port);
+
+ base::AutoLock locker(lock_);
+ // A |OnPeerClose()| can come in first, before |OnRemove()| gets called.
+ if (!endpoints_[port].get())
+ return;
+
+ endpoints_[port]->OnRemove();
+ if (endpoints_[destination_port].get()) {
+ if (!endpoints_[destination_port]->OnPeerClose())
+ endpoints_[destination_port].reset();
+ }
+ endpoints_[port].reset();
}
MessagePipe::~MessagePipe() {
@@ -254,28 +276,8 @@ MessagePipe::~MessagePipe() {
}
MojoResult MessagePipe::HandleControlMessage(
- unsigned port,
+ unsigned /*port*/,
scoped_ptr<MessageInTransit> message) {
- DCHECK(port == 0 || port == 1);
- DCHECK(message.get());
- DCHECK_EQ(message->type(), MessageInTransit::kTypeMessagePipe);
-
- switch (message->subtype()) {
- case MessageInTransit::kSubtypeMessagePipePeerClosed: {
- unsigned source_port = GetPeerPort(port);
-
- base::AutoLock locker(lock_);
- DCHECK(endpoints_[source_port].get());
-
- endpoints_[source_port]->Close();
- if (endpoints_[port].get())
- endpoints_[port]->OnPeerClose();
-
- endpoints_[source_port].reset();
- return MOJO_RESULT_OK;
- }
- }
-
LOG(WARNING) << "Unrecognized MessagePipe control message subtype "
<< message->subtype();
return MOJO_RESULT_UNKNOWN;
diff --git a/mojo/system/message_pipe.h b/mojo/system/message_pipe.h
index 85cce0ae3d..6392ab3530 100644
--- a/mojo/system/message_pipe.h
+++ b/mojo/system/message_pipe.h
@@ -81,10 +81,11 @@ class MOJO_SYSTEM_IMPL_EXPORT MessagePipe :
std::vector<DispatcherTransport>* transports);
// These are used by |Channel|.
- void Attach(unsigned port,
+ bool Attach(unsigned port,
scoped_refptr<Channel> channel,
MessageInTransit::EndpointId local_id);
void Run(unsigned port, MessageInTransit::EndpointId remote_id);
+ void OnRemove(unsigned port);
private:
friend class base::RefCountedThreadSafe<MessagePipe>;
diff --git a/mojo/system/message_pipe_dispatcher.cc b/mojo/system/message_pipe_dispatcher.cc
index 364259bd72..fc626efb71 100644
--- a/mojo/system/message_pipe_dispatcher.cc
+++ b/mojo/system/message_pipe_dispatcher.cc
@@ -73,8 +73,21 @@ scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize(
MessageInTransit::EndpointId remote_id =
static_cast<const SerializedMessagePipeDispatcher*>(source)->endpoint_id;
+ if (remote_id == MessageInTransit::kInvalidEndpointId) {
+ // This means that the other end was closed, and there were no messages
+ // enqueued for us.
+ // TODO(vtl): This is wrong. We should produce a "dead" message pipe
+ // dispatcher.
+ NOTIMPLEMENTED();
+ return scoped_refptr<MessagePipeDispatcher>();
+ }
MessageInTransit::EndpointId local_id =
channel->AttachMessagePipeEndpoint(remote_message_pipe.second, 1);
+ if (local_id == MessageInTransit::kInvalidEndpointId) {
+ LOG(ERROR) << "Failed to deserialize message pipe dispatcher (failed to "
+ "attach; remote ID = " << remote_id << ")";
+ return scoped_refptr<MessagePipeDispatcher>();
+ }
DVLOG(2) << "Deserializing message pipe dispatcher (remote ID = "
<< remote_id << ", new local ID = " << local_id << ")";
@@ -199,8 +212,11 @@ bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock(
// Attach the new proxy endpoint to the channel.
MessageInTransit::EndpointId endpoint_id =
channel->AttachMessagePipeEndpoint(message_pipe_, port_);
- DCHECK_NE(endpoint_id, MessageInTransit::kInvalidEndpointId);
-
+ // Note: It's okay to get an endpoint ID of |kInvalidEndpointId|. (It's
+ // possible that the other endpoint -- the one that we're not sending -- was
+ // closed in the intervening time.) In that case, we need to deserialize a
+ // "dead" message pipe dispatcher on the other end. (Note that this is
+ // different from just producing |MOJO_HANDLE_INVALID|.)
DVLOG(2) << "Serializing message pipe dispatcher (local ID = " << endpoint_id
<< ")";
diff --git a/mojo/system/message_pipe_endpoint.cc b/mojo/system/message_pipe_endpoint.cc
index dd186fd89c..a1a7be3a41 100644
--- a/mojo/system/message_pipe_endpoint.cc
+++ b/mojo/system/message_pipe_endpoint.cc
@@ -10,6 +10,10 @@
namespace mojo {
namespace system {
+void MessagePipeEndpoint::Close() {
+ NOTREACHED();
+}
+
void MessagePipeEndpoint::CancelAllWaiters() {
NOTREACHED();
}
@@ -39,7 +43,12 @@ void MessagePipeEndpoint::Attach(scoped_refptr<Channel> /*channel*/,
NOTREACHED();
}
-void MessagePipeEndpoint::Run(MessageInTransit::EndpointId /*remote_id*/) {
+bool MessagePipeEndpoint::Run(MessageInTransit::EndpointId /*remote_id*/) {
+ NOTREACHED();
+ return true;
+}
+
+void MessagePipeEndpoint::OnRemove() {
NOTREACHED();
}
diff --git a/mojo/system/message_pipe_endpoint.h b/mojo/system/message_pipe_endpoint.h
index b7b9589450..d14c58a627 100644
--- a/mojo/system/message_pipe_endpoint.h
+++ b/mojo/system/message_pipe_endpoint.h
@@ -42,8 +42,8 @@ class MOJO_SYSTEM_IMPL_EXPORT MessagePipeEndpoint {
virtual Type GetType() const = 0;
// All implementations must implement these.
- virtual void Close() = 0;
- virtual void OnPeerClose() = 0;
+ // Returns false if the endpoint should be closed and destroyed, else true.
+ virtual bool OnPeerClose() = 0;
// Implements |MessagePipe::EnqueueMessage()|. The major differences are that:
// a) Dispatchers have been vetted and cloned/attached to the message.
// b) At this point, we cannot report failure (if, e.g., a channel is torn
@@ -58,6 +58,7 @@ class MOJO_SYSTEM_IMPL_EXPORT MessagePipeEndpoint {
// These methods implement the methods of the same name in |MessagePipe|,
// though |MessagePipe|'s implementation may have to do a little more if the
// operation involves both endpoints.
+ virtual void Close();
virtual void CancelAllWaiters();
virtual MojoResult ReadMessage(
void* bytes, uint32_t* num_bytes,
@@ -74,7 +75,9 @@ class MOJO_SYSTEM_IMPL_EXPORT MessagePipeEndpoint {
// they should never be called.
virtual void Attach(scoped_refptr<Channel> channel,
MessageInTransit::EndpointId local_id);
- virtual void Run(MessageInTransit::EndpointId remote_id);
+ // Returns false if the endpoint should be closed and destroyed, else true.
+ virtual bool Run(MessageInTransit::EndpointId remote_id);
+ virtual void OnRemove();
protected:
MessagePipeEndpoint() {}
diff --git a/mojo/system/proxy_message_pipe_endpoint.cc b/mojo/system/proxy_message_pipe_endpoint.cc
index d5ef6566b2..81adda5450 100644
--- a/mojo/system/proxy_message_pipe_endpoint.cc
+++ b/mojo/system/proxy_message_pipe_endpoint.cc
@@ -17,7 +17,6 @@ namespace system {
ProxyMessagePipeEndpoint::ProxyMessagePipeEndpoint()
: local_id_(MessageInTransit::kInvalidEndpointId),
remote_id_(MessageInTransit::kInvalidEndpointId),
- is_open_(true),
is_peer_open_(true) {
}
@@ -26,7 +25,6 @@ ProxyMessagePipeEndpoint::ProxyMessagePipeEndpoint(
bool is_peer_open)
: local_id_(MessageInTransit::kInvalidEndpointId),
remote_id_(MessageInTransit::kInvalidEndpointId),
- is_open_(true),
is_peer_open_(is_peer_open),
paused_message_queue_(MessageInTransitQueue::PassContents(),
local_message_pipe_endpoint->message_queue()) {
@@ -44,27 +42,26 @@ MessagePipeEndpoint::Type ProxyMessagePipeEndpoint::GetType() const {
return kTypeProxy;
}
-void ProxyMessagePipeEndpoint::Close() {
- DCHECK(is_open_);
- is_open_ = false;
-
- DCHECK(is_attached());
- channel_->DetachMessagePipeEndpoint(local_id_);
- channel_ = NULL;
- local_id_ = MessageInTransit::kInvalidEndpointId;
- remote_id_ = MessageInTransit::kInvalidEndpointId;
- paused_message_queue_.Clear();
-}
-
-void ProxyMessagePipeEndpoint::OnPeerClose() {
- DCHECK(is_open_);
+bool ProxyMessagePipeEndpoint::OnPeerClose() {
DCHECK(is_peer_open_);
is_peer_open_ = false;
- EnqueueMessage(make_scoped_ptr(
- new MessageInTransit(MessageInTransit::kTypeMessagePipe,
- MessageInTransit::kSubtypeMessagePipePeerClosed,
- 0, 0, NULL)));
+
+ // If our outgoing message queue isn't empty, we shouldn't be destroyed yet.
+ if (!paused_message_queue_.IsEmpty())
+ return true;
+
+ if (is_attached()) {
+ if (!is_running()) {
+ // If we're not running yet, we can't be destroyed yet, because we're
+ // still waiting for the "run" message from the other side.
+ return true;
+ }
+
+ Detach();
+ }
+
+ return false;
}
// Note: We may have to enqueue messages even when our (local) peer isn't open
@@ -72,8 +69,6 @@ void ProxyMessagePipeEndpoint::OnPeerClose() {
// This case is handled in |Run()| (which will call us).
void ProxyMessagePipeEndpoint::EnqueueMessage(
scoped_ptr<MessageInTransit> message) {
- DCHECK(is_open_);
-
if (is_running()) {
message->SerializeAndCloseDispatchers(channel_.get());
@@ -99,7 +94,7 @@ void ProxyMessagePipeEndpoint::Attach(scoped_refptr<Channel> channel,
AssertConsistentState();
}
-void ProxyMessagePipeEndpoint::Run(MessageInTransit::EndpointId remote_id) {
+bool ProxyMessagePipeEndpoint::Run(MessageInTransit::EndpointId remote_id) {
// Assertions about arguments:
DCHECK_NE(remote_id, MessageInTransit::kInvalidEndpointId);
@@ -113,6 +108,29 @@ void ProxyMessagePipeEndpoint::Run(MessageInTransit::EndpointId remote_id) {
while (!paused_message_queue_.IsEmpty())
EnqueueMessage(paused_message_queue_.GetMessage());
+
+ if (is_peer_open_)
+ return true; // Stay alive.
+
+ // We were just waiting to die.
+ Detach();
+ return false;
+}
+
+void ProxyMessagePipeEndpoint::OnRemove() {
+ Detach();
+}
+
+void ProxyMessagePipeEndpoint::Detach() {
+ DCHECK(is_attached());
+
+ AssertConsistentState();
+ channel_->DetachMessagePipeEndpoint(local_id_, remote_id_);
+ channel_ = NULL;
+ local_id_ = MessageInTransit::kInvalidEndpointId;
+ remote_id_ = MessageInTransit::kInvalidEndpointId;
+ paused_message_queue_.Clear();
+ AssertConsistentState();
}
#ifndef NDEBUG
diff --git a/mojo/system/proxy_message_pipe_endpoint.h b/mojo/system/proxy_message_pipe_endpoint.h
index 7d62b9b79e..28b634d906 100644
--- a/mojo/system/proxy_message_pipe_endpoint.h
+++ b/mojo/system/proxy_message_pipe_endpoint.h
@@ -53,14 +53,22 @@ class MOJO_SYSTEM_IMPL_EXPORT ProxyMessagePipeEndpoint
// |MessagePipeEndpoint| implementation:
virtual Type GetType() const OVERRIDE;
- virtual void Close() OVERRIDE;
- virtual void OnPeerClose() OVERRIDE;
+ virtual bool OnPeerClose() OVERRIDE;
virtual void EnqueueMessage(scoped_ptr<MessageInTransit> message) OVERRIDE;
virtual void Attach(scoped_refptr<Channel> channel,
MessageInTransit::EndpointId local_id) OVERRIDE;
- virtual void Run(MessageInTransit::EndpointId remote_id) OVERRIDE;
+ virtual bool Run(MessageInTransit::EndpointId remote_id) OVERRIDE;
+ virtual void OnRemove() OVERRIDE;
private:
+ void Detach();
+
+#ifdef NDEBUG
+ void AssertConsistentState() const {}
+#else
+ void AssertConsistentState() const;
+#endif
+
bool is_attached() const {
return !!channel_.get();
}
@@ -69,12 +77,6 @@ class MOJO_SYSTEM_IMPL_EXPORT ProxyMessagePipeEndpoint
return remote_id_ != MessageInTransit::kInvalidEndpointId;
}
-#ifdef NDEBUG
- void AssertConsistentState() const {}
-#else
- void AssertConsistentState() const;
-#endif
-
// This should only be set if we're attached.
scoped_refptr<Channel> channel_;
@@ -88,7 +90,6 @@ class MOJO_SYSTEM_IMPL_EXPORT ProxyMessagePipeEndpoint
// we're attached.
MessageInTransit::EndpointId remote_id_;
- bool is_open_;
bool is_peer_open_;
// This queue is only used while we're detached, to store messages while we're
diff --git a/mojo/system/raw_channel.h b/mojo/system/raw_channel.h
index f1ce443e9d..4b60e36d5c 100644
--- a/mojo/system/raw_channel.h
+++ b/mojo/system/raw_channel.h
@@ -53,17 +53,18 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
FATAL_ERROR_FAILED_WRITE
};
- // Called when a message is read. This may call |Shutdown()| on the
- // |RawChannel|, but must not destroy it.
+ // Called when a message is read. This may call |Shutdown()| (on the
+ // |RawChannel|), but must not destroy it.
virtual void OnReadMessage(const MessageInTransit::View& message_view) = 0;
// Called when there's a fatal error, which leads to the channel no longer
- // being viable.
- // For each raw channel, at most one |FATAL_ERROR_FAILED_READ| and one
- // |FATAL_ERROR_FAILED_WRITE| notification will be issued. (And it is
- // possible to get both.)
- // After |OnFatalError(FATAL_ERROR_FAILED_READ)| there won't be further
- // |OnReadMessage()| calls.
+ // being viable. This may call |Shutdown()| (on the |RawChannel()|), but
+ // must now destroy it.
+ //
+ // For each raw channel, at most one |FATAL_ERROR_FAILED_READ| and at most
+ // one |FATAL_ERROR_FAILED_WRITE| notification will be issued (both may be
+ // issued). After a |OnFatalError(FATAL_ERROR_FAILED_READ)|, there will be
+ // no further calls to |OnReadMessage()|.
virtual void OnFatalError(FatalError fatal_error) = 0;
protected:
diff --git a/mojo/system/remote_message_pipe_unittest.cc b/mojo/system/remote_message_pipe_unittest.cc
index 4dee5772ab..7deb252ef4 100644
--- a/mojo/system/remote_message_pipe_unittest.cc
+++ b/mojo/system/remote_message_pipe_unittest.cc
@@ -138,10 +138,13 @@ class RemoteMessagePipeTest : public testing::Test {
unsigned port = channel_index ^ 1u;
- // Important: If we don't boot
CreateAndInitChannel(channel_index);
- CHECK_EQ(channels_[channel_index]->AttachMessagePipeEndpoint(mp, port),
- Channel::kBootstrapEndpointId);
+ MessageInTransit::EndpointId endpoint_id =
+ channels_[channel_index]->AttachMessagePipeEndpoint(mp, port);
+ if (endpoint_id == MessageInTransit::kInvalidEndpointId)
+ return;
+
+ CHECK_EQ(endpoint_id, Channel::kBootstrapEndpointId);
CHECK(channels_[channel_index]->RunMessagePipeEndpoint(
Channel::kBootstrapEndpointId, Channel::kBootstrapEndpointId));
}
@@ -561,7 +564,8 @@ TEST_F(RemoteMessagePipeTest, HandlePassing) {
TEST_F(RemoteMessagePipeTest, RacingClosesStress) {
base::TimeDelta delay = base::TimeDelta::FromMilliseconds(5);
- for (unsigned i = 0u; i < 256u; i++) {
+ for (unsigned i = 0; i < 256; i++) {
+ DVLOG(2) << "---------------------------------------- " << i;
scoped_refptr<MessagePipe> mp0(new MessagePipe(
scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()),
scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint())));
diff --git a/mojo/tools/data/unittests b/mojo/tools/data/unittests
index 4ec0b295a5..e209379c7a 100644
--- a/mojo/tools/data/unittests
+++ b/mojo/tools/data/unittests
@@ -14,3 +14,4 @@ mojo_apps_js_unittests
mojo_common_unittests
mojo_js_unittests
mojo_service_manager_unittests
+mojo_view_manager_unittests
diff --git a/mojo/tools/mojob.sh b/mojo/tools/mojob.sh
index 291012ca23..b870cd1301 100755
--- a/mojo/tools/mojob.sh
+++ b/mojo/tools/mojob.sh
@@ -61,9 +61,7 @@ do_perftests() {
}
do_pytests() {
- echo "Running Python unit tests under mojo/public/tools/bindings/pylib ..."
- python -m unittest \
- discover -s mojo/public/tools/bindings/pylib -p "*_unittest.py"
+ python mojo/tools/run_mojo_python_tests.py || exit 1
}
do_gyp() {
diff --git a/mojo/tools/run_mojo_python_tests.py b/mojo/tools/run_mojo_python_tests.py
new file mode 100755
index 0000000000..48b723cfd3
--- /dev/null
+++ b/mojo/tools/run_mojo_python_tests.py
@@ -0,0 +1,40 @@
+#!/bin/python
+# 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 optparse
+import os
+import sys
+import unittest
+
+
+# TODO(dpranke): crbug.com/364709 . We should add the ability to return
+# JSONified results data for the bots.
+
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('-v', '--verbose', action='count', default=0)
+ options, args = parser.parse_args()
+ if args:
+ parser.usage()
+ return 1
+
+ chromium_src_dir = os.path.join(os.path.dirname(__file__),
+ os.pardir,
+ os.pardir)
+
+ loader = unittest.loader.TestLoader()
+ print "Running Python unit tests under mojo/public/tools/bindings/pylib ..."
+ suite = loader.discover(os.path.join(chromium_src_dir, 'mojo', 'public',
+ 'tools', 'bindings', 'pylib'),
+ pattern='*_unittest.py')
+
+ runner = unittest.runner.TextTestRunner(verbosity=(options.verbose+1))
+ result = runner.run(suite)
+ return 0 if result.wasSuccessful() else 1
+
+
+if __name__ == '__main__':
+ sys.exit(main())