From 669bbc0a54393464248e6bac22558cda42a9a350 Mon Sep 17 00:00:00 2001 From: Eurogiciel-BOT Date: Mon, 17 Nov 2014 15:26:02 +0000 Subject: [PATCH] Upstream version 11.39.244.0 Upstream commit-id 9605f4c84aec82d20882bdd0878d7f1a2f06e3b4 Change-Id: I745f3b6e852604e53b56a8f99c0a60e8153c6caa Signed-off-by: Eurogiciel-BOT --- packaging/crosswalk.spec | 4 +- src/build/util/LASTCHANGE | 2 +- src/build/util/LASTCHANGE.blink | 2 +- .../renderer_host/media/audio_renderer_host.cc | 14 + .../renderer_host/media/audio_renderer_host.h | 18 + src/media/audio/audio_io.h | 11 + src/media/audio/audio_output_controller.cc | 4 + src/media/audio/audio_output_controller.h | 9 + src/media/audio/audio_output_dispatcher.cc | 9 + src/media/audio/audio_output_dispatcher.h | 14 + src/media/audio/audio_output_dispatcher_impl.cc | 4 + src/media/audio/audio_output_proxy.cc | 7 + src/media/audio/audio_output_proxy.h | 9 + src/media/audio/audio_output_resampler.cc | 8 + src/media/audio/pulse/pulse.sigs | 5 + src/media/audio/pulse/pulse_output.cc | 9 + src/media/audio/pulse/pulse_output.h | 13 + src/media/audio/pulse/pulse_util.cc | 17 + .../desktop_window_tree_host_wayland.cc | 2 + .../Source/bindings/core/v8/ScriptProfiler.cpp | 54 ++ .../Source/bindings/core/v8/ScriptProfiler.h | 8 + .../core/inspector/InspectorHeapProfilerAgent.cpp | 127 +++++ .../core/inspector/InspectorHeapProfilerAgent.h | 16 +- .../WebKit/Source/core/inspector/ScriptProfile.cpp | 53 ++ .../WebKit/Source/core/inspector/ScriptProfile.h | 24 + .../WebKit/Source/devtools/protocol.json | 53 +- src/v8/include/v8-profiler.h | 34 ++ src/v8/src/api.cc | 61 ++- src/v8/src/cpu-profiler.cc | 74 ++- src/v8/src/cpu-profiler.h | 4 +- src/v8/src/heap-profiler.cc | 56 ++- src/v8/src/heap-profiler.h | 10 +- src/v8/src/heap-snapshot-generator-inl.h | 2 +- src/v8/src/heap-snapshot-generator.cc | 106 ++-- src/v8/src/heap-snapshot-generator.h | 40 +- src/v8/src/profile-generator-inl.h | 6 +- src/v8/src/profile-generator.cc | 57 ++- src/v8/src/profile-generator.h | 30 +- src/v8/src/xdk-allocation.cc | 539 ++++++++++++++++++++ src/v8/src/xdk-allocation.h | 168 +++++++ src/v8/src/xdk-utils.cc | 541 +++++++++++++++++++++ src/v8/src/xdk-utils.h | 249 ++++++++++ src/v8/test/cctest/test-cpu-profiler.cc | 19 +- src/v8/test/cctest/test-heap-profiler.cc | 373 ++++++++++++++ src/v8/tools/gyp/v8.gyp | 4 + src/xwalk/DEPS.xwalk | 44 +- src/xwalk/VERSION | 4 +- .../org/xwalk/app/XWalkRuntimeActivityBase.java | 26 - .../XWalkRuntimeClientEmbeddedShellActivity.java | 20 + .../shell/XWalkRuntimeClientShellActivity.java | 25 + src/xwalk/app/tools/android/customize.py | 20 + src/xwalk/app/tools/android/handle_xml.py | 33 ++ src/xwalk/app/tools/android/make_apk_test.py | 21 + .../extensions/adextension/AndroidManifest.xml | 5 + .../extensions/adextension/adextension.js | 5 + .../extensions/adextension/adextension.json | 6 + .../src/com/example/extension/AdExtension.java | 11 + src/xwalk/application/browser/application.cc | 13 +- src/xwalk/application/browser/application.h | 13 +- src/xwalk/application/browser/application_tizen.cc | 77 +++ src/xwalk/application/browser/application_tizen.h | 7 + .../application/common/application_file_util.cc | 3 +- .../common/application_manifest_constants.cc | 2 + .../common/application_manifest_constants.h | 2 + src/xwalk/application/common/constants.cc | 2 + src/xwalk/application/common/constants.h | 4 + .../manifest_handlers/tizen_application_handler.cc | 12 +- .../manifest_handlers/tizen_setting_handler.cc | 13 + .../manifest_handlers/tizen_setting_handler.h | 6 + src/xwalk/application/tools/tizen/xwalk_backend.cc | 24 +- .../tools/tizen/xwalk_backend_plugin.cc | 40 +- .../application/tools/tizen/xwalk_backend_plugin.h | 2 +- .../application/tools/tizen/xwalk_backendlib.cc | 2 +- .../tools/tizen/xwalk_package_installer.cc | 38 +- .../tools/tizen/xwalk_package_installer.h | 7 +- .../tools/tizen/xwalk_packageinfo_constants.h | 2 +- .../tools/tizen/xwalk_platform_installer.cc | 65 ++- .../tools/tizen/xwalk_platform_installer.h | 3 +- .../tools/tizen/xwalk_rds_delta_parser.cc | 134 +++++ .../tools/tizen/xwalk_rds_delta_parser.h | 29 ++ .../application/tools/tizen/xwalk_tizen_tools.gyp | 2 + .../application/tools/tizen/xwalk_tizen_user.cc | 61 +-- .../browser/xwalk_extension_process_host.cc | 2 + .../browser/xwalk_extension_process_host.h | 2 + .../extensions/browser/xwalk_extension_service.cc | 5 + .../extensions/browser/xwalk_extension_service.h | 2 + .../common/android/xwalk_extension_android.cc | 2 +- .../test/external_extension_multi_process.cc | 17 +- src/xwalk/packaging/crosswalk.spec | 4 +- .../src/org/xwalk/core/internal/XWalkContent.java | 61 ++- .../core/internal/XWalkContentsClientBridge.java | 5 +- .../xwalk/core/internal/XWalkDevToolsServer.java | 14 +- .../core/internal/XWalkResourceClientInternal.java | 4 +- .../org/xwalk/core/internal/XWalkViewInternal.java | 154 +++++- .../api/messaging/MessagingSmsManager.java | 11 + .../extension/api/messaging/messaging_api.js | 18 +- .../runtime/android/sample/AndroidManifest.xml | 18 + .../android/sample/assets/create_window_1.html | 13 + .../android/sample/assets/create_window_2.html | 10 + .../runtime/android/sample/assets/favicon.html | 11 + src/xwalk/runtime/android/sample/assets/icon.png | Bin 0 -> 2662 bytes .../runtime/android/sample/assets/new_window.html | 10 + .../sample/OnCreateWindowRequestedActivity.java | 74 +++ .../xwalk/core/sample/OnReceivedIconActivity.java | 46 ++ .../renderer_host/xwalk_render_view_host_ext.cc | 5 + .../renderer_host/xwalk_render_view_host_ext.h | 1 + src/xwalk/runtime/browser/android/xwalk_content.cc | 8 +- src/xwalk/runtime/browser/android/xwalk_content.h | 1 + .../android/xwalk_contents_client_bridge.cc | 2 +- .../browser/android/xwalk_dev_tools_server.cc | 159 ++---- .../browser/android/xwalk_dev_tools_server.h | 5 +- .../browser/android/xwalk_http_auth_handler.cc | 2 +- .../runtime/browser/android/xwalk_path_helper.cc | 2 +- .../runtime/browser/android/xwalk_settings.cc | 2 +- .../runtime/browser/android/xwalk_view_delegate.cc | 2 +- .../runtime/browser/blink_upstream_version.h.in | 7 + .../browser/devtools/xwalk_devtools_browsertest.cc | 16 +- .../browser/devtools/xwalk_devtools_delegate.cc | 102 +++- .../browser/devtools/xwalk_devtools_delegate.h | 8 + src/xwalk/runtime/browser/runtime.cc | 157 ++---- src/xwalk/runtime/browser/runtime.h | 51 +- src/xwalk/runtime/browser/runtime_context.cc | 6 + .../runtime/browser/runtime_defered_ui_strategy.cc | 31 ++ .../runtime/browser/runtime_defered_ui_strategy.h | 37 ++ .../browser/runtime_platform_util_android.cc | 4 + .../runtime/browser/runtime_platform_util_tizen.cc | 89 ++++ .../runtime_resource_dispatcher_host_delegate.cc | 28 +- .../runtime_resource_dispatcher_host_delegate.h | 1 + ...me_resource_dispatcher_host_delegate_android.cc | 25 +- ...ime_resource_dispatcher_host_delegate_android.h | 5 - src/xwalk/runtime/browser/runtime_ui_strategy.cc | 75 +++ src/xwalk/runtime/browser/runtime_ui_strategy.h | 23 + .../browser/tizen/render_view_context_menu_impl.cc | 258 ++++++++++ .../browser/tizen/render_view_context_menu_impl.h | 54 ++ .../tizen/xwalk_web_contents_view_delegate.cc | 169 +++++++ .../tizen/xwalk_web_contents_view_delegate.h | 66 +++ .../runtime/browser/ui/native_app_window_views.cc | 4 + .../runtime/browser/ui/native_app_window_views.h | 1 + .../runtime/browser/xwalk_app_extension_bridge.cc | 19 + .../runtime/browser/xwalk_app_extension_bridge.h | 1 + .../browser/xwalk_content_browser_client.cc | 14 +- .../runtime/browser/xwalk_content_browser_client.h | 14 +- .../runtime/browser/xwalk_runtime_browsertest.cc | 24 +- .../common/android/xwalk_render_view_messages.h | 5 + .../renderer/android/xwalk_render_view_ext.cc | 7 + .../renderer/android/xwalk_render_view_ext.h | 5 +- .../runtime/resources/devtools_discovery_page.html | 3 + src/xwalk/sysapps/raw_socket/udp_socket_object.cc | 1 + .../xwview/test/OnCreateWindowRequestedTest.java | 53 ++ .../xwalk/core/xwview/test/OnReceivedIconTest.java | 53 ++ .../xwalk/core/xwview/test/TestHelperBridge.java | 41 ++ src/xwalk/test/android/data/create_window_1.html | 13 + src/xwalk/test/android/data/create_window_2.html | 10 + src/xwalk/test/android/data/favicon.html | 11 + src/xwalk/test/android/data/icon.png | Bin 0 -> 2662 bytes src/xwalk/test/android/data/new_window.html | 10 + src/xwalk/test/base/in_process_browser_test.cc | 15 +- .../browser/media/browser_mediaplayer_manager.cc | 11 +- src/xwalk/tizen/browser/media/murphy_resource.cc | 15 +- src/xwalk/tizen/browser/media/murphy_resource.h | 4 + src/xwalk/tools/upstream_revision.py | 50 ++ src/xwalk/xwalk.gyp | 54 +- src/xwalk/xwalk_android_app.gypi | 12 + src/xwalk/xwalk_android_tests.gypi | 20 + 164 files changed, 5297 insertions(+), 709 deletions(-) create mode 100644 src/v8/src/xdk-allocation.cc create mode 100644 src/v8/src/xdk-allocation.h create mode 100644 src/v8/src/xdk-utils.cc create mode 100644 src/v8/src/xdk-utils.h create mode 100644 src/xwalk/app/tools/android/test_data/extensions/adextension/AndroidManifest.xml create mode 100644 src/xwalk/app/tools/android/test_data/extensions/adextension/adextension.js create mode 100644 src/xwalk/app/tools/android/test_data/extensions/adextension/adextension.json create mode 100644 src/xwalk/app/tools/android/test_data/extensions/adextension/src/com/example/extension/AdExtension.java create mode 100644 src/xwalk/application/tools/tizen/xwalk_rds_delta_parser.cc create mode 100644 src/xwalk/application/tools/tizen/xwalk_rds_delta_parser.h create mode 100644 src/xwalk/runtime/android/sample/assets/create_window_1.html create mode 100644 src/xwalk/runtime/android/sample/assets/create_window_2.html create mode 100644 src/xwalk/runtime/android/sample/assets/favicon.html create mode 100644 src/xwalk/runtime/android/sample/assets/icon.png create mode 100644 src/xwalk/runtime/android/sample/assets/new_window.html create mode 100644 src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnCreateWindowRequestedActivity.java create mode 100644 src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnReceivedIconActivity.java create mode 100644 src/xwalk/runtime/browser/blink_upstream_version.h.in create mode 100644 src/xwalk/runtime/browser/runtime_defered_ui_strategy.cc create mode 100644 src/xwalk/runtime/browser/runtime_defered_ui_strategy.h create mode 100644 src/xwalk/runtime/browser/runtime_ui_strategy.cc create mode 100644 src/xwalk/runtime/browser/runtime_ui_strategy.h create mode 100644 src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.cc create mode 100644 src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.h create mode 100644 src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.cc create mode 100644 src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h create mode 100644 src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnCreateWindowRequestedTest.java create mode 100644 src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnReceivedIconTest.java create mode 100644 src/xwalk/test/android/data/create_window_1.html create mode 100644 src/xwalk/test/android/data/create_window_2.html create mode 100644 src/xwalk/test/android/data/favicon.html create mode 100644 src/xwalk/test/android/data/icon.png create mode 100644 src/xwalk/test/android/data/new_window.html create mode 100755 src/xwalk/tools/upstream_revision.py diff --git a/packaging/crosswalk.spec b/packaging/crosswalk.spec index 7420b6f..f3c1764 100644 --- a/packaging/crosswalk.spec +++ b/packaging/crosswalk.spec @@ -24,7 +24,7 @@ %define _binary_payload w3.gzdio Name: crosswalk -Version: 10.39.234.0 +Version: 11.39.244.0 Release: 0 Summary: Chromium-based app runtime License: (BSD-3-Clause and LGPL-2.1+) @@ -53,6 +53,7 @@ BuildRequires: python BuildRequires: python-xml BuildRequires: perl BuildRequires: which +BuildRequires: yasm BuildRequires: pkgconfig(ail) BuildRequires: pkgconfig(alsa) BuildRequires: pkgconfig(appcore-common) @@ -242,6 +243,7 @@ ${GYP_EXTRA_FLAGS} \ -Duse_system_libexif=1 \ -Duse_system_libxml=1 \ -Duse_system_nspr=1 \ +-Duse_system_yasm=1 \ -Dshared_process_mode=1 \ -Denable_hidpi=1 diff --git a/src/build/util/LASTCHANGE b/src/build/util/LASTCHANGE index cd3eecd..4e673a8 100644 --- a/src/build/util/LASTCHANGE +++ b/src/build/util/LASTCHANGE @@ -1 +1 @@ -LASTCHANGE=88fc58a654d73e2df3dffc946077486c450f3bdb +LASTCHANGE=52d4347d95a66afe54be98677b077fce0b7fd846 diff --git a/src/build/util/LASTCHANGE.blink b/src/build/util/LASTCHANGE.blink index 6201a3c..fe50828 100644 --- a/src/build/util/LASTCHANGE.blink +++ b/src/build/util/LASTCHANGE.blink @@ -1 +1 @@ -LASTCHANGE=ed2bae8ced284782cbd55f1597e02d6ee621621b +LASTCHANGE=a6caf4f53deee46eb41c31d38dc990964615b8e5 diff --git a/src/content/browser/renderer_host/media/audio_renderer_host.cc b/src/content/browser/renderer_host/media/audio_renderer_host.cc index 8c06395..86cf8f7 100644 --- a/src/content/browser/renderer_host/media/audio_renderer_host.cc +++ b/src/content/browser/renderer_host/media/audio_renderer_host.cc @@ -65,6 +65,11 @@ class AudioRendererHost::AudioEntry bool playing() const { return playing_; } void set_playing(bool playing) { playing_ = playing; } +#if defined(OS_TIZEN) + std::string app_id() const override { return host_->app_id_; } + std::string app_class() const override { return host_->app_class_; } +#endif + private: // media::AudioOutputController::EventHandler implementation. virtual void OnCreated() OVERRIDE; @@ -484,4 +489,13 @@ bool AudioRendererHost::HasActiveAudio() { return !base::AtomicRefCountIsZero(&num_playing_streams_); } +#if defined(OS_TIZEN) +void AudioRendererHost::SetMediaStreamProperties( + const std::string& app_id, + const std::string& app_class) { + app_id_ = app_id; + app_class_ = app_class; +} +#endif + } // namespace content diff --git a/src/content/browser/renderer_host/media/audio_renderer_host.h b/src/content/browser/renderer_host/media/audio_renderer_host.h index 38317ef..cc85a6f 100644 --- a/src/content/browser/renderer_host/media/audio_renderer_host.h +++ b/src/content/browser/renderer_host/media/audio_renderer_host.h @@ -38,6 +38,9 @@ #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_RENDERER_HOST_H_ #include +#if defined(OS_TIZEN) +#include +#endif #include "base/atomic_ref_count.h" #include "base/gtest_prod_util.h" @@ -89,6 +92,15 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter { // be called from any thread. bool HasActiveAudio(); +#if defined(OS_TIZEN) + // Sets an application ID and class properties, which are used to tag audio + // streams in pulseaudio/Murphy. + virtual void SetMediaStreamProperties(const std::string& app_id, + const std::string& app_class); + const std::string& app_id() const { return app_id_; } + const std::string& app_class() const { return app_class_; } +#endif + private: friend class AudioRendererHostTest; friend class BrowserThread; @@ -173,6 +185,12 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter { // The number of streams in the playing state. base::AtomicRefCount num_playing_streams_; +#if defined(OS_TIZEN) + // Application ID and class for the Murphy resource set. + std::string app_id_; + std::string app_class_; +#endif + DISALLOW_COPY_AND_ASSIGN(AudioRendererHost); }; diff --git a/src/media/audio/audio_io.h b/src/media/audio/audio_io.h index 1e1eba4..e4bb90e 100644 --- a/src/media/audio/audio_io.h +++ b/src/media/audio/audio_io.h @@ -5,6 +5,10 @@ #ifndef MEDIA_AUDIO_AUDIO_IO_H_ #define MEDIA_AUDIO_AUDIO_IO_H_ +#if defined(OS_TIZEN) +#include +#endif + #include "base/basictypes.h" #include "media/audio/audio_buffers_state.h" #include "media/base/audio_bus.h" @@ -99,6 +103,13 @@ class MEDIA_EXPORT AudioOutputStream { // Close the stream. This also generates AudioSourceCallback::OnClose(). // After calling this method, the object should not be used anymore. virtual void Close() = 0; + +#if defined(OS_TIZEN) + // Sets an application ID and class properties, which are used to tag audio + // streams in pulseaudio/Murphy. + virtual void SetMediaStreamProperties(const std::string& app_id, + const std::string& app_class) {} +#endif }; // Models an audio sink receiving recorded audio from the audio driver. diff --git a/src/media/audio/audio_output_controller.cc b/src/media/audio/audio_output_controller.cc index 45d308d..e1d015f 100644 --- a/src/media/audio/audio_output_controller.cc +++ b/src/media/audio/audio_output_controller.cc @@ -127,6 +127,10 @@ void AudioOutputController::DoCreate(bool is_for_device_change) { return; } +#if defined(OS_TIZEN) + stream_->SetMediaStreamProperties(handler_->app_id(), handler_->app_class()); +#endif + if (!stream_->Open()) { DoStopCloseAndClearStream(); state_ = kError; diff --git a/src/media/audio/audio_output_controller.h b/src/media/audio/audio_output_controller.h index f9e1033..0fd2efd 100644 --- a/src/media/audio/audio_output_controller.h +++ b/src/media/audio/audio_output_controller.h @@ -5,6 +5,10 @@ #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ #define MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ +#if defined(OS_TIZEN) +#include +#endif + #include "base/atomic_ref_count.h" #include "base/callback.h" #include "base/memory/ref_counted.h" @@ -69,6 +73,11 @@ class MEDIA_EXPORT AudioOutputController virtual void OnError() = 0; virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) = 0; +#if defined(OS_TIZEN) + virtual std::string app_id() const = 0; + virtual std::string app_class() const = 0; +#endif + protected: virtual ~EventHandler() {} }; diff --git a/src/media/audio/audio_output_dispatcher.cc b/src/media/audio/audio_output_dispatcher.cc index 7f3dd10..37a6410 100644 --- a/src/media/audio/audio_output_dispatcher.cc +++ b/src/media/audio/audio_output_dispatcher.cc @@ -25,4 +25,13 @@ AudioOutputDispatcher::~AudioOutputDispatcher() { DCHECK(task_runner_->BelongsToCurrentThread()); } +#if defined(OS_TIZEN) +void AudioOutputDispatcher::SetMediaStreamProperties( + const std::string& app_id, + const std::string& app_class) { + app_id_ = app_id; + app_class_ = app_class; +} +#endif + } // namespace media diff --git a/src/media/audio/audio_output_dispatcher.h b/src/media/audio/audio_output_dispatcher.h index 079cba0..115b89f 100644 --- a/src/media/audio/audio_output_dispatcher.h +++ b/src/media/audio/audio_output_dispatcher.h @@ -18,6 +18,10 @@ #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_H_ #define MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_H_ +#if defined(OS_TIZEN) +#include +#endif + #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/timer/timer.h" @@ -67,6 +71,11 @@ class MEDIA_EXPORT AudioOutputDispatcher const std::string& device_id() const { return device_id_; } +#if defined(OS_TIZEN) + virtual void SetMediaStreamProperties(const std::string& app_id, + const std::string& app_class); +#endif + protected: friend class base::RefCountedThreadSafe; virtual ~AudioOutputDispatcher(); @@ -78,6 +87,11 @@ class MEDIA_EXPORT AudioOutputDispatcher const AudioParameters params_; std::string device_id_; +#if defined(OS_TIZEN) + std::string app_id_; + std::string app_class_; +#endif + private: DISALLOW_COPY_AND_ASSIGN(AudioOutputDispatcher); }; diff --git a/src/media/audio/audio_output_dispatcher_impl.cc b/src/media/audio/audio_output_dispatcher_impl.cc index 0cb3db8..f44ae30 100644 --- a/src/media/audio/audio_output_dispatcher_impl.cc +++ b/src/media/audio/audio_output_dispatcher_impl.cc @@ -137,6 +137,10 @@ bool AudioOutputDispatcherImpl::CreateAndOpenStream() { if (!stream) return false; +#if defined(OS_TIZEN) + stream->SetMediaStreamProperties(app_id_, app_class_); +#endif + if (!stream->Open()) { stream->Close(); return false; diff --git a/src/media/audio/audio_output_proxy.cc b/src/media/audio/audio_output_proxy.cc index a69cbc9..10d8751 100644 --- a/src/media/audio/audio_output_proxy.cc +++ b/src/media/audio/audio_output_proxy.cc @@ -90,4 +90,11 @@ void AudioOutputProxy::Close() { delete this; } +#if defined(OS_TIZEN) +void AudioOutputProxy::SetMediaStreamProperties(const std::string& app_id, + const std::string& app_class) { + dispatcher_->SetMediaStreamProperties(app_id, app_class); +} +#endif + } // namespace media diff --git a/src/media/audio/audio_output_proxy.h b/src/media/audio/audio_output_proxy.h index 86dab51..4f5c6e3 100644 --- a/src/media/audio/audio_output_proxy.h +++ b/src/media/audio/audio_output_proxy.h @@ -5,6 +5,10 @@ #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_PROXY_H_ #define MEDIA_AUDIO_AUDIO_OUTPUT_PROXY_H_ +#if defined(OS_TIZEN) +#include +#endif + #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" @@ -39,6 +43,11 @@ class MEDIA_EXPORT AudioOutputProxy virtual void GetVolume(double* volume) OVERRIDE; virtual void Close() OVERRIDE; +#if defined(OS_TIZEN) + void SetMediaStreamProperties(const std::string& app_id, + const std::string& app_class) override; +#endif + private: enum State { kCreated, diff --git a/src/media/audio/audio_output_resampler.cc b/src/media/audio/audio_output_resampler.cc index 5926996..da28002 100644 --- a/src/media/audio/audio_output_resampler.cc +++ b/src/media/audio/audio_output_resampler.cc @@ -178,6 +178,10 @@ void AudioOutputResampler::Initialize() { bool AudioOutputResampler::OpenStream() { DCHECK(task_runner_->BelongsToCurrentThread()); +#if defined(OS_TIZEN) + dispatcher_->SetMediaStreamProperties(app_id_, app_class_); +#endif + if (dispatcher_->OpenStream()) { // Only record the UMA statistic if we didn't fallback during construction // and only for the first stream we open. @@ -246,6 +250,10 @@ bool AudioOutputResampler::StartStream( resampler_callback = it->second; } +#if defined(OS_TIZEN) + dispatcher_->SetMediaStreamProperties(app_id_, app_class_); +#endif + resampler_callback->Start(callback); bool result = dispatcher_->StartStream(resampler_callback, stream_proxy); if (!result) diff --git a/src/media/audio/pulse/pulse.sigs b/src/media/audio/pulse/pulse.sigs index 8d2dab7..03d9aa8 100644 --- a/src/media/audio/pulse/pulse.sigs +++ b/src/media/audio/pulse/pulse.sigs @@ -50,3 +50,8 @@ void pa_stream_unref(pa_stream* s); int pa_context_errno(pa_context *c); const char* pa_strerror(int error); pa_cvolume* pa_cvolume_set(pa_cvolume* a, unsigned channels, pa_volume_t v); +# Functions from pulse used in TIZEN to set the audio stream role. +pa_proplist* pa_proplist_new(void); +void pa_proplist_free(pa_proplist* p); +int pa_proplist_sets(pa_proplist *p, const char *key, const char *value); +pa_stream* pa_stream_new_with_proplist(pa_context* c, const char* name, const pa_sample_spec* ss, const pa_channel_map* map, pa_proplist* proplist); diff --git a/src/media/audio/pulse/pulse_output.cc b/src/media/audio/pulse/pulse_output.cc index e0a0b42..4f556c1 100644 --- a/src/media/audio/pulse/pulse_output.cc +++ b/src/media/audio/pulse/pulse_output.cc @@ -234,4 +234,13 @@ void PulseAudioOutputStream::GetVolume(double* volume) { *volume = volume_; } +#if defined(OS_TIZEN) +void PulseAudioOutputStream::SetMediaStreamProperties( + const std::string& app_id, + const std::string& app_class) { + app_id_ = app_id; + app_class_ = app_class; +} +#endif + } // namespace media diff --git a/src/media/audio/pulse/pulse_output.h b/src/media/audio/pulse/pulse_output.h index e1c0045..a0be5a6 100644 --- a/src/media/audio/pulse/pulse_output.h +++ b/src/media/audio/pulse/pulse_output.h @@ -51,6 +51,13 @@ class PulseAudioOutputStream : public AudioOutputStream { virtual void SetVolume(double volume) OVERRIDE; virtual void GetVolume(double* volume) OVERRIDE; +#if defined(OS_TIZEN) + void SetMediaStreamProperties(const std::string& app_id, + const std::string& app_class) override; + const std::string& app_id() const {return app_id_;} + const std::string& app_class() const {return app_class_;} +#endif + private: // Called by PulseAudio when |pa_stream_| change state. If an unexpected // failure state change happens and |source_callback_| is set @@ -91,6 +98,12 @@ class PulseAudioOutputStream : public AudioOutputStream { // Container for retrieving data from AudioSourceCallback::OnMoreData(). scoped_ptr audio_bus_; +#if defined(OS_TIZEN) + // Application ID and class for the pulseaudio streams. + std::string app_id_; + std::string app_class_; +#endif + base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(PulseAudioOutputStream); diff --git a/src/media/audio/pulse/pulse_util.cc b/src/media/audio/pulse/pulse_util.cc index c06195e..020ad3d 100644 --- a/src/media/audio/pulse/pulse_util.cc +++ b/src/media/audio/pulse/pulse_util.cc @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if defined(OS_TIZEN) +#include "media/audio/pulse/pulse_output.h" +#endif + #include "media/audio/pulse/pulse_util.h" #include "base/logging.h" @@ -259,7 +263,20 @@ bool CreateOutputStream(pa_threaded_mainloop** mainloop, // than the default channel map (NULL). map = &source_channel_map; } + +#if defined(OS_TIZEN) + PulseAudioOutputStream* data = + static_cast(user_data); + pa_proplist* proplist = pa_proplist_new(); + pa_proplist_sets(proplist, "resource.set.appid", data->app_id().c_str()); + pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, data->app_class().c_str()); + *stream = pa_stream_new_with_proplist(*context, "Playback", + &sample_specifications, + map, proplist); + pa_proplist_free(proplist); +#else *stream = pa_stream_new(*context, "Playback", &sample_specifications, map); +#endif RETURN_ON_FAILURE(*stream, "failed to create PA playback stream"); pa_stream_set_state_callback(*stream, stream_callback, user_data); diff --git a/src/ozone/ui/desktop_aura/desktop_window_tree_host_wayland.cc b/src/ozone/ui/desktop_aura/desktop_window_tree_host_wayland.cc index 656ac7d..c00e21a 100644 --- a/src/ozone/ui/desktop_aura/desktop_window_tree_host_wayland.cc +++ b/src/ozone/ui/desktop_aura/desktop_window_tree_host_wayland.cc @@ -464,6 +464,8 @@ void DesktopWindowTreeHostWayland::Minimize() { } void DesktopWindowTreeHostWayland::Restore() { + g_delegate_ozone_wayland_->SetActiveWindow(this); + if (state_ & Normal) return; diff --git a/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.cpp b/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.cpp index be022fd..810cd81 100644 --- a/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.cpp +++ b/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.cpp @@ -307,4 +307,58 @@ void ScriptProfiler::setIdle(bool isIdle) profiler->SetIdle(isIdle); } +namespace { + +class HeapXDKStream : public v8::OutputStream { +public: + HeapXDKStream(ScriptProfiler::OutputStream* stream) : m_stream(stream) { } + virtual void EndOfStream() OVERRIDE { } + + virtual WriteResult WriteAsciiChunk(char* data, int size) OVERRIDE + { + ASSERT(false); + return kAbort; + } + + virtual WriteResult WriteHeapXDKChunk(const char* symbols, int symbolsSize, + const char* frames, int framesSize, + const char* types, int typesSize, + const char* chunks, int chunksSize, + const char* retentions, + int retentionSize) OVERRIDE + { + m_stream->write(symbols, symbolsSize, frames, framesSize, + types, typesSize, chunks, chunksSize, + retentions, retentionSize); + return kContinue; + } + +private: + ScriptProfiler::OutputStream* m_stream; +}; + +} + +void ScriptProfiler::requestHeapXDKUpdate(ScriptProfiler::OutputStream* stream) +{ + HeapXDKStream heapXDKStream(stream); + v8::Isolate::GetCurrent()->GetHeapProfiler()->GetHeapXDKStats( + &heapXDKStream); +} + +void ScriptProfiler::startTrackingHeapObjectsXDK(int stackDepth, + bool retentions) +{ + v8::Isolate::GetCurrent()->GetHeapProfiler()->StartTrackingHeapObjectsXDK( + stackDepth, retentions); +} + +PassRefPtr ScriptProfiler::stopTrackingHeapObjectsXDK() +{ + return HeapProfileXDK::create( + v8::Isolate::GetCurrent() + ->GetHeapProfiler()->StopTrackingHeapObjectsXDK()); +} + + } // namespace blink diff --git a/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.h b/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.h index 826efdd..b68e448 100644 --- a/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.h +++ b/src/third_party/WebKit/Source/bindings/core/v8/ScriptProfiler.h @@ -62,6 +62,11 @@ public: public: virtual ~OutputStream() { } virtual void write(const uint32_t* chunk, const int size) = 0; + virtual void write(const char* symbols, int symbolsSize, + const char* frames, int framesSize, + const char* types, int typesSize, + const char* chunks, int chunksSize, + const char* retentions, int retentionsSize) { }; }; static void collectGarbage(); @@ -75,6 +80,9 @@ public: static void startTrackingHeapObjects(bool trackAllocations); static void stopTrackingHeapObjects(); static unsigned requestHeapStatsUpdate(OutputStream*); + static void startTrackingHeapObjectsXDK(int stackDepth, bool retentions); + static PassRefPtr stopTrackingHeapObjectsXDK(); + static void requestHeapXDKUpdate(OutputStream*); static void initialize(); static void visitNodeWrappers(WrappedNodeVisitor*); static HashMap* currentProfileNameIdleTimeMap(); diff --git a/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp b/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp index ed6b607..36ea17d 100644 --- a/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp +++ b/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp @@ -61,6 +61,20 @@ private: Timer m_timer; }; + +class InspectorHeapProfilerAgent::HeapXDKUpdateTask FINAL : public NoBaseWillBeGarbageCollectedFinalized { +public: + HeapXDKUpdateTask(InspectorHeapProfilerAgent*); + void startTimer(float sav); + void resetTimer() { m_timer.stop(); } + void onTimer(Timer*); + +private: + InspectorHeapProfilerAgent* m_heapProfilerAgent; + Timer m_timer; +}; + + PassOwnPtrWillBeRawPtr InspectorHeapProfilerAgent::create(InjectedScriptManager* injectedScriptManager) { return adoptPtrWillBeNoop(new InspectorHeapProfilerAgent(injectedScriptManager)); @@ -325,5 +339,118 @@ void InspectorHeapProfilerAgent::trace(Visitor* visitor) InspectorBaseAgent::trace(visitor); } +static PassRefPtr createHeapProfileXDK(const HeapProfileXDK& heapProfileXDK) +{ + RefPtr profile = TypeBuilder::HeapProfiler::HeapEventXDK::create() + .setDuration(heapProfileXDK.getDuration()) + .setSymbols(heapProfileXDK.getSymbols()) + .setFrames(heapProfileXDK.getFrames()) + .setTypes(heapProfileXDK.getTypes()) + .setChunks(heapProfileXDK.getChunks()) + .setRetentions(heapProfileXDK.getRetentions()); + return profile.release(); +} + +InspectorHeapProfilerAgent::HeapXDKUpdateTask::HeapXDKUpdateTask(InspectorHeapProfilerAgent* heapProfilerAgent) + : m_heapProfilerAgent(heapProfilerAgent) + , m_timer(this, &HeapXDKUpdateTask::onTimer) +{ +} + +void InspectorHeapProfilerAgent::HeapXDKUpdateTask::onTimer(Timer*) +{ + // The timer is stopped on m_heapProfilerAgent destruction, + // so this method will never be called after m_heapProfilerAgent has been destroyed. + m_heapProfilerAgent->requestHeapXDKUpdate(); +} + +void InspectorHeapProfilerAgent::HeapXDKUpdateTask::startTimer(float sav) +{ + ASSERT(!m_timer.isActive()); + m_timer.startRepeating(sav, FROM_HERE); +} + +void InspectorHeapProfilerAgent::startTrackingHeapXDK(ErrorString*, + const int* stack_depth, + const int* sav, + const bool* retentions) +{ + m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true); + + // inline of startTrackingHeapObjectsInternal(allocationTrackingEnabled); + if (m_heapXDKUpdateTask) + return; + int stackDepth = 8; + if (stack_depth) { + stackDepth = *stack_depth; + } + float sav_timer = 1; + if (sav) { + sav_timer = (float)*sav / 1000.; + } + bool needRetentions = retentions && *retentions; + ScriptProfiler::startTrackingHeapObjectsXDK(stackDepth, needRetentions ); + m_heapXDKUpdateTask = adoptPtr(new HeapXDKUpdateTask(this)); + m_heapXDKUpdateTask->startTimer(sav_timer); +} + +class InspectorHeapProfilerAgent::HeapXDKStream FINAL : public ScriptProfiler::OutputStream { +public: + HeapXDKStream(InspectorHeapProfilerAgent* heapProfilerAgent) + : m_heapProfilerAgent(heapProfilerAgent) + { + } + + virtual void write(const uint32_t* chunk, const int size){} + virtual void write(const char* symbols, int symbolsSize, + const char* frames, int framesSize, + const char* types, int typesSize, + const char* chunks, int chunksSize, + const char* retentions, int retentionsSize) OVERRIDE + { + m_heapProfilerAgent->pushHeapXDKUpdate(symbols, symbolsSize, frames, framesSize, + types, typesSize, chunks, chunksSize, + retentions, retentionsSize); + } +private: + InspectorHeapProfilerAgent* m_heapProfilerAgent; +}; + +void InspectorHeapProfilerAgent::requestHeapXDKUpdate() +{ + if (!m_frontend) + return; + HeapXDKStream stream(this); + ScriptProfiler::requestHeapXDKUpdate(&stream); +} + +void InspectorHeapProfilerAgent::stopTrackingHeapXDK(ErrorString* error, RefPtr& profile) +{ + if (!m_heapXDKUpdateTask) { + *error = "Heap object tracking is not started."; + return; + } + + RefPtr heapProfileXDK = ScriptProfiler::stopTrackingHeapObjectsXDK(); + profile = createHeapProfileXDK(*heapProfileXDK); + + m_heapXDKUpdateTask->resetTimer(); + m_heapXDKUpdateTask.clear(); + m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, false); + +} +void InspectorHeapProfilerAgent::pushHeapXDKUpdate( const char* symbols, int symbolsSize, + const char* frames, int framesSize, + const char* types, int typesSize, + const char* chunks, int chunksSize, + const char* retentions, int retentionsSize) +{ + if (!m_frontend) + return; + m_frontend->heapXDKUpdate(String(symbols, symbolsSize), String(frames, framesSize), + String(types, typesSize), String(chunks, chunksSize), + String(retentions, retentionsSize)); +} + } // namespace blink diff --git a/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h b/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h index ac3ce51..03be422 100644 --- a/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h +++ b/src/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h @@ -6,7 +6,8 @@ * met: * * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of co + * nditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the @@ -62,6 +63,8 @@ public: virtual void disable(ErrorString*) OVERRIDE; virtual void startTrackingHeapObjects(ErrorString*, const bool* trackAllocations) OVERRIDE; virtual void stopTrackingHeapObjects(ErrorString*, const bool* reportProgress) OVERRIDE; + virtual void startTrackingHeapXDK(ErrorString*, const int* stack_depth, const int* sav, const bool* retentions) OVERRIDE; + virtual void stopTrackingHeapXDK(ErrorString*, RefPtr&) OVERRIDE; virtual void setFrontend(InspectorFrontend*) OVERRIDE; virtual void clearFrontend() OVERRIDE; @@ -76,11 +79,21 @@ private: class HeapStatsStream; class HeapStatsUpdateTask; + class HeapXDKStream; + class HeapXDKUpdateTask; + explicit InspectorHeapProfilerAgent(InjectedScriptManager*); void requestHeapStatsUpdate(); void pushHeapStatsUpdate(const uint32_t* const data, const int size); + void requestHeapXDKUpdate(); + void pushHeapXDKUpdate(const char* symbols, int symbolsSize, + const char* frames, int framesSize, + const char* types, int typesSize, + const char* chunks, int chunksSize, + const char* retentions, int retentionsSize); + void startTrackingHeapObjectsInternal(bool trackAllocations); void stopTrackingHeapObjectsInternal(); @@ -88,6 +101,7 @@ private: InspectorFrontend::HeapProfiler* m_frontend; unsigned m_nextUserInitiatedHeapSnapshotNumber; OwnPtrWillBeMember m_heapStatsUpdateTask; + OwnPtrWillBeMember m_heapXDKUpdateTask; }; } // namespace blink diff --git a/src/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp b/src/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp index e835b01..f352976 100644 --- a/src/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp +++ b/src/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp @@ -64,6 +64,26 @@ double ScriptProfile::endTime() const return static_cast(m_profile->GetEndTime()) / 1000000; } +static RefPtr > buildInspectorObjectForLineTicks(const v8::CpuProfileNode* node) +{ + RefPtr > array = TypeBuilder::Array::create(); + unsigned int lineCount = node->GetHitLineCount(); + if (lineCount) { + Vector entries(lineCount); + bool res = node->GetLineTicks(&entries[0], lineCount); + if (res) { + for (unsigned int i = 0; i < lineCount; i++) { + RefPtr line = TypeBuilder::Profiler::LineTick::create() + .setLine(entries[i].line) + .setTicks(entries[i].hit_count); + array->addItem(line); + line.release(); + } + } + } + return array; +} + static PassRefPtr buildInspectorObjectFor(const v8::CpuProfileNode* node) { v8::HandleScope handleScope(v8::Isolate::GetCurrent()); @@ -75,6 +95,8 @@ static PassRefPtr buildInspectorObjectFor children->addItem(buildInspectorObjectFor(child)); } + RefPtr > lineTicks = buildInspectorObjectForLineTicks(node); + RefPtr result = TypeBuilder::Profiler::CPUProfileNode::create() .setFunctionName(toCoreString(node->GetFunctionName())) .setScriptId(String::number(node->GetScriptId())) @@ -84,6 +106,7 @@ static PassRefPtr buildInspectorObjectFor .setHitCount(node->GetHitCount()) .setCallUID(node->GetCallUid()) .setChildren(children.release()) + .setLineTicks(lineTicks.release()) .setDeoptReason(node->GetBailoutReason()) .setId(node->GetNodeId()); return result.release(); @@ -112,4 +135,34 @@ PassRefPtr > ScriptProfile::buildInspectorObjectForTi return array.release(); } +String HeapProfileXDK::getSymbols() const +{ + return String(m_event->getSymbols()); +} + +String HeapProfileXDK::getFrames() const +{ + return String(m_event->getFrames()); +} + +String HeapProfileXDK::getTypes() const +{ + return String(m_event->getTypes()); +} + +String HeapProfileXDK::getChunks() const +{ + return String(m_event->getChunks()); +} + +int HeapProfileXDK::getDuration() const +{ + return (int)m_event->getDuration(); +} + +String HeapProfileXDK::getRetentions() const +{ + return String(m_event->getRetentions()); +} + } // namespace blink diff --git a/src/third_party/WebKit/Source/core/inspector/ScriptProfile.h b/src/third_party/WebKit/Source/core/inspector/ScriptProfile.h index ad8e652..af522ce 100644 --- a/src/third_party/WebKit/Source/core/inspector/ScriptProfile.h +++ b/src/third_party/WebKit/Source/core/inspector/ScriptProfile.h @@ -69,6 +69,30 @@ private: double m_idleTime; }; +class HeapProfileXDK FINAL : public RefCountedWillBeGarbageCollectedFinalized { +public: + static PassRefPtrWillBeRawPtr create(v8::HeapEventXDK* event) + { + return adoptRefWillBeNoop(new HeapProfileXDK(event)); + } + + String getSymbols() const; + String getFrames() const; + String getTypes() const; + String getChunks() const; + String getRetentions() const; + int getDuration() const; + +private: + HeapProfileXDK(v8::HeapEventXDK* event) + : m_event(event) + { + } + + v8::HeapEventXDK* m_event; + +}; + } // namespace blink #endif // ScriptProfile_h diff --git a/src/third_party/WebKit/Source/devtools/protocol.json b/src/third_party/WebKit/Source/devtools/protocol.json index 12246b8..8b6a9a4 100644 --- a/src/third_party/WebKit/Source/devtools/protocol.json +++ b/src/third_party/WebKit/Source/devtools/protocol.json @@ -3625,7 +3625,8 @@ { "name": "callUID", "type": "number", "description": "Call UID." }, { "name": "children", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "Child nodes." }, { "name": "deoptReason", "type": "string", "description": "The reason of being not optimized. The function may be deoptimized or marked as don't optimize."}, - { "name": "id", "type": "integer", "description": "Unique id of the node." } + { "name": "id", "type": "integer", "description": "Unique id of the node." }, + { "name": "lineTicks", "type": "array", "items": { "$ref": "LineTick" }, "description": "A set of source line ticks." } ] }, { @@ -3639,7 +3640,16 @@ { "name": "samples", "optional": true, "type": "array", "items": { "type": "integer" }, "description": "Ids of samples top nodes." }, { "name": "timestamps", "optional": true, "type": "array", "items": { "type": "number" }, "description": "Timestamps of the samples in microseconds." } ] - } + }, + { + "id": "LineTick", + "type": "object", + "description": "Specifies a number of samples attributed to a certain source line.", + "properties": [ + { "name": "line", "type": "integer", "description": "Source line number." }, + { "name": "ticks", "type": "integer", "description": "Number of samples attributed to a source line number." } + ] + } ], "commands": [ { @@ -3695,6 +3705,19 @@ "id": "HeapSnapshotObjectId", "type": "string", "description": "Heap snapshot object id." + }, + { + "id": "HeapEventXDK", + "type": "object", + "description": "", + "properties": [ + { "name": "duration", "type": "integer" }, + { "name": "symbols", "type": "string" }, + { "name": "frames", "type": "string" }, + { "name": "types", "type": "string" }, + { "name": "chunks", "type": "string" }, + { "name": "retentions", "type": "string" } + ] } ], "commands": [ @@ -3718,6 +3741,20 @@ }, { + "name": "startTrackingHeapXDK", + "parameters": [ + { "name": "stack_depth", "type": "integer", "optional": true }, + { "name": "sav", "type": "integer", "optional": true }, + { "name": "retentions", "type": "boolean", "optional": true } + ] + }, + { + "name": "stopTrackingHeapXDK", + "returns": [ + { "name": "profileXDK", "$ref": "HeapEventXDK", "description": "Recorded profile." } + ] + }, + { "name": "takeHeapSnapshot", "parameters": [ { "name": "reportProgress", "type": "boolean", "optional": true, "description": "If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken." } @@ -3778,7 +3815,17 @@ "parameters": [ { "name": "statsUpdate", "type": "array", "items": { "type": "integer" }, "description": "An array of triplets. Each triplet describes a fragment. The first integer is the fragment index, the second integer is a total count of objects for the fragment, the third integer is a total size of the objects for the fragment."} ] - } + }, + { + "name": "heapXDKUpdate", + "parameters": [ + { "name": "symbols", "type": "string" }, + { "name": "frames", "type": "string" }, + { "name": "types", "type": "string" }, + { "name": "chunks", "type": "string" }, + { "name": "retentions", "type": "string" } + ] + } ] }, { diff --git a/src/v8/include/v8-profiler.h b/src/v8/include/v8-profiler.h index d021520..b1ae6eb 100644 --- a/src/v8/include/v8-profiler.h +++ b/src/v8/include/v8-profiler.h @@ -143,6 +143,19 @@ class V8_EXPORT CpuProfile { /** + * HeapEventXDK contains the latest chunk of heap info + */ +class V8_EXPORT HeapEventXDK { + public: + const char* getSymbols(); + const char* getFrames(); + const char* getTypes(); + const char* getChunks(); + const char* getRetentions(); + unsigned int getDuration(); +}; + +/** * Interface for controlling CPU profiling. Instance of the * profiler can be retrieved using v8::Isolate::GetCpuProfiler. */ @@ -314,6 +327,19 @@ class V8_EXPORT OutputStream { // NOLINT virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) { return kAbort; } + + + /** + * Writes XDK object + */ + virtual WriteResult WriteHeapXDKChunk(const char* symbols, int symbolsSize, + const char* frames, int framesSize, + const char* types, int typesSize, + const char* chunks, int chunksSize, + const char* retentions, + int retentionSize) { + return kAbort; + } }; @@ -530,6 +556,14 @@ class V8_EXPORT HeapProfiler { */ void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info); + void StartTrackingHeapObjectsXDK(int stackDepth, bool retentions, + bool strict_collection = false); + /** + * @author amalyshe + */ + void GetHeapXDKStats(OutputStream* stream); + HeapEventXDK* StopTrackingHeapObjectsXDK(); + private: HeapProfiler(); ~HeapProfiler(); diff --git a/src/v8/src/api.cc b/src/v8/src/api.cc index 2546456..7e612cd 100644 --- a/src/v8/src/api.cc +++ b/src/v8/src/api.cc @@ -47,7 +47,7 @@ #include "src/v8threads.h" #include "src/version.h" #include "src/vm-state-inl.h" - +#include "src/xdk-allocation.h" #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr)) @@ -7316,6 +7316,47 @@ Handle HeapSnapshot::GetTitle() const { } +const char* HeapEventXDK::getSymbols() { + const i::HeapEventXDK* eventXDK = + reinterpret_cast(this); + return eventXDK->symbols(); +} + + +const char* HeapEventXDK::getFrames() { + const i::HeapEventXDK* eventXDK = + reinterpret_cast(this); + return eventXDK->frames(); +} + + +const char* HeapEventXDK::getTypes() { + const i::HeapEventXDK* eventXDK = + reinterpret_cast(this); + return eventXDK->types(); +} + + +const char* HeapEventXDK::getChunks() { + const i::HeapEventXDK* eventXDK = + reinterpret_cast(this); + return eventXDK->chunks(); +} + + +const char* HeapEventXDK::getRetentions() { + const i::HeapEventXDK* eventXDK = + reinterpret_cast(this); + return eventXDK->retentions(); +} + + +unsigned int HeapEventXDK::getDuration() { + const i::HeapEventXDK* eventXDK = + reinterpret_cast(this); + return eventXDK->duration(); +} + const HeapGraphNode* HeapSnapshot::GetRoot() const { return reinterpret_cast(ToInternal(this)->root()); } @@ -7412,6 +7453,24 @@ SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) { } +void HeapProfiler::GetHeapXDKStats(OutputStream* stream) { + reinterpret_cast(this)->PushHeapObjectsXDKStats(stream); +} + + +void HeapProfiler::StartTrackingHeapObjectsXDK(int stackDepth, + bool retentions, bool strict_collection) { + reinterpret_cast(this)->StartHeapObjectsTrackingXDK( + stackDepth, retentions, strict_collection); +} + + +HeapEventXDK* HeapProfiler::StopTrackingHeapObjectsXDK() { + return reinterpret_cast( + reinterpret_cast(this)->StopHeapObjectsTrackingXDK()); +} + + void HeapProfiler::DeleteAllHeapSnapshots() { reinterpret_cast(this)->DeleteAllSnapshots(); } diff --git a/src/v8/src/cpu-profiler.cc b/src/v8/src/cpu-profiler.cc index 115324c..2d611b4 100644 --- a/src/v8/src/cpu-profiler.cc +++ b/src/v8/src/cpu-profiler.cc @@ -20,17 +20,16 @@ namespace internal { static const int kProfilerStackSize = 64 * KB; -ProfilerEventsProcessor::ProfilerEventsProcessor( - ProfileGenerator* generator, - Sampler* sampler, - base::TimeDelta period) +ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator, + Sampler* sampler, + base::TimeDelta period) : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), generator_(generator), sampler_(sampler), - running_(true), + running_(1), period_(period), - last_code_event_id_(0), last_processed_code_event_id_(0) { -} + last_code_event_id_(0), + last_processed_code_event_id_(0) {} void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { @@ -55,8 +54,7 @@ void ProfilerEventsProcessor::AddCurrentStack(Isolate* isolate) { void ProfilerEventsProcessor::StopSynchronously() { - if (!running_) return; - running_ = false; + if (!base::NoBarrier_AtomicExchange(&running_, 0)) return; Join(); } @@ -107,7 +105,7 @@ ProfilerEventsProcessor::SampleProcessingResult void ProfilerEventsProcessor::Run() { - while (running_) { + while (!!base::NoBarrier_Load(&running_)) { base::ElapsedTimer timer; timer.Start(); // Keep processing existing events until we need to do next sample. @@ -201,7 +199,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->start = code->address(); - rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); + rec->entry = profiles_->NewCodeEntry( + tag, + profiles_->GetFunctionName(name), + CodeEntry::kEmptyNamePrefix, + CodeEntry::kEmptyResourceName, + CpuProfileNode::kNoLineNumberInfo, + CpuProfileNode::kNoColumnNumberInfo, + NULL, + code->instruction_start()); rec->size = code->ExecutableSize(); rec->shared = NULL; processor_->Enqueue(evt_rec); @@ -215,7 +221,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->start = code->address(); - rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); + rec->entry = profiles_->NewCodeEntry( + tag, + profiles_->GetFunctionName(name), + CodeEntry::kEmptyNamePrefix, + CodeEntry::kEmptyResourceName, + CpuProfileNode::kNoLineNumberInfo, + CpuProfileNode::kNoColumnNumberInfo, + NULL, + code->instruction_start()); rec->size = code->ExecutableSize(); rec->shared = NULL; processor_->Enqueue(evt_rec); @@ -231,7 +245,11 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, rec->start = code->address(); rec->entry = profiles_->NewCodeEntry( tag, profiles_->GetFunctionName(shared->DebugName()), - CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name)); + CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), + CpuProfileNode::kNoLineNumberInfo, + CpuProfileNode::kNoColumnNumberInfo, + NULL, + code->instruction_start()); if (info) { rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); } @@ -256,11 +274,9 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->start = code->address(); - Script* script = NULL; + Script* script = Script::cast(shared->script()); JITLineInfoTable* line_table = NULL; - if (shared->script()->IsScript()) { - DCHECK(Script::cast(shared->script())); - script = Script::cast(shared->script()); + if (script) { line_table = new JITLineInfoTable(); for (RelocIterator it(code); !it.done(); it.next()) { RelocInfo::Mode mode = it.rinfo()->rmode(); @@ -277,17 +293,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, rec->entry = profiles_->NewCodeEntry( tag, profiles_->GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line, - column, line_table); + column, line_table, code->instruction_start()); if (info) { rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); } - if (script) { - rec->entry->set_script_id(script->id()->value()); - } - rec->entry->set_bailout_reason( - GetBailoutReason(shared->DisableOptimizationReason())); + rec->entry->set_script_id(script->id()->value()); rec->size = code->ExecutableSize(); rec->shared = shared->address(); + rec->entry->set_bailout_reason( + GetBailoutReason(shared->DisableOptimizationReason())); processor_->Enqueue(evt_rec); } @@ -302,7 +316,12 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, rec->entry = profiles_->NewCodeEntry( tag, profiles_->GetName(args_count), - "args_count: "); + "args_count: ", + CodeEntry::kEmptyResourceName, + CpuProfileNode::kNoLineNumberInfo, + CpuProfileNode::kNoColumnNumberInfo, + NULL, + code->instruction_start()); rec->size = code->ExecutableSize(); rec->shared = NULL; processor_->Enqueue(evt_rec); @@ -364,7 +383,12 @@ void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { rec->entry = profiles_->NewCodeEntry( Logger::REG_EXP_TAG, profiles_->GetName(source), - "RegExp: "); + "RegExp: ", + CodeEntry::kEmptyResourceName, + CpuProfileNode::kNoLineNumberInfo, + CpuProfileNode::kNoColumnNumberInfo, + NULL, + code->instruction_start()); rec->size = code->ExecutableSize(); processor_->Enqueue(evt_rec); } diff --git a/src/v8/src/cpu-profiler.h b/src/v8/src/cpu-profiler.h index c1e75a1..4dc5643 100644 --- a/src/v8/src/cpu-profiler.h +++ b/src/v8/src/cpu-profiler.h @@ -132,7 +132,7 @@ class ProfilerEventsProcessor : public base::Thread { // Thread control. virtual void Run(); void StopSynchronously(); - INLINE(bool running()) { return running_; } + INLINE(bool running()) { return !!base::NoBarrier_Load(&running_); } void Enqueue(const CodeEventsContainer& event); // Puts current stack into tick sample events buffer. @@ -163,7 +163,7 @@ class ProfilerEventsProcessor : public base::Thread { ProfileGenerator* generator_; Sampler* sampler_; - bool running_; + base::Atomic32 running_; // Sampling period in microseconds. const base::TimeDelta period_; UnboundQueue events_buffer_; diff --git a/src/v8/src/heap-profiler.cc b/src/v8/src/heap-profiler.cc index d86ce5e..eec5fd1 100644 --- a/src/v8/src/heap-profiler.cc +++ b/src/v8/src/heap-profiler.cc @@ -8,6 +8,7 @@ #include "src/allocation-tracker.h" #include "src/heap-snapshot-generator-inl.h" +#include "src/xdk-allocation.h" namespace v8 { namespace internal { @@ -68,7 +69,7 @@ HeapSnapshot* HeapProfiler::TakeSnapshot( v8::HeapProfiler::ObjectNameResolver* resolver) { HeapSnapshot* result = new HeapSnapshot(this, name, next_snapshot_uid_++); { - HeapSnapshotGenerator generator(result, control, resolver, heap()); + HeapSnapshotGenerator generator(this, result, control, resolver, heap()); if (!generator.GenerateSnapshot()) { delete result; result = NULL; @@ -115,6 +116,46 @@ void HeapProfiler::StopHeapObjectsTracking() { } +void HeapProfiler::StartHeapObjectsTrackingXDK(int stackDepth, + bool retentions, bool strict_collection) { + ids_->UpdateHeapObjectsMap(); + is_tracking_object_moves_ = true; + DCHECK(!is_tracking_allocations()); + allocation_tracker_xdk_.Reset(new XDKAllocationTracker(this, ids_.get(), + names_.get(), stackDepth, retentions, + strict_collection)); + heap()->DisableInlineAllocation(); + // init pre collected objects + allocation_tracker_xdk_->CollectFreedObjects(false, true); +} + + +void HeapProfiler::PushHeapObjectsXDKStats(OutputStream* stream) { + // get the garbage here + if (!allocation_tracker_xdk_.is_empty()) { + allocation_tracker_xdk_->CollectFreedObjects(); + OutputStream::WriteResult result = + allocation_tracker_xdk_->SendChunk(stream); + // TODO(amalyshe): it's interesting why CDT can return kAbort. Need to + // investigate if we need add better error generation in the + // allocation_tracker_xdk_->SendChunk + if (result == OutputStream::kAbort) return; + stream->EndOfStream(); + } +} + + +v8::internal::HeapEventXDK* HeapProfiler::StopHeapObjectsTrackingXDK() { + HeapEventXDK* event = NULL; + if (!allocation_tracker_xdk_.is_empty()) { + event = allocation_tracker_xdk_->stopTracking(); + allocation_tracker_xdk_.Reset(NULL); + heap()->EnableInlineAllocation(); + } + return event; +} + + size_t HeapProfiler::GetMemorySizeUsedByProfiler() { size_t size = sizeof(*this); size += names_->GetUsedMemorySize(); @@ -145,9 +186,13 @@ SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle obj) { void HeapProfiler::ObjectMoveEvent(Address from, Address to, int size) { - bool known_object = ids_->MoveObject(from, to, size); - if (!known_object && !allocation_tracker_.is_empty()) { - allocation_tracker_->address_to_trace()->MoveObject(from, to, size); + if (allocation_tracker_xdk_.is_empty()) { + bool known_object = ids_->MoveObject(from, to, size); + if (!known_object && !allocation_tracker_.is_empty()) { + allocation_tracker_->address_to_trace()->MoveObject(from, to, size); + } + } else { + allocation_tracker_xdk_->OnMove(from, to, size); } } @@ -157,6 +202,9 @@ void HeapProfiler::AllocationEvent(Address addr, int size) { if (!allocation_tracker_.is_empty()) { allocation_tracker_->AllocationEvent(addr, size); } + if (!allocation_tracker_xdk_.is_empty()) { + allocation_tracker_xdk_->OnAlloc(addr, size); + } } diff --git a/src/v8/src/heap-profiler.h b/src/v8/src/heap-profiler.h index 4197d4d..88141cb 100644 --- a/src/v8/src/heap-profiler.h +++ b/src/v8/src/heap-profiler.h @@ -13,6 +13,7 @@ namespace v8 { namespace internal { class HeapSnapshot; +class HeapEventXDK; class HeapProfiler { public: @@ -39,6 +40,11 @@ class HeapProfiler { StringsStorage* names() const { return names_.get(); } SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); + void PushHeapObjectsXDKStats(OutputStream* stream); + void StartHeapObjectsTrackingXDK(int stackDepth, bool retentions, + bool strict_collection = false); + v8::internal::HeapEventXDK* StopHeapObjectsTrackingXDK(); + int GetSnapshotsCount(); HeapSnapshot* GetSnapshot(int index); SnapshotObjectId GetSnapshotObjectId(Handle obj); @@ -60,7 +66,8 @@ class HeapProfiler { bool is_tracking_object_moves() const { return is_tracking_object_moves_; } bool is_tracking_allocations() const { - return !allocation_tracker_.is_empty(); + return (!allocation_tracker_.is_empty() || + !allocation_tracker_xdk_.is_empty()); } Handle FindHeapObjectById(SnapshotObjectId id); @@ -76,6 +83,7 @@ class HeapProfiler { unsigned next_snapshot_uid_; List wrapper_callbacks_; SmartPointer allocation_tracker_; + SmartPointer allocation_tracker_xdk_; bool is_tracking_object_moves_; }; diff --git a/src/v8/src/heap-snapshot-generator-inl.h b/src/v8/src/heap-snapshot-generator-inl.h index 3f7e622..9fe704f 100644 --- a/src/v8/src/heap-snapshot-generator-inl.h +++ b/src/v8/src/heap-snapshot-generator-inl.h @@ -22,7 +22,7 @@ HeapSnapshot* HeapGraphEdge::snapshot() const { int HeapEntry::index() const { - return static_cast(this - &snapshot_->entries().first()); + return static_cast(this - &entries_->first()); } diff --git a/src/v8/src/heap-snapshot-generator.cc b/src/v8/src/heap-snapshot-generator.cc index 4a4c914..d77e519 100644 --- a/src/v8/src/heap-snapshot-generator.cc +++ b/src/v8/src/heap-snapshot-generator.cc @@ -47,6 +47,7 @@ void HeapGraphEdge::ReplaceToIndexWithEntry(HeapSnapshot* snapshot) { const int HeapEntry::kNoEntry = -1; HeapEntry::HeapEntry(HeapSnapshot* snapshot, + const List* entries, Type type, const char* name, SnapshotObjectId id, @@ -57,6 +58,7 @@ HeapEntry::HeapEntry(HeapSnapshot* snapshot, children_index_(-1), self_size_(self_size), snapshot_(snapshot), + entries_(entries), name_(name), id_(id), trace_node_id_(trace_node_id) { } @@ -169,12 +171,16 @@ template struct SnapshotSizeConstants; template <> struct SnapshotSizeConstants<4> { static const int kExpectedHeapGraphEdgeSize = 12; - static const int kExpectedHeapEntrySize = 28; + // This variable reflects the size of the HeapEntry structure + // it is increased to the 4 bytes in case of 32bit arch and for + // 8 bytes for 64 bit arch because for isolating HeapEntry from + // snapshot we need to add one more pointer to the List* entries_ + static const int kExpectedHeapEntrySize = 32; }; template <> struct SnapshotSizeConstants<8> { static const int kExpectedHeapGraphEdgeSize = 24; - static const int kExpectedHeapEntrySize = 40; + static const int kExpectedHeapEntrySize = 48; }; } // namespace @@ -269,7 +275,7 @@ HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, SnapshotObjectId id, size_t size, unsigned trace_node_id) { - HeapEntry entry(this, type, name, id, size, trace_node_id); + HeapEntry entry(this, &this->entries(), type, name, id, size, trace_node_id); entries_.Add(entry); return &entries_.last(); } @@ -779,13 +785,14 @@ void HeapObjectsSet::SetTag(Object* obj, const char* tag) { V8HeapExplorer::V8HeapExplorer( + HeapProfiler* profiler, HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress, v8::HeapProfiler::ObjectNameResolver* resolver) - : heap_(snapshot->profiler()->heap_object_map()->heap()), + : heap_(profiler->heap_object_map()->heap()), snapshot_(snapshot), - names_(snapshot_->profiler()->names()), - heap_object_map_(snapshot_->profiler()->heap_object_map()), + names_(profiler->names()), + heap_object_map_(profiler->heap_object_map()), progress_(progress), filler_(NULL), global_object_name_resolver_(resolver) { @@ -891,12 +898,13 @@ HeapEntry* V8HeapExplorer::AddEntry(Address address, } -class SnapshotFiller { +class CDTSnapshotFiller: public SnapshotFiller { public: - explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) + explicit CDTSnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) : snapshot_(snapshot), names_(snapshot->profiler()->names()), entries_(entries) { } + virtual ~CDTSnapshotFiller() {} HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { HeapEntry* entry = allocator->AllocateEntry(ptr); entries_->Pair(ptr, entry->index()); @@ -1855,11 +1863,15 @@ bool V8HeapExplorer::IterateAndExtractReferences( // Make sure builtin code objects get their builtin tags // first. Otherwise a particular JSFunction object could set // its custom name to a generic builtin. - RootsReferencesExtractor extractor(heap_); - heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); - extractor.SetCollectingAllReferences(); - heap_->IterateRoots(&extractor, VISIT_ALL); - extractor.FillReferences(this); + // TODO(amalyshe): this condition should be refactored for catching + // root extractor + if (snapshot_) { + RootsReferencesExtractor extractor(heap_); + heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); + extractor.SetCollectingAllReferences(); + heap_->IterateRoots(&extractor, VISIT_ALL); + extractor.FillReferences(this); + } // We have to do two passes as sometimes FixedArrays are used // to weakly hold their items, and it's impossible to distinguish @@ -2085,10 +2097,12 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, void V8HeapExplorer::SetRootGcRootsReference() { - filler_->SetIndexedAutoIndexReference( - HeapGraphEdge::kElement, - snapshot_->root()->index(), - snapshot_->gc_roots()); + if (snapshot_) { + filler_->SetIndexedAutoIndexReference( + HeapGraphEdge::kElement, + snapshot_->root()->index(), + snapshot_->gc_roots()); + } } @@ -2103,10 +2117,12 @@ void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) { void V8HeapExplorer::SetGcRootsReference(VisitorSynchronization::SyncTag tag) { - filler_->SetIndexedAutoIndexReference( - HeapGraphEdge::kElement, - snapshot_->gc_roots()->index(), - snapshot_->gc_subroot(tag)); + if (snapshot_) { + filler_->SetIndexedAutoIndexReference( + HeapGraphEdge::kElement, + snapshot_->gc_roots()->index(), + snapshot_->gc_subroot(tag)); + } } @@ -2258,11 +2274,12 @@ class GlobalHandlesExtractor : public ObjectVisitor { class BasicHeapEntriesAllocator : public HeapEntriesAllocator { public: BasicHeapEntriesAllocator( + HeapProfiler* profiler, HeapSnapshot* snapshot, HeapEntry::Type entries_type) : snapshot_(snapshot), - names_(snapshot_->profiler()->names()), - heap_object_map_(snapshot_->profiler()->heap_object_map()), + names_(profiler->names()), + heap_object_map_(profiler->heap_object_map()), entries_type_(entries_type) { } virtual HeapEntry* AllocateEntry(HeapThing ptr); @@ -2292,20 +2309,21 @@ HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) { NativeObjectsExplorer::NativeObjectsExplorer( + HeapProfiler* profiler, HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress) - : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()), + : isolate_(profiler->heap_object_map()->heap()->isolate()), snapshot_(snapshot), - names_(snapshot_->profiler()->names()), + names_(profiler->names()), progress_(progress), embedder_queried_(false), objects_by_info_(RetainedInfosMatch), native_groups_(StringsMatch), filler_(NULL) { synthetic_entries_allocator_ = - new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); + new BasicHeapEntriesAllocator(profiler, snapshot, HeapEntry::kSynthetic); native_entries_allocator_ = - new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); + new BasicHeapEntriesAllocator(profiler, snapshot, HeapEntry::kNative); } @@ -2533,15 +2551,18 @@ void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { HeapSnapshotGenerator::HeapSnapshotGenerator( + HeapProfiler* profiler, HeapSnapshot* snapshot, v8::ActivityControl* control, v8::HeapProfiler::ObjectNameResolver* resolver, - Heap* heap) + Heap* heap, + SnapshotFiller* filler) : snapshot_(snapshot), control_(control), - v8_heap_explorer_(snapshot_, this, resolver), - dom_explorer_(snapshot_, this), - heap_(heap) { + v8_heap_explorer_(profiler, snapshot_, this, resolver), + dom_explorer_(profiler, snapshot_, this), + heap_(heap), + filler_(filler) { } @@ -2570,12 +2591,16 @@ bool HeapSnapshotGenerator::GenerateSnapshot() { debug_heap->Verify(); #endif - snapshot_->AddSyntheticRootEntries(); + if (snapshot_) { + snapshot_->AddSyntheticRootEntries(); + } if (!FillReferences()) return false; - snapshot_->FillChildren(); - snapshot_->RememberLastJSObjectId(); + if (snapshot_) { + snapshot_->FillChildren(); + snapshot_->RememberLastJSObjectId(); + } progress_counter_ = progress_total_; if (!ProgressReport(true)) return false; @@ -2611,9 +2636,16 @@ void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { bool HeapSnapshotGenerator::FillReferences() { - SnapshotFiller filler(snapshot_, &entries_); - return v8_heap_explorer_.IterateAndExtractReferences(&filler) - && dom_explorer_.IterateAndExtractReferences(&filler); + if (!filler_) { + CDTSnapshotFiller filler(snapshot_, &entries_); + return v8_heap_explorer_.IterateAndExtractReferences(&filler) + && dom_explorer_.IterateAndExtractReferences(&filler); + } else { + // TODO(amalyshe): finally this need to be returned back when XDK heap + // profiler supports toot extractor + // v8_heap_explorer_.AddRootEntries(filler_); + return v8_heap_explorer_.IterateAndExtractReferences(filler_); + } } diff --git a/src/v8/src/heap-snapshot-generator.h b/src/v8/src/heap-snapshot-generator.h index 3e4ce71..e649317 100644 --- a/src/v8/src/heap-snapshot-generator.h +++ b/src/v8/src/heap-snapshot-generator.h @@ -11,6 +11,7 @@ namespace v8 { namespace internal { class AllocationTracker; +class XDKAllocationTracker; class AllocationTraceNode; class HeapEntry; class HeapSnapshot; @@ -90,6 +91,7 @@ class HeapEntry BASE_EMBEDDED { HeapEntry() { } HeapEntry(HeapSnapshot* snapshot, + const List* entries, Type type, const char* name, SnapshotObjectId id, @@ -129,6 +131,7 @@ class HeapEntry BASE_EMBEDDED { int children_index_; size_t self_size_; HeapSnapshot* snapshot_; + const List* entries_; const char* name_; SnapshotObjectId id_; // id of allocation stack trace top node @@ -323,11 +326,36 @@ class SnapshottingProgressReportingInterface { virtual bool ProgressReport(bool force) = 0; }; +class SnapshotFiller { + public: + virtual ~SnapshotFiller() {} + + virtual HeapEntry* AddEntry(HeapThing ptr, + HeapEntriesAllocator* allocator) = 0; + virtual HeapEntry* FindEntry(HeapThing ptr) = 0; + virtual HeapEntry* FindOrAddEntry(HeapThing ptr, + HeapEntriesAllocator* allocator) = 0; + virtual void SetIndexedReference(HeapGraphEdge::Type type, + int parent, + int index, + HeapEntry* child_entry) = 0; + virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, + int parent, + HeapEntry* child_entry) = 0; + virtual void SetNamedReference(HeapGraphEdge::Type type, + int parent, + const char* reference_name, + HeapEntry* child_entry) = 0; + virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type, + int parent, + HeapEntry* child_entry) = 0; +}; // An implementation of V8 heap graph extractor. class V8HeapExplorer : public HeapEntriesAllocator { public: - V8HeapExplorer(HeapSnapshot* snapshot, + V8HeapExplorer(HeapProfiler* profiler, + HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress, v8::HeapProfiler::ObjectNameResolver* resolver); virtual ~V8HeapExplorer(); @@ -470,7 +498,8 @@ class NativeGroupRetainedObjectInfo; // An implementation of retained native objects extractor. class NativeObjectsExplorer { public: - NativeObjectsExplorer(HeapSnapshot* snapshot, + NativeObjectsExplorer(HeapProfiler* profiler, + HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress); virtual ~NativeObjectsExplorer(); void AddRootEntries(SnapshotFiller* filler); @@ -527,10 +556,12 @@ class NativeObjectsExplorer { class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { public: - HeapSnapshotGenerator(HeapSnapshot* snapshot, + HeapSnapshotGenerator(HeapProfiler* profiler, + HeapSnapshot* snapshot, v8::ActivityControl* control, v8::HeapProfiler::ObjectNameResolver* resolver, - Heap* heap); + Heap* heap, + SnapshotFiller* filler = NULL); bool GenerateSnapshot(); private: @@ -549,6 +580,7 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { int progress_counter_; int progress_total_; Heap* heap_; + SnapshotFiller* filler_; DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); }; diff --git a/src/v8/src/profile-generator-inl.h b/src/v8/src/profile-generator-inl.h index b27a009..f7c36b9 100644 --- a/src/v8/src/profile-generator-inl.h +++ b/src/v8/src/profile-generator-inl.h @@ -16,7 +16,8 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, const char* resource_name, int line_number, int column_number, - JITLineInfoTable* line_info) + JITLineInfoTable* line_info, + Address instruction_start) : tag_(tag), builtin_id_(Builtins::builtin_count), name_prefix_(name_prefix), @@ -28,7 +29,8 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, script_id_(v8::UnboundScript::kNoScriptId), no_frame_ranges_(NULL), bailout_reason_(kEmptyBailoutReason), - line_info_(line_info) { } + line_info_(line_info), + instruction_start_(instruction_start) { } bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) { diff --git a/src/v8/src/profile-generator.cc b/src/v8/src/profile-generator.cc index 3f79c6a..61743a5 100644 --- a/src/v8/src/profile-generator.cc +++ b/src/v8/src/profile-generator.cc @@ -132,6 +132,31 @@ HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) { } +JITLineInfoTable::JITLineInfoTable() {} + + +JITLineInfoTable::~JITLineInfoTable() {} + + +void JITLineInfoTable::SetPosition(int pc_offset, int line) { + DCHECK(pc_offset >= 0); + DCHECK(line > 0); // The 1-based number of the source line. + if (GetSourceLineNumber(pc_offset) != line) { + pc_offset_map_.insert(std::make_pair(pc_offset, line)); + } +} + + +int JITLineInfoTable::GetSourceLineNumber(int pc_offset) const { + PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset); + if (it == pc_offset_map_.end()) { + if (pc_offset_map_.empty()) return v8::CpuProfileNode::kNoLineNumberInfo; + return (--pc_offset_map_.end())->second; + } + return it->second; +} + + const char* const CodeEntry::kEmptyNamePrefix = ""; const char* const CodeEntry::kEmptyResourceName = ""; const char* const CodeEntry::kEmptyBailoutReason = ""; @@ -183,7 +208,7 @@ void CodeEntry::SetBuiltinId(Builtins::Name id) { int CodeEntry::GetSourceLine(int pc_offset) const { - if (line_info_ && !line_info_->Empty()) { + if (line_info_ && !line_info_->empty()) { return line_info_->GetSourceLineNumber(pc_offset); } return v8::CpuProfileNode::kNoLineNumberInfo; @@ -216,7 +241,7 @@ void ProfileNode::IncrementLineTicks(int src_line) { // Increment a hit counter of a certain source line. // Add a new source line if not found. HashMap::Entry* e = - line_ticks_.Lookup(reinterpret_cast(src_line), src_line, true); + line_ticks_.Lookup(reinterpret_cast(src_line), src_line, true); DCHECK(e); e->value = reinterpret_cast(reinterpret_cast(e->value) + 1); } @@ -228,7 +253,7 @@ bool ProfileNode::GetLineTicks(v8::CpuProfileNode::LineTick* entries, unsigned line_count = line_ticks_.occupancy(); - if (line_count == 0) return false; + if (line_count == 0) return true; if (length < line_count) return false; v8::CpuProfileNode::LineTick* entry = entries; @@ -591,14 +616,16 @@ CodeEntry* CpuProfilesCollection::NewCodeEntry( const char* resource_name, int line_number, int column_number, - JITLineInfoTable* line_info) { + JITLineInfoTable* line_info, + Address instruction_start) { CodeEntry* code_entry = new CodeEntry(tag, name, name_prefix, resource_name, line_number, column_number, - line_info); + line_info, + instruction_start); code_entries_.Add(code_entry); return code_entry; } @@ -641,8 +668,9 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { // the same JS function. The line number information associated with // the latest version of generated code is used to find a source line number // for a JS function. Then, the detected source line is passed to - // ProfileNode to accumulate the samples. + // ProfileNode to increase the tick count for this source line. int src_line = v8::CpuProfileNode::kNoLineNumberInfo; + bool src_line_not_found = true; if (sample.pc != NULL) { if (sample.has_external_callback && sample.state == EXTERNAL && @@ -660,9 +688,8 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { // frame. Check for this case and just skip such samples. if (pc_entry) { List* ranges = pc_entry->no_frame_ranges(); - Code* code = Code::cast(HeapObject::FromAddress(start)); - int pc_offset = static_cast(sample.pc - code->instruction_start()); - src_line = pc_entry->GetSourceLine(pc_offset); + int pc_offset = + static_cast(sample.pc - pc_entry->instruction_start()); if (ranges) { for (int i = 0; i < ranges->length(); i++) { OffsetRange& range = ranges->at(i); @@ -671,6 +698,11 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { } } } + src_line = pc_entry->GetSourceLine(pc_offset); + if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) { + src_line = pc_entry->line_number(); + } + src_line_not_found = false; *entry++ = pc_entry; if (pc_entry->builtin_id() == Builtins::kFunctionCall || @@ -687,8 +719,6 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { } } - bool src_line_not_found = src_line == v8::CpuProfileNode::kNoLineNumberInfo; - for (const Address* stack_pos = sample.stack, *stack_end = stack_pos + sample.frames_count; stack_pos != stack_end; @@ -697,11 +727,10 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { *entry = code_map_.FindEntry(*stack_pos, &start); // Skip unresolved frames (e.g. internal frame) and get source line of - // the JS caller. + // the first JS caller. if (src_line_not_found && *entry) { - Code* code = Code::cast(HeapObject::FromAddress(start)); int pc_offset = - static_cast(*stack_pos - code->instruction_start()); + static_cast(*stack_pos - (*entry)->instruction_start()); src_line = (*entry)->GetSourceLine(pc_offset); if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) { src_line = (*entry)->line_number(); diff --git a/src/v8/src/profile-generator.h b/src/v8/src/profile-generator.h index f973eb2..897ce07 100644 --- a/src/v8/src/profile-generator.h +++ b/src/v8/src/profile-generator.h @@ -49,24 +49,13 @@ class StringsStorage { // the source line. class JITLineInfoTable : public Malloced { public: - JITLineInfoTable() {} - ~JITLineInfoTable() {} + JITLineInfoTable(); + ~JITLineInfoTable(); - void SetPosition(int pc_offset, int line) { - DCHECK(pc_offset >= 0); - DCHECK(line > 0); // The 1-based number of the source line. - pc_offset_map_.insert(std::make_pair(pc_offset, line)); - } + void SetPosition(int pc_offset, int line); + int GetSourceLineNumber(int pc_offset) const; - int GetSourceLineNumber(int pc_offset) const { - PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset); - if (it == pc_offset_map_.end()) { - return v8::CpuProfileNode::kNoLineNumberInfo; - } - return it->second; - } - - bool Empty() const { return pc_offset_map_.empty(); } + bool empty() const { return pc_offset_map_.empty(); } private: // pc_offset -> source line @@ -84,7 +73,8 @@ class CodeEntry { const char* resource_name = CodeEntry::kEmptyResourceName, int line_number = v8::CpuProfileNode::kNoLineNumberInfo, int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, - JITLineInfoTable* line_info = NULL); + JITLineInfoTable* line_info = NULL, + Address instruction_start = NULL); ~CodeEntry(); bool is_js_function() const { return is_js_function_tag(tag_); } @@ -118,6 +108,8 @@ class CodeEntry { int GetSourceLine(int pc_offset) const; + Address instruction_start() const { return instruction_start_; } + static const char* const kEmptyNamePrefix; static const char* const kEmptyResourceName; static const char* const kEmptyBailoutReason; @@ -135,6 +127,7 @@ class CodeEntry { List* no_frame_ranges_; const char* bailout_reason_; JITLineInfoTable* line_info_; + Address instruction_start_; DISALLOW_COPY_AND_ASSIGN(CodeEntry); }; @@ -329,7 +322,8 @@ class CpuProfilesCollection { const char* resource_name = CodeEntry::kEmptyResourceName, int line_number = v8::CpuProfileNode::kNoLineNumberInfo, int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, - JITLineInfoTable* line_info = NULL); + JITLineInfoTable* line_info = NULL, + Address instruction_start = NULL); // Called from profile generator thread. void AddPathToCurrentProfiles(base::TimeTicks timestamp, diff --git a/src/v8/src/xdk-allocation.cc b/src/v8/src/xdk-allocation.cc new file mode 100644 index 0000000..311a592 --- /dev/null +++ b/src/v8/src/xdk-allocation.cc @@ -0,0 +1,539 @@ +// Copyright 2014 the V8 project 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 +#include + +#include "src/v8.h" + +#include "src/xdk-allocation.h" + +#include "frames-inl.h" +#include "src/xdk-utils.h" + +namespace v8 { +namespace internal { + +XDKAllocationTracker::XDKAllocationTracker(HeapProfiler* heap_profiler, + HeapObjectsMap *ids, + StringsStorage *names, + int stackDepth, + bool collectRetention, + bool strict_collection) + : heap_profiler_(heap_profiler), + ids_(ids), + names_(names), + stackDepth_(stackDepth), + collectRetention_(collectRetention), + strict_collection_(strict_collection) { + references_ = new References(); + aggregated_chunks_ = new AggregatedChunks(); + runtime_info_ = new RuntimeInfo(aggregated_chunks_); + symbols_ = new SymbolsStorage(ids_->heap(), names_); + collectedStacks_ = new ShadowStack(); + classNames_ = new ClassNames(names_); + + List stack_ooc; + stack_ooc.Add(symbols_->registerSymInfo(1, "OutOfContext", "NoSource", + 0, 0)); + outOfContextFrame_ = collectedStacks_->registerStack(stack_ooc); + + List stack_abc; + stack_abc.Add(symbols_->registerSymInfo(2, "AllocatedBeforeCollection", + "NoSource", 0, 0)); + AllocatedBeforeCollectionFrame_ = collectedStacks_->registerStack(stack_abc); + + runtime_info_->InitABCFrame(AllocatedBeforeCollectionFrame_); + + baseTime_ = v8::base::Time::Now(); + latest_delta_ = 0; +} + + +XDKAllocationTracker::~XDKAllocationTracker() { + delete collectedStacks_; + delete classNames_; + delete aggregated_chunks_; + delete runtime_info_; + delete symbols_; + delete references_; +} + + +// Heap profiler regularly takes time for storing when object was allocated, +// deallocated, when object's retention snapshot was taken, etc +unsigned int XDKAllocationTracker::GetTimeDelta() { + v8::base::TimeDelta td = v8::base::Time::Now() - baseTime_; + return static_cast(td.InMilliseconds()); +} + + +void XDKAllocationTracker::OnAlloc(Address addr, int size) { + DisallowHeapAllocation no_alloc; + Heap *heap = ids_->heap(); + + // below call saves from the crash during StackTraceFrameIterator creation + // Mark the new block as FreeSpace to make sure the heap is iterable + // while we are capturing stack trace. + FreeListNode::FromAddress(addr)->set_size(heap, size); + + Isolate *isolate = heap->isolate(); + StackTraceFrameIterator it(isolate); + List stack; + + // TODO(amalyshe): checking of isolate->handle_scope_data()->level is quite + // artificial. need to understand when we can have such behaviour + // if level == 0 we will crash in getting of source info + while (isolate->handle_scope_data()->level && !it.done() && + stack.length() < stackDepth_) { + JavaScriptFrame *frame = it.frame(); + if (!frame->function()) + break; + SharedFunctionInfo *shared = frame->function()->shared(); + if (!shared) + break; + + stack.Add(symbols_->FindOrRegisterFrame(frame)); + it.Advance(); + } + + unsigned sid; + if (!stack.is_empty()) { + sid = collectedStacks_->registerStack(stack); + } else { + sid = outOfContextFrame_; + } + + latest_delta_ = GetTimeDelta(); + + PostCollectedInfo* info = runtime_info_->AddPostCollectedInfo(addr, + latest_delta_); + info->size_ = size; + info->timeStamp_ = latest_delta_; + info->stackId_ = sid; + info->className_ = (unsigned int)-1; + info->dirty_ = false; +} + + +void XDKAllocationTracker::OnMove(Address from, Address to, int size) { + DisallowHeapAllocation no_alloc; + // look for the prev address + PostCollectedInfo* info_from = runtime_info_->FindPostCollectedInfo(from); + if (info_from == NULL) { + return; + } + + runtime_info_->AddPostCollectedInfo(to, latest_delta_, info_from); + runtime_info_->RemoveInfo(from); +} + + +HeapEventXDK* XDKAllocationTracker::stopTracking() { + std::string symbols, types, frames, chunks, retentions; + SerializeChunk(&symbols, &types, &frames, &chunks, &retentions); + CollectFreedObjects(true); + std::string symbolsA, typesA, framesA, chunksA, retentionsA; + SerializeChunk(&symbolsA, &typesA, &framesA, &chunksA, &retentionsA, true); + + // TODO(amalyshe): check who releases this object - new HeapEventXDK + return (new HeapEventXDK(GetTimeDelta(), symbols+symbolsA, types+typesA, + frames+framesA, chunks+chunksA, "")); +} + + +void XDKAllocationTracker::CollectFreedObjects(bool bAll, bool initPreCollect) { + clearIndividualReteiners(); + if (collectRetention_) { + XDKSnapshotFiller filler(ids_, names_, this); + HeapSnapshotGenerator generator(heap_profiler_, NULL, NULL, NULL, + ids_->heap(), &filler); + generator.GenerateSnapshot(); + } + + Heap *heap = ids_->heap(); + if (!heap) { + return; + } + + unsigned int ts = GetTimeDelta(); + if (bAll) { + ts += RETAINED_DELTA; + } + + // CDT heap profiler calls CollectAllGarbage twice because after the first + // pass there are weak retained object not collected, but due to perf issues + // and because we do garbage collection regularly, we leave here only one call + // only for strict collection like in test where we need to make sure that + // object is definitely collected, we collect twice + heap->CollectAllGarbage( + Heap::kMakeHeapIterableMask, + "XDKAllocationTracker::CollectFreedObjects"); + if (strict_collection_) { + heap->CollectAllGarbage( + Heap::kMakeHeapIterableMask, + "XDKAllocationTracker::CollectFreedObjects"); + } + std::map individualReteiners; + + // TODO(amalyshe): check what DisallowHeapAllocation no_alloc means because in + // standalone v8 this part is crashed if DisallowHeapAllocation is defined + // DisallowHeapAllocation no_alloc; + if (!bAll) { + HeapIterator iterator(heap); + HeapObject* obj = iterator.next(); + for (; + obj != NULL; + obj = iterator.next()) { + Address addr = obj->address(); + + PostCollectedInfo* info = runtime_info_->FindPostCollectedInfo(addr); + if (!info) { + // if we don't find info, we consider it as pre collection allocated + // object. need to add to the full picture for retentions + if (initPreCollect) { + info = runtime_info_->AddPreCollectionInfo(addr, obj->Size()); + } + } + + if (info) { + info->dirty_ = true; + } + // check of the class name and its initialization + if ((info && info->className_ == (unsigned)-1) || !info) { + InitClassName(addr, ts, obj->Size()); + } + } + } + + if (collectRetention_) { + std::map::const_iterator citir = + individualReteiners_.begin(); + while (citir != individualReteiners_.end()) { + PostCollectedInfo* infoChild = + runtime_info_->FindPostCollectedInfo(citir->first); + if (infoChild) { + RefId rfId; + rfId.stackId_ = infoChild->stackId_; + rfId.classId_ = infoChild->className_; + + references_->addReference(rfId, citir->second, infoChild->timeStamp_); + } + citir++; + } + } + + runtime_info_->CollectGarbaged(ts); +} + + +void XDKAllocationTracker::SerializeChunk(std::string* symbols, + std::string* types, + std::string* frames, + std::string* chunks, + std::string* retentions, + bool final) { + if (final) { + *symbols = symbols_->SerializeChunk(); + *types = classNames_->SerializeChunk(); + } + *frames = collectedStacks_->SerializeChunk(); + *chunks = aggregated_chunks_->SerializeChunk(); + + *retentions = references_->serialize(); + std::stringstream retentionsT; + retentionsT << GetTimeDelta() << std::endl << retentions->c_str(); + *retentions = retentionsT.str(); + references_->clear(); +} + + +OutputStream::WriteResult XDKAllocationTracker::SendChunk( + OutputStream* stream) { + // go over all aggregated_ and send data to the stream + std::string symbols, types, frames, chunks, retentions; + SerializeChunk(&symbols, &types, &frames, &chunks, &retentions); + + OutputStream::WriteResult ret = stream->WriteHeapXDKChunk( + symbols.c_str(), symbols.length(), + frames.c_str(), frames.length(), + types.c_str(), types.length(), + chunks.c_str(), chunks.length(), + retentions.c_str(), retentions.length()); + return ret; +} + + +unsigned XDKAllocationTracker::GetTraceNodeId(Address address) { + PostCollectedInfo* info = runtime_info_->FindPostCollectedInfo(address); + if (info) { + return info->stackId_; + } else { + return AllocatedBeforeCollectionFrame_; + } +} + + +void XDKAllocationTracker::clearIndividualReteiners() { + individualReteiners_.clear(); +} + + +std::map* XDKAllocationTracker::GetIndividualReteiners() { + return &individualReteiners_; +} + + +unsigned XDKAllocationTracker::FindClassName(Address address) { + PostCollectedInfo* info = runtime_info_->FindPostCollectedInfo(address); + if (info) { + return info->className_; + } else { + return (unsigned)-1; + } +} + + +unsigned XDKAllocationTracker::InitClassName(Address address, unsigned ts, + unsigned size) { + unsigned id = -2; + PostCollectedInfo* info = runtime_info_->FindPostCollectedInfo(address); + if (!info) { + info = runtime_info_->AddPostCollectedInfo(address, ts); + info->className_ = -1; + info->stackId_ = outOfContextFrame_; + info->timeStamp_ = ts; + info->size_ = size; + } + if (info->className_ == (unsigned)-1) { + String* str = classNames_->GetConstructorName(address); + if (str) { + // get const char*, it's safe because pointer will be retained in the + // name_ until it is destroyed + id = classNames_->registerName(names_->GetName(str)); + } + } + info->className_ = id; + return id; +} + + +unsigned XDKAllocationTracker::FindOrInitClassName(Address address, + unsigned ts) { + unsigned id = FindClassName(address); + if (id == (unsigned)-1) { + // TODO(amalyshe) check if 0 size here is appropriate + id = InitClassName(address, ts, 0); + } + return id; +} + + +// ----------------------------------------------------------------------------- +// this is almost a copy and duplication of +// V8HeapExplorer::AddEntry. refactoring is impossible because +// heap-snapshot-generator rely on it's structure which is not fully suitable +// for us. +HeapEntry* XDKSnapshotFiller::AddEntry(HeapThing ptr, + HeapEntriesAllocator* allocator) { + HeapObject* object = reinterpret_cast(ptr); + if (object->IsJSFunction()) { + JSFunction* func = JSFunction::cast(object); + SharedFunctionInfo* shared = func->shared(); + const char* name = shared->bound() ? "native_bind" : + names_->GetName(String::cast(shared->name())); + return AddEntry(ptr, object, HeapEntry::kClosure, name); + } else if (object->IsJSRegExp()) { + JSRegExp* re = JSRegExp::cast(object); + return AddEntry(ptr, object, + HeapEntry::kRegExp, + names_->GetName(re->Pattern())); + } else if (object->IsJSObject()) { + return AddEntry(ptr, object, HeapEntry::kObject, ""); + } else if (object->IsString()) { + String* string = String::cast(object); + if (string->IsConsString()) + return AddEntry(ptr, object, + HeapEntry::kConsString, + "(concatenated string)"); + if (string->IsSlicedString()) + return AddEntry(ptr, object, + HeapEntry::kSlicedString, + "(sliced string)"); + return AddEntry(ptr, object, + HeapEntry::kString, + names_->GetName(String::cast(object))); + } else if (object->IsSymbol()) { + return AddEntry(ptr, object, HeapEntry::kSymbol, "symbol"); + } else if (object->IsCode()) { + return AddEntry(ptr, object, HeapEntry::kCode, ""); + } else if (object->IsSharedFunctionInfo()) { + String* name = String::cast(SharedFunctionInfo::cast(object)->name()); + return AddEntry(ptr, object, + HeapEntry::kCode, + names_->GetName(name)); + } else if (object->IsScript()) { + Object* name = Script::cast(object)->name(); + return AddEntry(ptr, object, + HeapEntry::kCode, + name->IsString() + ? names_->GetName(String::cast(name)) + : ""); + } else if (object->IsNativeContext()) { + return AddEntry(ptr, object, HeapEntry::kHidden, "system / NativeContext"); + } else if (object->IsContext()) { + return AddEntry(ptr, object, HeapEntry::kObject, "system / Context"); + } else if (object->IsFixedArray() || + object->IsFixedDoubleArray() || + object->IsByteArray() || + object->IsExternalArray()) { + return AddEntry(ptr, object, HeapEntry::kArray, ""); + } else if (object->IsHeapNumber()) { + return AddEntry(ptr, object, HeapEntry::kHeapNumber, "number"); + } + + return AddEntry(ptr, object, HeapEntry::kHidden, "system / NOT SUPORTED YET"); +} + + +HeapEntry* XDKSnapshotFiller::AddEntry(HeapThing thing, + HeapObject* object, + HeapEntry::Type type, + const char* name) { + Address address = object->address(); + unsigned trace_node_id = 0; + trace_node_id = allocation_tracker_->GetTraceNodeId(address); + + // cannot store pointer in the map because List reallcoates content regularly + // and the only one way to find the entry - by index. so, index is cached in + // the map + // TODO(amalyshe): need to reuse type. it seems it is important + HeapEntry entry(NULL, &heap_entries_list_, type, name, 0, 0, + trace_node_id); + heap_entries_list_.Add(entry); + HeapEntry* pEntry = &heap_entries_list_.last(); + + HashMap::Entry* cache_entry = heap_entries_.Lookup(thing, Hash(thing), true); + DCHECK(cache_entry->value == NULL); + int index = pEntry->index(); + cache_entry->value = reinterpret_cast(static_cast(index)); + + // TODO(amalyshe): it seems this storage might be optimized + HashMap::Entry* address_entry = index_to_address_.Lookup( + reinterpret_cast(index+1), HashInt(index+1), true); + address_entry->value = reinterpret_cast(address); + + return pEntry; +} + + +HeapEntry* XDKSnapshotFiller::FindEntry(HeapThing thing) { + HashMap::Entry* cache_entry = heap_entries_.Lookup(thing, Hash(thing), false); + if (cache_entry == NULL) return NULL; + return &heap_entries_list_[static_cast( + reinterpret_cast(cache_entry->value))]; +} + + +HeapEntry* XDKSnapshotFiller::FindOrAddEntry(HeapThing ptr, + HeapEntriesAllocator* allocator) { + HeapEntry* entry = FindEntry(ptr); + return entry != NULL ? entry : AddEntry(ptr, allocator); +} + + +void XDKSnapshotFiller::SetIndexedReference(HeapGraphEdge::Type type, + int parent, + int index, + HeapEntry* child_entry) { + if (child_entry->trace_node_id() < 3) { + return; + } + HashMap::Entry* address_entry_child = index_to_address_.Lookup( + reinterpret_cast(child_entry->index()+1), + HashInt(child_entry->index()+1), false); + DCHECK(address_entry_child != NULL); + if (!address_entry_child) { + return; + } + + Address child_addr = reinterpret_cast
(address_entry_child->value); + + std::map* individualReteiners = + allocation_tracker_->GetIndividualReteiners(); + // get the parent's address, constructor name and form the RefId + HashMap::Entry* address_entry = index_to_address_.Lookup( + reinterpret_cast(parent+1), HashInt(parent+1), false); + DCHECK(address_entry != NULL); + if (!address_entry) { + return; + } + HeapEntry* parent_entry = &(heap_entries_list_[parent]); + Address parent_addr = reinterpret_cast
(address_entry->value); + RefId parent_ref_id; + parent_ref_id.stackId_ = parent_entry->trace_node_id(); + parent_ref_id.classId_ = + allocation_tracker_->FindOrInitClassName(parent_addr, 0); + + std::stringstream str; + str << index << " element in Array"; + parent_ref_id.field_ = str.str(); + + (*individualReteiners)[child_addr].references_.insert(parent_ref_id); +} + + +void XDKSnapshotFiller::SetIndexedAutoIndexReference(HeapGraphEdge::Type type, + int parent, + HeapEntry* child_entry) { +} + + +void XDKSnapshotFiller::SetNamedReference(HeapGraphEdge::Type type, + int parent, + const char* reference_name, + HeapEntry* child_entry) { + if (child_entry->trace_node_id() < 3) { + return; + } + + std::map* individualReteiners = + allocation_tracker_->GetIndividualReteiners(); + // get the parent's address, constructor name and form the RefId + HashMap::Entry* address_entry = index_to_address_.Lookup( + reinterpret_cast(parent+1), HashInt(parent+1), false); + DCHECK(address_entry != NULL); + if (!address_entry) { + return; + } + HeapEntry* parent_entry = &(heap_entries_list_[parent]); + Address parent_addr = reinterpret_cast
(address_entry->value); + RefId parent_ref_id; + parent_ref_id.stackId_ = parent_entry->trace_node_id(); + // TODO(amalyshe): need to get access to classNames_ + parent_ref_id.classId_ = + allocation_tracker_->FindOrInitClassName(parent_addr, 0); + parent_ref_id.field_ = reference_name; + + HashMap::Entry* address_entry_child = index_to_address_.Lookup( + reinterpret_cast(child_entry->index()+1), + HashInt(child_entry->index()+1), false); + DCHECK(address_entry_child != NULL); + if (!address_entry_child) { + return; + } + Address child_addr = reinterpret_cast
(address_entry_child->value); + + (*individualReteiners)[child_addr].references_.insert(parent_ref_id); +} + + +void XDKSnapshotFiller::SetNamedAutoIndexReference(HeapGraphEdge::Type type, + int parent, + HeapEntry* child_entry) { +} + + +} +} // namespace v8::internal diff --git a/src/v8/src/xdk-allocation.h b/src/v8/src/xdk-allocation.h new file mode 100644 index 0000000..79384e9 --- /dev/null +++ b/src/v8/src/xdk-allocation.h @@ -0,0 +1,168 @@ +// Copyright 2014 the V8 project 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 V8_XDK_ALLOCATION_H_ +#define V8_XDK_ALLOCATION_H_ + +#include +#include +#include "src/base/platform/time.h" + +namespace v8 { +namespace internal { + +class HeapObjectsMap; +class HeapEventXDK; +class ClassNames; +class ShadowStack; +class SymbolsStorage; +class AggregatedChunks; +class RuntimeInfo; +class References; +class RefSet; + + +class XDKSnapshotFiller: public SnapshotFiller { + public: + explicit XDKSnapshotFiller(HeapObjectsMap* heap_object_map, + StringsStorage* names, + XDKAllocationTracker* allocation_tracker) + : names_(names), + heap_object_map_(heap_object_map), + allocation_tracker_(allocation_tracker), + heap_entries_(HashMap::PointersMatch), + index_to_address_(HashMap::PointersMatch) {} + virtual ~XDKSnapshotFiller() {} + + HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator); + HeapEntry* FindEntry(HeapThing thing); + HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator); + void SetIndexedReference(HeapGraphEdge::Type type, + int parent, + int index, + HeapEntry* child_entry); + void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, + int parent, + HeapEntry* child_entry); + void SetNamedReference(HeapGraphEdge::Type type, + int parent, + const char* reference_name, + HeapEntry* child_entry); + void SetNamedAutoIndexReference(HeapGraphEdge::Type type, + int parent, + HeapEntry* child_entry); + + private: + StringsStorage* names_; + HeapObjectsMap* heap_object_map_; + XDKAllocationTracker* allocation_tracker_; + HashMap heap_entries_; + HashMap index_to_address_; + + + List heap_entries_list_; + + HeapEntry* AddEntry(HeapThing thing, + HeapObject* object, + HeapEntry::Type type, + const char* name); + + static uint32_t Hash(HeapThing thing) { + return ComputeIntegerHash( + static_cast(reinterpret_cast(thing)), + v8::internal::kZeroHashSeed); + } + static uint32_t HashInt(int key) { + return ComputeIntegerHash(key, v8::internal::kZeroHashSeed); + } +}; + + +class XDKAllocationTracker { + public: + XDKAllocationTracker(HeapProfiler* heap_profiler, + HeapObjectsMap* ids, + StringsStorage* names, + int stackDepth, + bool collectRetention, + bool strict_collection); + ~XDKAllocationTracker(); + + void OnAlloc(Address addr, int size); + void OnMove(Address from, Address to, int size); + void CollectFreedObjects(bool bAll = false, bool initPreCollect = false); + HeapEventXDK* stopTracking(); + OutputStream::WriteResult SendChunk(OutputStream* stream); + unsigned GetTraceNodeId(Address address); + void clearIndividualReteiners(); + std::map* GetIndividualReteiners(); + + unsigned FindOrInitClassName(Address address, unsigned ts); + + private: + static const int RETAINED_DELTA = 1000; + + // external object + HeapProfiler* heap_profiler_; + HeapObjectsMap* ids_; + StringsStorage* names_; + + AggregatedChunks* aggregated_chunks_; + RuntimeInfo* runtime_info_; + void SerializeChunk(std::string* symbols, std::string* types, + std::string* frames, std::string* chunks, + std::string* retentions, bool final = false); + + unsigned FindClassName(Address address); + unsigned InitClassName(Address address, unsigned ts, unsigned size); + + SymbolsStorage* symbols_; + ShadowStack* collectedStacks_; + ClassNames* classNames_; + + unsigned outOfContextFrame_; + unsigned AllocatedBeforeCollectionFrame_; + + v8::base::Time baseTime_; + unsigned latest_delta_; + unsigned int GetTimeDelta(); + + int stackDepth_; + bool collectRetention_; + bool strict_collection_; + References* references_; + std::map individualReteiners_; +}; + + +class HeapEventXDK { + public: + HeapEventXDK(unsigned int duration, + const std::string& symbols, const std::string& types, + const std::string& frames, const std::string& chunks, + const std::string& retentions) : + symbols_(symbols), types_(types), frames_(frames), chunks_(chunks), + duration_(duration), retentions_(retentions) { + } + + unsigned int duration() const {return duration_; } + const char* symbols() const { return symbols_.c_str(); } + const char* types() const { return types_.c_str(); } + const char* frames() const { return frames_.c_str(); } + const char* chunks() const { return chunks_.c_str(); } + const char* retentions() const { return retentions_.c_str(); } + + private: + std::string symbols_; + std::string types_; + std::string frames_; + std::string chunks_; + unsigned int duration_; + std::string retentions_; + DISALLOW_COPY_AND_ASSIGN(HeapEventXDK); +}; + +} } // namespace v8::internal + +#endif // V8_XDK_ALLOCATION_H_ diff --git a/src/v8/src/xdk-utils.cc b/src/v8/src/xdk-utils.cc new file mode 100644 index 0000000..b17eb95 --- /dev/null +++ b/src/v8/src/xdk-utils.cc @@ -0,0 +1,541 @@ +// Copyright 2014 the V8 project 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 "src/v8.h" + +#include "src/frames-inl.h" +#include "src/xdk-utils.h" + +namespace v8 { +namespace internal { + +static bool AddressesMatch(void* key1, void* key2) { + return key1 == key2; +} + + +static uint32_t CharAddressHash(char* addr) { + return ComputeIntegerHash(static_cast( + reinterpret_cast(addr)), + v8::internal::kZeroHashSeed); +} + + +static uint32_t AddressHash(Address addr) { + return ComputeIntegerHash(static_cast( + reinterpret_cast(addr)), + v8::internal::kZeroHashSeed); +} + + +ClassNames::ClassNames(StringsStorage* names) + : counter_(0), + char_to_idx_(AddressesMatch), + names_(names) { +} + + +unsigned ClassNames::registerName(const char* name) { + // since const char is retained outside and cannot be moved, we rely on this + // and just compare the pointers. It should be enough for the strings from the + // only one StringStorage + unsigned counter; + HashMap::Entry* entry = char_to_idx_.Lookup(const_cast(name), + CharAddressHash(const_cast(name)), + true); + if (entry->value == NULL) { + counter = ++counter_; + entry->value = reinterpret_cast(counter); + } else { + counter = static_cast(reinterpret_cast(entry->value)); + } + return counter; +} + + +std::string ClassNames::SerializeChunk() { + std::stringstream serialized; + for (HashMap::Entry* p = char_to_idx_.Start(); p != NULL; + p = char_to_idx_.Next(p)) { + serialized << static_cast( + reinterpret_cast(p->value)) << "," << + reinterpret_cast(p->key) << std::endl; + } + + return serialized.str(); +} + + +String* ClassNames::GetConstructorName(Address address) { + HeapObject *heap_object = HeapObject::FromAddress(address); + bool is_js_object = heap_object->IsJSObject(); + if (!is_js_object) { + // TODO(amalyshe): look for another function for taking the class name + // String* constructor_name = object2->constructor_name(); + return NULL; + } + JSObject* object = JSObject::cast(heap_object); + Heap* heap = object->GetHeap(); + if (object->IsJSFunction()) return heap->closure_string(); + return object->constructor_name(); +} + + +// ----------------------------------------------------------------------------- +ShadowStack::ShadowStack() { + last_index_ = 1; + serializedCounter_ = last_index_; + root_.index_ = 0; + root_.parent_ = NULL; + root_.callsite_ = 0; +} + + +ShadowStack::~ShadowStack() { + // erasing all objects from the current container + std::map::iterator eit = allNodes_.begin(); + while (eit != allNodes_.end()) { + delete eit->second; + eit++; + } +} + + +unsigned ShadowStack::registerStack(const List& shadow_stack_) { + // look for the latest node + CallTree* pNode = &root_; + // go over all entries and add them to the tree if they are not in the map + int i, j; + for (i = shadow_stack_.length()-1; i != -1; i--) { + std::map::iterator it = + pNode->children_.find(shadow_stack_[i]); + if (it == pNode->children_.end()) + break; + pNode = it->second; + } + // verification if we need to add something or not + for (j = i; j != -1; j--) { + CallTree* pNodeTmp = new CallTree; + pNodeTmp->index_ = last_index_++; + pNodeTmp->parent_ = pNode; + pNodeTmp->callsite_ = shadow_stack_[j]; + pNode->children_[shadow_stack_[j]] = pNodeTmp; + allNodes_[pNodeTmp->index_] = pNodeTmp; + pNode = pNodeTmp; + } + return pNode->index_; +} + + +std::string ShadowStack::SerializeChunk() { + std::stringstream str; + std::map::iterator it = + allNodes_.find(serializedCounter_); + while (it!= allNodes_.end()) { + str << it->first << "," << it->second->callsite_ << "," << + it->second->parent_->index_ << std::endl; + it++; + } + + serializedCounter_ = last_index_; + return str.str(); +} + + +// ----------------------------------------------------------------------------- +static bool SymInfoMatch(void* key1, void* key2) { + SymInfoKey* key_c1 = reinterpret_cast(key1); + SymInfoKey* key_c2 = reinterpret_cast(key2); + return *key_c1 == *key_c2; +} + + +static uint32_t SymInfoHash(const SymInfoKey& key) { + uint32_t hash = 0; + // take the low 16 bits of function_id_ + hash |= (key.function_id_ & 0xffff); + // take the low 8 bits of line_ and column_ and init highest bits + hash |= ((key.line_ & 0xff) << 16); + hash |= ((key.column_ & 0xff) << 14); + + return hash; +} + + +struct SymbolCached { + unsigned int symbol_id_; + uintptr_t function_; +}; + + +SymbolsStorage::SymbolsStorage(Heap* heap, StringsStorage* names) : + symbols_(SymInfoMatch), + curSym_(1), + sym_info_hash_(AddressesMatch), + heap_(heap), + names_(names) { + reserved_key_ = new SymInfoKey(); +} + + +SymbolsStorage::~SymbolsStorage() { + // go over map and delete all keys and values + for (HashMap::Entry* p = symbols_.Start(); p != NULL; p = symbols_.Next(p)) { + delete reinterpret_cast(p->value); + delete reinterpret_cast(p->key); + } + delete reserved_key_; +} + + +unsigned SymbolsStorage::registerSymInfo(size_t functionId, + std::string functionName, + std::string sourceName, + unsigned line, + unsigned column) { + if (sourceName.empty()) { + sourceName = "unknown"; + } + + reserved_key_->function_id_ = functionId; + reserved_key_->line_ = line; + reserved_key_->column_ = column; + + HashMap::Entry* entry = symbols_.Lookup(reserved_key_, + SymInfoHash(*reserved_key_), true); + if (entry->value) { + return reinterpret_cast(entry->value)->symId_; + } + + // else initialize by new one + SymInfoValue* value = new SymInfoValue; + value->symId_ = curSym_++; + value->funcName_ = functionName; + value->sourceFile_ = sourceName; + entry->value = value; + + // compensation for registered one + reserved_key_ = new SymInfoKey(); + + return value->symId_; +} + + +std::string SymbolsStorage::SerializeChunk() { + std::stringstream serialized; + for (HashMap::Entry* p = symbols_.Start(); p != NULL; p = symbols_.Next(p)) { + SymInfoValue* v = reinterpret_cast(p->value); + SymInfoKey* k = reinterpret_cast(p->key); + serialized << v->symId_ << "," << k->function_id_ << "," << + v->funcName_ << "," << v->sourceFile_ << "," << + k->line_ << "," << k->column_ << std::endl; + } + + return serialized.str(); +} + + +unsigned SymbolsStorage::FindOrRegisterFrame(JavaScriptFrame* frame) { + SharedFunctionInfo *shared = frame->function()->shared(); + DCHECK(shared); + Isolate *isolate = heap_->isolate(); + + Address pc = frame->pc(); + unsigned int symbolId = 0; + + // We don't rely on the address only. Since this is JIT based language, + // the address might be occupied by other function + // thus we are verifying if the same function takes this place + // before we take symbol info from the cache + HashMap::Entry* sym_entry = sym_info_hash_.Lookup( + reinterpret_cast(pc), AddressHash(pc), true); + if (sym_entry->value == NULL || + (reinterpret_cast(sym_entry->value)->function_ != + reinterpret_cast(frame->function()))) { + if (sym_entry->value) { + delete reinterpret_cast(sym_entry->value); + } + + const char *s = names_->GetFunctionName(shared->DebugName()); + // trying to get the source name and line# + Code *code = Code::cast(isolate->FindCodeObject(pc)); + if (code) { + int source_pos = code->SourcePosition(pc); + Object *maybe_script = shared->script(); + if (maybe_script && maybe_script->IsScript()) { + Handle + + +

Create window by click

+ + diff --git a/src/xwalk/runtime/android/sample/assets/create_window_2.html b/src/xwalk/runtime/android/sample/assets/create_window_2.html new file mode 100644 index 0000000..2f65c0b --- /dev/null +++ b/src/xwalk/runtime/android/sample/assets/create_window_2.html @@ -0,0 +1,10 @@ + + + + + Create Window 2 + + +

Create window by open link

+ + diff --git a/src/xwalk/runtime/android/sample/assets/favicon.html b/src/xwalk/runtime/android/sample/assets/favicon.html new file mode 100644 index 0000000..6e60d4d --- /dev/null +++ b/src/xwalk/runtime/android/sample/assets/favicon.html @@ -0,0 +1,11 @@ + + + + + Favicon + + + +

The favicon will be shown by Toast

+ + diff --git a/src/xwalk/runtime/android/sample/assets/icon.png b/src/xwalk/runtime/android/sample/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d94fd20efdad671f015b23b4889962b05b77aa01 GIT binary patch literal 2662 zcmV-s3YqnZP)k7C187(-y>c(SRf_RSOxO~VN(i`B zM2!@RQAtpwO}#KcWm}~{3SmomDKE;FwiF6TID)cly?{Idc4to(T5WQoOGi8w%HgOaj8QV2=f-jepVLGWP) z?X8R(KvuE=s}MxyLX$>d9B4Weoyr6PwY1q#l?fuf!O7YmSp=s;)6)c~`Vpvpf=DlL zU~4z*^rsQ1q7BplK_uVbq>6$S8YiMUVgH7z=64-uxUdp@spmt(}dw3wH%UF|Ah_GBQQtI-pV+fPdsAMUwx=I94Ai;1)8QU^Gk%+uccwWhl zNcqS^gq2s3%J$GSVsBa56`UmzAPBhw1W>4gwk_4ok%|UH_C-OMJxbM=6hRxG!iqN< z>CC>EBKe82M66LAwNIcP~VI;zvtXHY+ zNHuz`*(i3iNR*>CBk?jp5RrJ5=Y|OH;&xD*k?Pcex4*a|QI^_^?q7W%)N~?z`Lv2KI(F=?$4>r;OBgunS3_Mzt%1A+@Q7uGiY8z5eh{z9- z{6mDxfoPPP#H-Fmk%&?m$&+elJX(~>NIsRWhbTpDLh`6(X4+&z^jN#DA6 z-)D1e>*XHwrS)uR>Yns#y+1z2t_}@KjYJMaQdV@FoMY_cSDvz$CBI|M8a~bvAMTcV z%oCGSEcu4q0RL=mhK>DjP}bp+jY|B`b@NG;?O#|U{oA=XHqIU$+9~aLr*BNLYt>cK zuXD8LbM|OvMtX&2HJfM@md?yAvZIS@r8n^E-+pJ)gMFbN=i-f9Z1kCYfW{B*W%sXN zmtCPHok*0FeZfZ_EV6Tn)zTaK)xK|R&oC0&{wJqyvolrs*LC;LK{k2zw6Y3K*^7jG zDvV88a=)?F*?HD};4?NqJ1ucudAqH5 z&8%W`iG*B`ZvV&Deesd-{r>Uq19o@eiF6}<{@VlW>B3{>5GhksjJ7HxJ$7IZo4t2W zWf!KELlgz0t;$GW?fZ(|y>eM~_a(J}$Yi6f(nw1hP}D!2nQXMB*lDv#IlcGaY5=cv89=ZB<6PGJ2Mc|9V`c1GHWbf%lp9=>*+jI;|x6`fB| zwb8zObBdi~@{g~xk#^)fDBTkAHsYun?K_9RV?!6mq#qXs6g4%{Ez{Yw?k6hSXoDBq zduM?S_3mHtCNh1{@ZN3{*cqvZNc(6c+i353v}VbZ!E{rYb}CE5yFS(4NY|G4wGfp} zIBQu(8$8%Q^NY(r!?aVFej2vM_7#jU(x?F=A(COV!Fz!Rd%@_QJN`X#jE!oGDk z(se4=Lo{I0*@tDc!E^Prs8z?0|FmR!!!Xhpj`cCaR5s2Ng>AIKYk}vQZ!sVZUS*`% zBh+XcWTYFG_sbCBQ?DjWx(Lxm8@v{HE;orb+ORJ}jC8}wtTqxEm(oNUZSYv&wRk1U zXscK&CfZaR50MC?-ONb4DX7tgzg4tWj35$ewB3xfYb5b$w3kMt?Y}ixjUmF9qD`23 zRbGuYkCAp0co~?k>cwa;-I=$|xq&`t*$>sfva0?re!r<#<``|!M%qmJW_?&Zq?x9#D^)h0XcKOv-305w8X0XJ*NTaXLd_s5M&W9ARuU@) zB1IT!KSo>EwPHS1X%I+ zLW4a>?H7CXVrKFV5f6c+SjaUawSOZlPg3NjbiPENVJ-v81#XeR=Lk;qAFRINovJN%?EM-Ar_ z@oMv?jW8J1Nqu0n;MPVa$PR)&JvK}J$ao)=4Z4#+5aEDSmiod-!IwYl*9VD=M9#gn zZPX{mDKF~D!9pH}Zl6q%jJ8qQhJ7YPfsAznqYWpvmHJ3)!QJ_s$Q=rOEd!n$P4JHq zK*Av+km3hWC=d}y@d79`hzO+k02C@jH6ZPvepFh8<-$IQ(CVy3)dm;xCH1K^!9ZeO zWErm)K_>0Zi+E80(g^i)Xo6KaDcSF^lNO2Uq7po&6h?y0F(f=+lD^p_&Q4LHP_IwG; z1}fXdO(2UELVE+S08> + + + + New Window + + +

This is a new window

+ + diff --git a/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnCreateWindowRequestedActivity.java b/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnCreateWindowRequestedActivity.java new file mode 100644 index 0000000..a7767ab --- /dev/null +++ b/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnCreateWindowRequestedActivity.java @@ -0,0 +1,74 @@ +// Copyright (c) 2014 Intel Corporation. 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.xwalk.core.sample; + +import android.app.Activity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.widget.LinearLayout; +import android.webkit.ValueCallback; + +import java.util.LinkedList; + +import org.xwalk.core.XWalkNavigationHistory; +import org.xwalk.core.XWalkUIClient; +import org.xwalk.core.XWalkView; + +public class OnCreateWindowRequestedActivity extends XWalkBaseActivity { + private LinearLayout mParent; + private LinkedList mXWalkViewHistory = new LinkedList(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mParent = new LinearLayout(OnCreateWindowRequestedActivity.this); + setContentView(mParent); + + mXWalkView = new XWalkView(OnCreateWindowRequestedActivity.this, + OnCreateWindowRequestedActivity.this); + setClient(mXWalkView); + + mParent.addView(mXWalkView); + mXWalkViewHistory.add(mXWalkView); + + mXWalkView.load("file:///android_asset/create_window_1.html", null); + } + + private void setClient(XWalkView view) { + view.setUIClient(new XWalkUIClient(view) { + @Override + public boolean onCreateWindowRequested(XWalkView view, InitiateBy initiator, + ValueCallback callback) { + XWalkView newView = new XWalkView(OnCreateWindowRequestedActivity.this, + OnCreateWindowRequestedActivity.this); + setClient(newView); + + mParent.removeView(mXWalkViewHistory.getLast()); + mParent.addView(newView); + mXWalkViewHistory.add(newView); + + callback.onReceiveValue(newView); + return true; + } + }); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) { + if (mXWalkViewHistory.getLast().getNavigationHistory().canGoBack()) { + mXWalkViewHistory.getLast().getNavigationHistory().navigate( + XWalkNavigationHistory.Direction.BACKWARD, 1); + return true; + } else if (mXWalkViewHistory.size() > 1) { + mParent.removeView(mXWalkViewHistory.removeLast()); + mParent.addView(mXWalkViewHistory.getLast()); + return true; + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnReceivedIconActivity.java b/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnReceivedIconActivity.java new file mode 100644 index 0000000..03b4e5a --- /dev/null +++ b/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnReceivedIconActivity.java @@ -0,0 +1,46 @@ +// Copyright (c) 2014 Intel Corporation. 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.xwalk.core.sample; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.os.Message; +import android.widget.ImageView; +import android.widget.Toast; + +import org.xwalk.core.XWalkUIClient; +import org.xwalk.core.XWalkView; + +public class OnReceivedIconActivity extends XWalkBaseActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mXWalkView = new XWalkView(OnReceivedIconActivity.this, OnReceivedIconActivity.this); + setContentView(mXWalkView); + + mXWalkView.setUIClient(new XWalkUIClient(mXWalkView) { + @Override + public void onIconAvailable(XWalkView view, String url, Message msg) { + msg.sendToTarget(); + } + + @Override + public void onReceivedIcon(XWalkView view, String url, Bitmap icon) { + Toast toast = Toast.makeText(OnReceivedIconActivity.this, "Favicon", + Toast.LENGTH_LONG); + + ImageView favicon = new ImageView(OnReceivedIconActivity.this); + favicon.setImageBitmap(icon); + + toast.setView(favicon); + toast.show(); + } + }); + + mXWalkView.load("file:///android_asset/favicon.html", null); + } +} diff --git a/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.cc b/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.cc index 7877ade..dc1d74c 100644 --- a/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.cc +++ b/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.cc @@ -169,4 +169,9 @@ void XWalkRenderViewHostExt::OnPageScaleFactorChanged(float page_scale_factor) { client_bridge->OnWebLayoutPageScaleFactorChanged(page_scale_factor); } +void XWalkRenderViewHostExt::SetBackgroundColor(SkColor c) { + DCHECK(CalledOnValidThread()); + Send(new XWalkViewMsg_SetBackgroundColor(web_contents()->GetRoutingID(), c)); +} + } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.h b/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.h index 73be9a6..f27ad93 100644 --- a/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.h +++ b/src/xwalk/runtime/browser/android/renderer_host/xwalk_render_view_host_ext.h @@ -62,6 +62,7 @@ class XWalkRenderViewHostExt : public content::WebContentsObserver, // the meta viewport tag. void SetInitialPageScale(double page_scale_factor); void SetJsOnlineProperty(bool network_up); + void SetBackgroundColor(SkColor c); // Sets the white list for Cross-Origin access. void SetOriginAccessWhitelist(const std::string& base_url, diff --git a/src/xwalk/runtime/browser/android/xwalk_content.cc b/src/xwalk/runtime/browser/android/xwalk_content.cc index a7fb148..0054609 100644 --- a/src/xwalk/runtime/browser/android/xwalk_content.cc +++ b/src/xwalk/runtime/browser/android/xwalk_content.cc @@ -413,7 +413,7 @@ static jlong Init(JNIEnv* env, jobject obj) { } bool RegisterXWalkContent(JNIEnv* env) { - return RegisterNativesImpl(env) >= 0; + return RegisterNativesImpl(env); } namespace { @@ -501,4 +501,10 @@ void XWalkContent::HideGeolocationPrompt(const GURL& origin) { } } +// Called by Java. +void XWalkContent::SetBackgroundColor(JNIEnv* env, jobject obj, jint color) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + render_view_host_ext_->SetBackgroundColor(color); +} + } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/xwalk_content.h b/src/xwalk/runtime/browser/android/xwalk_content.h index 0a738d4..3e7ae73 100644 --- a/src/xwalk/runtime/browser/android/xwalk_content.h +++ b/src/xwalk/runtime/browser/android/xwalk_content.h @@ -66,6 +66,7 @@ class XWalkContent { jobject obj, jstring path, jstring manifest); + void SetBackgroundColor(JNIEnv* env, jobject obj, jint color); // Geolocation API support void ShowGeolocationPrompt(const GURL& origin, diff --git a/src/xwalk/runtime/browser/android/xwalk_contents_client_bridge.cc b/src/xwalk/runtime/browser/android/xwalk_contents_client_bridge.cc index d5b30af..2f04730 100644 --- a/src/xwalk/runtime/browser/android/xwalk_contents_client_bridge.cc +++ b/src/xwalk/runtime/browser/android/xwalk_contents_client_bridge.cc @@ -470,7 +470,7 @@ void XWalkContentsClientBridge::OnReceivedIcon(const GURL& icon_url, } bool RegisterXWalkContentsClientBridge(JNIEnv* env) { - return RegisterNativesImpl(env) >= 0; + return RegisterNativesImpl(env); } } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.cc b/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.cc index f979b2d..f5df627 100644 --- a/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.cc +++ b/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.cc @@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "blink_upstream_version.h" // NOLINT #include "content/public/browser/android/devtools_auth.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_http_handler.h" @@ -28,7 +29,6 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" -#include "content/public/common/user_agent.h" #include "grit/xwalk_resources.h" #include "jni/XWalkDevToolsServer_jni.h" #include "net/socket/unix_domain_listen_socket_posix.h" @@ -45,9 +45,6 @@ namespace { // Currently, the chrome version is hardcoded because of this dependancy. const char kFrontEndURL[] = "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html"; -const char kTargetTypePage[] = "page"; -const char kTargetTypeServiceWorker[] = "service_worker"; -const char kTargetTypeOther[] = "other"; bool AuthorizeSocketAccessWithDebugPermission( const net::UnixDomainServerSocket::Credentials& credentials) { @@ -58,79 +55,12 @@ bool AuthorizeSocketAccessWithDebugPermission( content::CanUserConnectToDevTools(credentials); } -class Target : public content::DevToolsTarget { - public: - explicit Target(scoped_refptr agent_host); - - virtual std::string GetId() const OVERRIDE { return agent_host_->GetId(); } - virtual std::string GetType() const OVERRIDE { - switch (agent_host_->GetType()) { - case content::DevToolsAgentHost::TYPE_WEB_CONTENTS: - return kTargetTypePage; - case content::DevToolsAgentHost::TYPE_SERVICE_WORKER: - return kTargetTypeServiceWorker; - default: - break; - } - return kTargetTypeOther; - } - virtual std::string GetTitle() const OVERRIDE { - return agent_host_->GetTitle(); - } - - // TODO(hmin): Get the description about web contents view. - virtual std::string GetDescription() const OVERRIDE { return std::string(); } - virtual GURL GetURL() const OVERRIDE { return url_; } - virtual GURL GetFaviconURL() const OVERRIDE { return GURL(); } - virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { - return last_activity_time_; - } - virtual std::string GetParentId() const OVERRIDE { return std::string(); } - virtual bool IsAttached() const OVERRIDE { - return agent_host_->IsAttached(); - } - virtual scoped_refptr GetAgentHost() const OVERRIDE { - return agent_host_; - } - - virtual bool Activate() const OVERRIDE { - WebContents* web_contents = agent_host_->GetWebContents(); - if (!web_contents) - return false; - web_contents->GetDelegate()->ActivateContents(web_contents); - return true; - } - - virtual bool Close() const OVERRIDE { return false; } - - private: - scoped_refptr agent_host_; - std::string id_; - std::string title_; - GURL url_; - GURL favicon_url_; - base::TimeTicks last_activity_time_; -}; - -Target::Target(scoped_refptr agent_host) - : agent_host_(agent_host) { - if (content::WebContents* web_contents = agent_host_->GetWebContents()) { - content::NavigationController& controller = web_contents->GetController(); - content::NavigationEntry* entry = controller.GetActiveEntry(); - if (entry != NULL && entry->GetURL().is_valid()) - favicon_url_ = entry->GetFavicon().url; - last_activity_time_ = web_contents->GetLastActiveTime(); - } -} - // Delegate implementation for the devtools http handler on android. A new // instance of this gets created each time devtools is enabled. -class XWalkDevToolsHttpHandlerDelegate +class XWalkAndroidDevToolsHttpHandlerDelegate : public content::DevToolsHttpHandlerDelegate { public: - explicit XWalkDevToolsHttpHandlerDelegate( - const net::UnixDomainServerSocket::AuthCallback& auth_callback) - : auth_callback_(auth_callback) { + XWalkAndroidDevToolsHttpHandlerDelegate() { } virtual std::string GetDiscoveryPageHTML() OVERRIDE { @@ -152,49 +82,29 @@ class XWalkDevToolsHttpHandlerDelegate return scoped_ptr(); } private: - const net::UnixDomainServerSocket::AuthCallback auth_callback_; - DISALLOW_COPY_AND_ASSIGN(XWalkDevToolsHttpHandlerDelegate); -}; - -class XWalkDevToolsDelegate - : public content::DevToolsManagerDelegate { - public: - virtual std::string GetPageThumbnailData(const GURL& url) OVERRIDE { - return std::string(); - } - - virtual scoped_ptr CreateNewTarget( - const GURL&) OVERRIDE { - return scoped_ptr(); - } - virtual void EnumerateTargets(TargetCallback callback) OVERRIDE { - TargetList targets; - content::DevToolsAgentHost::List agents = - content::DevToolsAgentHost::GetOrCreateAll(); - for (content::DevToolsAgentHost::List::iterator it = agents.begin(); - it != agents.end(); ++it) { - targets.push_back(new Target(*it)); - } - callback.Run(targets); - } + DISALLOW_COPY_AND_ASSIGN(XWalkAndroidDevToolsHttpHandlerDelegate); }; // Factory for UnixDomainServerSocket. class UnixDomainServerSocketFactory : public content::DevToolsHttpHandler::ServerSocketFactory { public: - explicit UnixDomainServerSocketFactory(const std::string& socket_name) - : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1) {} + explicit UnixDomainServerSocketFactory( + const std::string& socket_name, + const net::UnixDomainServerSocket::AuthCallback& auth_callback) + : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1), + auth_callback_(auth_callback) {} private: // content::DevToolsHttpHandler::ServerSocketFactory. virtual scoped_ptr Create() const OVERRIDE { return scoped_ptr( new net::UnixDomainServerSocket( - base::Bind(&content::CanUserConnectToDevTools), + auth_callback_, true /* use_abstract_namespace */)); } + const net::UnixDomainServerSocket::AuthCallback auth_callback_; DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory); }; @@ -205,7 +115,8 @@ namespace xwalk { XWalkDevToolsServer::XWalkDevToolsServer(const std::string& socket_name) : socket_name_(socket_name), protocol_handler_(NULL), - allowed_uid_(0) { + allow_debug_permission_(false), + allow_socket_access_(false) { } XWalkDevToolsServer::~XWalkDevToolsServer() { @@ -217,27 +128,30 @@ XWalkDevToolsServer::~XWalkDevToolsServer() { // process and connects to the devtools server. bool XWalkDevToolsServer::CanUserConnectToDevTools( const net::UnixDomainServerSocket::Credentials& credentials) { - if (credentials.user_id == allowed_uid_) + if (allow_socket_access_) return true; + if (allow_debug_permission_) + return AuthorizeSocketAccessWithDebugPermission(credentials); return content::CanUserConnectToDevTools(credentials); } -void XWalkDevToolsServer::Start(bool allow_debug_permission) { +void XWalkDevToolsServer::Start(bool allow_debug_permission, + bool allow_socket_access) { + allow_debug_permission_ = allow_debug_permission; + allow_socket_access_ = allow_socket_access; if (protocol_handler_) return; net::UnixDomainServerSocket::AuthCallback auth_callback = - allow_debug_permission ? - base::Bind(&AuthorizeSocketAccessWithDebugPermission) : - base::Bind(&XWalkDevToolsServer::CanUserConnectToDevTools, - base::Unretained(this)); + base::Bind(&XWalkDevToolsServer::CanUserConnectToDevTools, + base::Unretained(this)); scoped_ptr factory( - new UnixDomainServerSocketFactory(socket_name_)); + new UnixDomainServerSocketFactory(socket_name_, auth_callback)); protocol_handler_ = content::DevToolsHttpHandler::Start( factory.Pass(), - base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str()), - new XWalkDevToolsHttpHandlerDelegate(auth_callback), base::FilePath()); + base::StringPrintf(kFrontEndURL, BLINK_UPSTREAM_REVISION), + new XWalkAndroidDevToolsHttpHandlerDelegate(), base::FilePath()); } void XWalkDevToolsServer::Stop() { @@ -247,16 +161,14 @@ void XWalkDevToolsServer::Stop() { // deletion. protocol_handler_->Stop(); protocol_handler_ = NULL; + allow_socket_access_ = false; + allow_debug_permission_ = false; } bool XWalkDevToolsServer::IsStarted() const { return protocol_handler_; } -void XWalkDevToolsServer::AllowConnectionFromUid(uid_t uid) { - allowed_uid_ = uid; -} - bool RegisterXWalkDevToolsServer(JNIEnv* env) { return RegisterNativesImpl(env); } @@ -283,23 +195,16 @@ static void SetRemoteDebuggingEnabled(JNIEnv* env, jobject obj, jlong server, jboolean enabled, - jboolean allow_debug_permission) { + jboolean allow_debug_permission, + jboolean allow_socket_access) { XWalkDevToolsServer* devtools_server = reinterpret_cast(server); - if (enabled) { - devtools_server->Start(allow_debug_permission); + if (enabled == JNI_TRUE) { + devtools_server->Start(allow_debug_permission == JNI_TRUE, + allow_socket_access == JNI_TRUE); } else { devtools_server->Stop(); } } -static void AllowConnectionFromUid(JNIEnv* env, - jobject obj, - jlong server, - jint uid) { - XWalkDevToolsServer* devtools_server = - reinterpret_cast(server); - devtools_server->AllowConnectionFromUid((uid_t) uid); -} - } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.h b/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.h index 7f140f2..4ee689b 100644 --- a/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.h +++ b/src/xwalk/runtime/browser/android/xwalk_dev_tools_server.h @@ -23,7 +23,7 @@ class XWalkDevToolsServer { ~XWalkDevToolsServer(); // Opens linux abstract socket to be ready for remote debugging. - void Start(bool allow_debug_permission); + void Start(bool allow_debug_permission, bool allow_socket_access); // Closes debugging socket, stops debugging. void Stop(); @@ -38,7 +38,8 @@ class XWalkDevToolsServer { std::string socket_name_; content::DevToolsHttpHandler* protocol_handler_; - uid_t allowed_uid_; + bool allow_debug_permission_; + bool allow_socket_access_; DISALLOW_COPY_AND_ASSIGN(XWalkDevToolsServer); }; diff --git a/src/xwalk/runtime/browser/android/xwalk_http_auth_handler.cc b/src/xwalk/runtime/browser/android/xwalk_http_auth_handler.cc index 27d279f..7cc1450 100644 --- a/src/xwalk/runtime/browser/android/xwalk_http_auth_handler.cc +++ b/src/xwalk/runtime/browser/android/xwalk_http_auth_handler.cc @@ -77,7 +77,7 @@ XWalkHttpAuthHandlerBase* XWalkHttpAuthHandlerBase::Create( } bool RegisterXWalkHttpAuthHandler(JNIEnv* env) { - return RegisterNativesImpl(env) >= 0; + return RegisterNativesImpl(env); } } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/xwalk_path_helper.cc b/src/xwalk/runtime/browser/android/xwalk_path_helper.cc index e7566d1..7900199 100644 --- a/src/xwalk/runtime/browser/android/xwalk_path_helper.cc +++ b/src/xwalk/runtime/browser/android/xwalk_path_helper.cc @@ -38,7 +38,7 @@ static void SetDirectory(JNIEnv* env, jclass clazz, } bool RegisterXWalkPathHelper(JNIEnv* env) { - return RegisterNativesImpl(env) >= 0; + return RegisterNativesImpl(env); } } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/xwalk_settings.cc b/src/xwalk/runtime/browser/android/xwalk_settings.cc index 528f049..ba26c31 100644 --- a/src/xwalk/runtime/browser/android/xwalk_settings.cc +++ b/src/xwalk/runtime/browser/android/xwalk_settings.cc @@ -237,7 +237,7 @@ static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) { } bool RegisterXWalkSettings(JNIEnv* env) { - return RegisterNativesImpl(env) >= 0; + return RegisterNativesImpl(env); } } // namespace xwalk diff --git a/src/xwalk/runtime/browser/android/xwalk_view_delegate.cc b/src/xwalk/runtime/browser/android/xwalk_view_delegate.cc index 1b992f1..f6e3e52 100644 --- a/src/xwalk/runtime/browser/android/xwalk_view_delegate.cc +++ b/src/xwalk/runtime/browser/android/xwalk_view_delegate.cc @@ -19,7 +19,7 @@ jboolean IsLibraryBuiltForIA(JNIEnv* env, jclass jcaller) { } bool RegisterXWalkViewDelegate(JNIEnv* env) { - return RegisterNativesImpl(env) >= 0; + return RegisterNativesImpl(env); } } // namespace xwalk diff --git a/src/xwalk/runtime/browser/blink_upstream_version.h.in b/src/xwalk/runtime/browser/blink_upstream_version.h.in new file mode 100644 index 0000000..ab6d1ed --- /dev/null +++ b/src/xwalk/runtime/browser/blink_upstream_version.h.in @@ -0,0 +1,7 @@ +// Copyright 2014 Intel Corp. All rights reserved. +// Use of this source is governed by a BSD-style license that can be +// found in the LICENSE file. + +// upstream_blink_version.h is generated from upstream_blink_version.h.in. Edit the source! + +#define BLINK_UPSTREAM_REVISION "@@UPSTREAM_REVISION@" diff --git a/src/xwalk/runtime/browser/devtools/xwalk_devtools_browsertest.cc b/src/xwalk/runtime/browser/devtools/xwalk_devtools_browsertest.cc index 229ff6f..c9a11e4 100644 --- a/src/xwalk/runtime/browser/devtools/xwalk_devtools_browsertest.cc +++ b/src/xwalk/runtime/browser/devtools/xwalk_devtools_browsertest.cc @@ -16,6 +16,20 @@ #include "testing/gmock/include/gmock/gmock.h" using xwalk::Runtime; +namespace { +Runtime* CreateWithDefaultWindow( + xwalk::RuntimeContext* runtime_context, const GURL& url, + Runtime::Observer* observer = NULL) { + Runtime* runtime = Runtime::Create(runtime_context, observer); + runtime->LoadURL(url); +#if !defined(OS_ANDROID) + xwalk::RuntimeUIStrategy ui_strategy; + xwalk::NativeAppWindow::CreateParams params; + ui_strategy.Show(runtime, params); +#endif + return runtime; +} +} // namespace class XWalkDevToolsTest : public InProcessBrowserTest { public: @@ -30,7 +44,7 @@ class XWalkDevToolsTest : public InProcessBrowserTest { IN_PROC_BROWSER_TEST_F(XWalkDevToolsTest, RemoteDebugging) { GURL localhost_url("http://127.0.0.1:9222"); - Runtime* debugging_host = Runtime::CreateWithDefaultWindow( + Runtime* debugging_host = CreateWithDefaultWindow( GetRuntimeContext(), localhost_url, runtime_registry()); content::WaitForLoadStop(debugging_host->web_contents()); base::string16 real_title = debugging_host->web_contents()->GetTitle(); diff --git a/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.cc b/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.cc index 2f8d3a5..6a8d5f8 100644 --- a/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.cc +++ b/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.cc @@ -6,22 +6,28 @@ #include +#include "base/base64.h" +#include "base/memory/ref_counted_memory.h" #include "base/strings/utf_string_conversions.h" +#include "base/thread_task_runner_handle.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_http_handler.h" #include "content/public/browser/devtools_target.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "grit/xwalk_resources.h" #include "net/socket/tcp_listen_socket.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/snapshot/snapshot.h" #include "xwalk/runtime/browser/runtime.h" using content::DevToolsAgentHost; using content::RenderViewHost; +using content::RenderWidgetHostView; using content::WebContents; namespace { @@ -50,7 +56,7 @@ class Target : public content::DevToolsTarget { return agent_host_->GetTitle(); } virtual std::string GetDescription() const OVERRIDE { return std::string(); } - virtual GURL GetURL() const OVERRIDE { return url_; } + virtual GURL GetURL() const OVERRIDE { return agent_host_->GetURL(); } virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; } virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { return last_activity_time_; @@ -66,10 +72,11 @@ class Target : public content::DevToolsTarget { virtual bool Close() const OVERRIDE; private: + GURL GetFaviconDataURL(WebContents* web_contents) const; + scoped_refptr agent_host_; std::string id_; std::string title_; - GURL url_; GURL favicon_url_; base::TimeTicks last_activity_time_; }; @@ -81,30 +88,55 @@ Target::Target(scoped_refptr agent_host) content::NavigationEntry* entry = controller.GetActiveEntry(); if (entry != NULL && entry->GetURL().is_valid()) favicon_url_ = entry->GetFavicon().url; + if (favicon_url_.is_empty()) + favicon_url_ = GetFaviconDataURL(web_contents); last_activity_time_ = web_contents->GetLastActiveTime(); } } +GURL Target::GetFaviconDataURL(WebContents* web_contents) const { + // Convert icon image to "data:" url. + xwalk::Runtime* runtime = + static_cast(web_contents->GetDelegate()); + if (!runtime || runtime->app_icon().IsEmpty()) + return GURL(); + scoped_refptr icon_bytes = + runtime->app_icon().Copy1xPNGBytes(); + std::string str_url; + str_url.append(reinterpret_cast(icon_bytes->front()), + icon_bytes->size()); + base::Base64Encode(str_url, &str_url); + str_url.insert(0, "data:image/png;base64,"); + return GURL(str_url); +} + bool Target::Activate() const { - WebContents* web_contents = agent_host_->GetWebContents(); - if (!web_contents) - return false; - web_contents->GetDelegate()->ActivateContents(web_contents); - return true; + return agent_host_->Activate(); } bool Target::Close() const { - RenderViewHost* rvh = agent_host_->GetWebContents()->GetRenderViewHost(); - if (!rvh) - return false; - rvh->ClosePage(); - return true; + return agent_host_->Close(); } } // namespace namespace xwalk { +namespace { +Runtime* CreateWithDefaultWindow( + RuntimeContext* runtime_context, const GURL& url, + Runtime::Observer* observer = NULL) { + Runtime* runtime = Runtime::Create(runtime_context, observer); + runtime->LoadURL(url); +#if !defined(OS_ANDROID) + RuntimeUIStrategy ui_strategy; + NativeAppWindow::CreateParams params; + ui_strategy.Show(runtime, params); +#endif + return runtime; +} +} // namespace + XWalkDevToolsHttpHandlerDelegate::XWalkDevToolsHttpHandlerDelegate() { } @@ -116,6 +148,15 @@ std::string XWalkDevToolsHttpHandlerDelegate::GetDiscoveryPageHTML() { IDR_DEVTOOLS_FRONTEND_PAGE_HTML).as_string(); } +void XWalkDevToolsDelegate::ProcessAndSaveThumbnail( + const GURL& url, + scoped_refptr png) { + const std::vector& png_data = png->data(); + std::string png_string_data(reinterpret_cast(&png_data[0]), + png_data.size()); + thumbnail_map_[url] = png_string_data; +} + bool XWalkDevToolsHttpHandlerDelegate::BundlesFrontendResources() { return true; } @@ -132,7 +173,8 @@ XWalkDevToolsHttpHandlerDelegate::CreateSocketForTethering( } XWalkDevToolsDelegate::XWalkDevToolsDelegate(RuntimeContext* runtime_context) - : runtime_context_(runtime_context) { + : runtime_context_(runtime_context), + weak_factory_(this) { } XWalkDevToolsDelegate::~XWalkDevToolsDelegate() { @@ -145,12 +187,34 @@ base::DictionaryValue* XWalkDevToolsDelegate::HandleCommand( } std::string XWalkDevToolsDelegate::GetPageThumbnailData(const GURL& url) { + if (thumbnail_map_.find(url) != thumbnail_map_.end()) + return thumbnail_map_[url]; + // TODO(YangangHan): Support real time thumbnail. + content::DevToolsAgentHost::List agents = + content::DevToolsAgentHost::GetOrCreateAll(); + for (auto& it : agents) { + WebContents* web_contents = it.get()->GetWebContents(); + if (web_contents && web_contents->GetURL() == url) { + RenderWidgetHostView* render_widget_host_view = + web_contents->GetRenderViewHost()->GetView(); + gfx::Rect snapshot_bounds( + render_widget_host_view->GetViewBounds().size()); + ui::GrabViewSnapshotAsync( + render_widget_host_view->GetNativeView(), + snapshot_bounds, + base::ThreadTaskRunnerHandle::Get(), + base::Bind(&XWalkDevToolsDelegate::ProcessAndSaveThumbnail, + weak_factory_.GetWeakPtr(), + url)); + break; + } + } return std::string(); } scoped_ptr XWalkDevToolsDelegate::CreateNewTarget(const GURL& url) { - Runtime* runtime = Runtime::CreateWithDefaultWindow( + Runtime* runtime = CreateWithDefaultWindow( runtime_context_, GURL(url::kAboutBlankURL)); return scoped_ptr( new Target(DevToolsAgentHost::GetOrCreateFor(runtime->web_contents()))); @@ -158,13 +222,15 @@ XWalkDevToolsDelegate::CreateNewTarget(const GURL& url) { void XWalkDevToolsDelegate::EnumerateTargets(TargetCallback callback) { TargetList targets; - content::DevToolsAgentHost::List agents = - content::DevToolsAgentHost::GetOrCreateAll(); - for (content::DevToolsAgentHost::List::iterator it = agents.begin(); - it != agents.end(); ++it) { + content::DevToolsAgentHost::List agents = + content::DevToolsAgentHost::GetOrCreateAll(); + for (content::DevToolsAgentHost::List::iterator it = agents.begin(); + it != agents.end(); ++it) { +#if !defined(OS_ANDROID) Runtime* runtime = static_cast((*it)->GetWebContents()->GetDelegate()); if (runtime && runtime->remote_debugging_enabled()) +#endif targets.push_back(new Target(*it)); } callback.Run(targets); diff --git a/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h b/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h index 66307e8..2a35fd6 100644 --- a/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h +++ b/src/xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h @@ -5,11 +5,14 @@ #ifndef XWALK_RUNTIME_BROWSER_DEVTOOLS_XWALK_DEVTOOLS_DELEGATE_H_ #define XWALK_RUNTIME_BROWSER_DEVTOOLS_XWALK_DEVTOOLS_DELEGATE_H_ +#include #include #include #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted_memory.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/devtools_http_handler_delegate.h" #include "content/public/browser/devtools_manager_delegate.h" #include "url/gurl.h" @@ -58,9 +61,14 @@ class XWalkDevToolsDelegate : public content::DevToolsManagerDelegate { const GURL& url) OVERRIDE; virtual void EnumerateTargets(TargetCallback callback) OVERRIDE; virtual std::string GetPageThumbnailData(const GURL& url) OVERRIDE; + void ProcessAndSaveThumbnail(const GURL& url, + scoped_refptr png); private: + using ThumbnailMap = std::map; + ThumbnailMap thumbnail_map_; RuntimeContext* runtime_context_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(XWalkDevToolsDelegate); }; diff --git a/src/xwalk/runtime/browser/runtime.cc b/src/xwalk/runtime/browser/runtime.cc index 7426247..5f86702 100644 --- a/src/xwalk/runtime/browser/runtime.cc +++ b/src/xwalk/runtime/browser/runtime.cc @@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/message_loop/message_loop.h" +#include "base/strings/utf_string_conversions.h" #include "xwalk/runtime/browser/image_util.h" #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h" #include "xwalk/runtime/browser/runtime_context.h" @@ -22,6 +23,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" @@ -30,28 +32,22 @@ #include "ui/gfx/image/image_skia.h" #include "ui/gfx/native_widget_types.h" +#if defined(OS_TIZEN) +#include "content/public/browser/site_instance.h" +#include "xwalk/application/browser/application.h" +#include "xwalk/application/browser/application_system.h" +#include "xwalk/application/browser/application_service.h" +#endif + +#if !defined(OS_ANDROID) +#include "xwalk/runtime/browser/runtime_ui_strategy.h" +#endif + using content::FaviconURL; using content::WebContents; namespace xwalk { -namespace { - -// The default size for web content area size. -const int kDefaultWidth = 840; -const int kDefaultHeight = 600; - -} // namespace - -// static -Runtime* Runtime::CreateWithDefaultWindow( - RuntimeContext* runtime_context, const GURL& url, Observer* observer) { - Runtime* runtime = Runtime::Create(runtime_context, observer); - runtime->LoadURL(url); - runtime->AttachDefaultWindow(); - return runtime; -} - // static Runtime* Runtime::Create(RuntimeContext* runtime_context, Observer* observer, @@ -60,12 +56,7 @@ Runtime* Runtime::Create(RuntimeContext* runtime_context, params.routing_id = MSG_ROUTING_NONE; WebContents* web_contents = WebContents::Create(params); - Runtime* runtime = new Runtime(web_contents, observer); -#if defined(OS_TIZEN_MOBILE) - runtime->InitRootWindow(); -#endif - - return runtime; + return new Runtime(web_contents, observer); } Runtime::Runtime(content::WebContents* web_contents, Observer* observer) @@ -81,9 +72,6 @@ Runtime::Runtime(content::WebContents* web_contents, Observer* observer) xwalk::NOTIFICATION_RUNTIME_OPENED, content::Source(this), content::NotificationService::NoDetails()); -#if defined(OS_TIZEN_MOBILE) - root_window_ = NULL; -#endif if (observer_) observer_->OnRuntimeAdded(this); } @@ -97,44 +85,16 @@ Runtime::~Runtime() { observer_->OnRuntimeRemoved(this); } -void Runtime::AttachDefaultWindow() { - NativeAppWindow::CreateParams params; - AttachWindow(params); -} - -void Runtime::AttachWindow(const NativeAppWindow::CreateParams& params) { -#if defined(OS_ANDROID) - NOTIMPLEMENTED(); -#else - CHECK(!window_); - NativeAppWindow::CreateParams effective_params(params); - ApplyWindowDefaultParams(&effective_params); - - // Set the app icon if it is passed from command line. - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kAppIcon)) { - base::FilePath icon_file = - command_line->GetSwitchValuePath(switches::kAppIcon); - app_icon_ = xwalk_utils::LoadImageFromFilePath(icon_file); - } else { - // Otherwise, use the default icon for Crosswalk app. - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - app_icon_ = rb.GetNativeImageNamed(IDR_XWALK_ICON_48); - } - +void Runtime::EnableTitleUpdatedNotification() { registrar_.Add(this, - content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, - content::Source(web_contents_.get())); + content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, + content::Source(web_contents_.get())); +} - window_ = NativeAppWindow::Create(effective_params); - if (!app_icon_.IsEmpty()) +void Runtime::set_app_icon(const gfx::Image& app_icon) { + app_icon_ = app_icon; + if (window_ && !app_icon_.IsEmpty()) window_->UpdateIcon(app_icon_); - window_->Show(); -#if defined(OS_TIZEN_MOBILE) - if (root_window_) - root_window_->Show(); -#endif -#endif } void Runtime::LoadURL(const GURL& url) { @@ -165,10 +125,24 @@ content::RenderProcessHost* Runtime::GetRenderProcessHost() { ////////////////////////////////////////////////////// content::WebContents* Runtime::OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) { - // The only one disposition we would take into consideration. +#if defined(OS_ANDROID) DCHECK(params.disposition == CURRENT_TAB); source->GetController().LoadURL( params.url, params.referrer, params.transition, std::string()); +#else + if (params.disposition == CURRENT_TAB) { + source->GetController().LoadURL( + params.url, params.referrer, params.transition, std::string()); + } else if (params.disposition == NEW_WINDOW || + params.disposition == NEW_POPUP || + params.disposition == NEW_FOREGROUND_TAB || + params.disposition == NEW_BACKGROUND_TAB) { + // TODO(xinchao): Excecuting JaveScript code is a temporary solution, + // need to be implemented by creating a new runtime window instead. + web_contents()->GetFocusedFrame()->ExecuteJavaScript( + base::UTF8ToUTF16("window.open('" + params.url.spec() + "')")); + } +#endif return source; } @@ -232,11 +206,7 @@ void Runtime::WebContentsCreated( const base::string16& frame_name, const GURL& target_url, content::WebContents* new_contents) { - Runtime* new_runtime = new Runtime(new_contents, observer_); -#if defined(OS_TIZEN_MOBILE) - new_runtime->SetRootWindow(root_window_); -#endif - new_runtime->AttachDefaultWindow(); + new Runtime(new_contents, observer_); } void Runtime::DidNavigateMainFramePostCommit( @@ -344,57 +314,4 @@ void Runtime::RequestMediaAccessPermission( XWalkMediaCaptureDevicesDispatcher::RunRequestMediaAccessPermission( web_contents, request, callback); } - -void Runtime::ApplyWindowDefaultParams(NativeAppWindow::CreateParams* params) { - if (!params->delegate) - params->delegate = this; - if (!params->web_contents) - params->web_contents = web_contents_.get(); - if (params->bounds.IsEmpty()) - params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight); -#if defined(OS_TIZEN_MOBILE) - if (root_window_) - params->parent = root_window_->GetNativeWindow(); -#endif - ApplyFullScreenParam(params); -} - -void Runtime::ApplyFullScreenParam(NativeAppWindow::CreateParams* params) { - DCHECK(params); - if (params->state == ui::SHOW_STATE_FULLSCREEN) - fullscreen_options_ |= FULLSCREEN_FOR_LAUNCH; - else - fullscreen_options_ &= ~FULLSCREEN_FOR_LAUNCH; -} - -#if defined(OS_TIZEN_MOBILE) -void Runtime::CloseRootWindow() { - if (root_window_) { - root_window_->Close(); - root_window_ = NULL; - } -} - -void Runtime::ApplyRootWindowParams(NativeAppWindow::CreateParams* params) { - if (!params->delegate) - params->delegate = this; - if (params->bounds.IsEmpty()) - params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight); - ApplyFullScreenParam(params); -} - -void Runtime::InitRootWindow() { - if (root_window_) - return; - - NativeAppWindow::CreateParams params; - ApplyRootWindowParams(¶ms); - root_window_ = NativeAppWindow::Create(params); -} - -void Runtime::SetRootWindow(NativeAppWindow* window) { - root_window_= window; -} - -#endif } // namespace xwalk diff --git a/src/xwalk/runtime/browser/runtime.h b/src/xwalk/runtime/browser/runtime.h index 5b48ab5..f12dfdb 100644 --- a/src/xwalk/runtime/browser/runtime.h +++ b/src/xwalk/runtime/browser/runtime.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "xwalk/runtime/browser/runtime_ui_strategy.h" #include "xwalk/runtime/browser/ui/native_app_window.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -55,26 +56,34 @@ class Runtime : public content::WebContentsDelegate, virtual ~Observer() {} }; + // Fullscreen options. + enum FullscreenOptions { + NO_FULLSCREEN = 0, + // Fullscreen entered by launch with "--fullscreen". + FULLSCREEN_FOR_LAUNCH = 1, + // Fullscreen entered by HTML requestFullscreen. + FULLSCREEN_FOR_TAB = 1 << 1, + }; + void SetObserver(Observer* observer) { observer_ = observer; } - // Create a new Runtime instance which binds to a default app window. - static Runtime* CreateWithDefaultWindow(RuntimeContext*, - const GURL&, Observer* = NULL); // Create a new Runtime instance with the given browsing context. static Runtime* Create(RuntimeContext*, Observer* = NULL, content::SiteInstance* = NULL); - // Attach to a default app window. - void AttachDefaultWindow(); - // Attach to a app window created with 'params'. - void AttachWindow(const NativeAppWindow::CreateParams& params); - void LoadURL(const GURL& url); void Close(); content::WebContents* web_contents() const { return web_contents_.get(); } NativeAppWindow* window() const { return window_; } + void set_window(NativeAppWindow* window) { window_ = window; } gfx::Image app_icon() const { return app_icon_; } + void set_app_icon(const gfx::Image& app_icon); + void EnableTitleUpdatedNotification(); + unsigned int fullscreen_options() { return fullscreen_options_; } + void set_fullscreen_options(unsigned int options) { + fullscreen_options_ = options; + } content::RenderProcessHost* GetRenderProcessHost(); @@ -83,10 +92,6 @@ class Runtime : public content::WebContentsDelegate, } bool remote_debugging_enabled() const { return remote_debugging_enabled_; } -#if defined(OS_TIZEN_MOBILE) - void CloseRootWindow(); -#endif - protected: Runtime(content::WebContents* web_contents, Observer* observer); virtual ~Runtime(); @@ -158,15 +163,6 @@ class Runtime : public content::WebContentsDelegate, // NativeAppWindowDelegate implementation. virtual void OnWindowDestroyed() OVERRIDE; - void ApplyWindowDefaultParams(NativeAppWindow::CreateParams* params); - void ApplyFullScreenParam(NativeAppWindow::CreateParams* params); - -#if defined(OS_TIZEN_MOBILE) - void ApplyRootWindowParams(NativeAppWindow::CreateParams* params); - void SetRootWindow(NativeAppWindow* window); - void InitRootWindow(); -#endif - // Notification manager. content::NotificationRegistrar registrar_; @@ -175,23 +171,10 @@ class Runtime : public content::WebContentsDelegate, NativeAppWindow* window_; -#if defined(OS_TIZEN_MOBILE) - NativeAppWindow* root_window_; -#endif - gfx::Image app_icon_; base::WeakPtrFactory weak_ptr_factory_; - // Fullscreen options. - enum FullscreenOptions { - NO_FULLSCREEN = 0, - // Fullscreen entered by launch with "--fullscreen". - FULLSCREEN_FOR_LAUNCH = 1, - // Fullscreen entered by HTML requestFullscreen. - FULLSCREEN_FOR_TAB = 1 << 1, - }; - unsigned int fullscreen_options_; bool remote_debugging_enabled_; diff --git a/src/xwalk/runtime/browser/runtime_context.cc b/src/xwalk/runtime/browser/runtime_context.cc index 10f8bda..b422a13 100644 --- a/src/xwalk/runtime/browser/runtime_context.cc +++ b/src/xwalk/runtime/browser/runtime_context.cc @@ -258,6 +258,12 @@ net::URLRequestContextGetter* context_getters_.insert( std::make_pair(partition_path.value(), context_getter)); + // Make sure that the default url request getter has been initialized, + // please refer to https://crosswalk-project.org/jira/browse/XWALK-2890 + // for more details. + if (!url_request_getter_.get()) + CreateRequestContext(protocol_handlers, request_interceptors.Pass()); + return context_getter.get(); #endif } diff --git a/src/xwalk/runtime/browser/runtime_defered_ui_strategy.cc b/src/xwalk/runtime/browser/runtime_defered_ui_strategy.cc new file mode 100644 index 0000000..2cad3be --- /dev/null +++ b/src/xwalk/runtime/browser/runtime_defered_ui_strategy.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xwalk/runtime/browser/runtime_defered_ui_strategy.h" + +#include "xwalk/runtime/browser/runtime.h" + +namespace xwalk { +RuntimeDeferedUIStrategy::RuntimeDeferedUIStrategy() + : defered_show_(true) {} + +RuntimeDeferedUIStrategy::~RuntimeDeferedUIStrategy() {} + +void RuntimeDeferedUIStrategy::Show( + Runtime* runtime, const NativeAppWindow::CreateParams& params) { + if (!defered_show_) { + RuntimeUIStrategy::Show(runtime, params); + return; + } + + runtime_map_[runtime] = params; +} + +void RuntimeDeferedUIStrategy::ShowStoredRuntimes() { + for (const auto& item : runtime_map_) { + RuntimeUIStrategy::Show(item.first, item.second); + } + defered_show_ = false; +} +} // namespace xwalk diff --git a/src/xwalk/runtime/browser/runtime_defered_ui_strategy.h b/src/xwalk/runtime/browser/runtime_defered_ui_strategy.h new file mode 100644 index 0000000..4ccd189 --- /dev/null +++ b/src/xwalk/runtime/browser/runtime_defered_ui_strategy.h @@ -0,0 +1,37 @@ +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef XWALK_RUNTIME_BROWSER_RUNTIME_DEFERED_UI_STRATEGY_H_ +#define XWALK_RUNTIME_BROWSER_RUNTIME_DEFERED_UI_STRATEGY_H_ + +#include + +#include "xwalk/runtime/browser/runtime_ui_strategy.h" +#include "xwalk/runtime/browser/ui/native_app_window.h" + +namespace xwalk { +class Runtime; + +class RuntimeDeferedUIStrategy : public RuntimeUIStrategy { + public: + RuntimeDeferedUIStrategy(); + virtual ~RuntimeDeferedUIStrategy(); + + // Override from RuntimeUIStrategy. + virtual void Show(Runtime* runtime, + const NativeAppWindow::CreateParams& params) OVERRIDE; + + void ShowStoredRuntimes(); + + private: + std::map runtime_map_; + bool defered_show_; +}; + +inline RuntimeDeferedUIStrategy* +ToRuntimeDeferedUIStrategy(RuntimeUIStrategy* ui_strategy) { + return static_cast(ui_strategy); +} +} // namespace xwalk +#endif // XWALK_RUNTIME_BROWSER_RUNTIME_DEFERED_UI_STRATEGY_H_ diff --git a/src/xwalk/runtime/browser/runtime_platform_util_android.cc b/src/xwalk/runtime/browser/runtime_platform_util_android.cc index 02cf298..39092de 100644 --- a/src/xwalk/runtime/browser/runtime_platform_util_android.cc +++ b/src/xwalk/runtime/browser/runtime_platform_util_android.cc @@ -30,4 +30,8 @@ bool IsVisible(gfx::NativeView view) { return true; } +void OpenExternal(const GURL& url) { + NOTIMPLEMENTED(); +} + } // namespace platform_util diff --git a/src/xwalk/runtime/browser/runtime_platform_util_tizen.cc b/src/xwalk/runtime/browser/runtime_platform_util_tizen.cc index 1e58c42..1b25c7c 100644 --- a/src/xwalk/runtime/browser/runtime_platform_util_tizen.cc +++ b/src/xwalk/runtime/browser/runtime_platform_util_tizen.cc @@ -4,10 +4,14 @@ #include "xwalk/runtime/browser/runtime_platform_util.h" +#include "base/bind.h" #include "base/file_util.h" #include "base/logging.h" #include "base/process/kill.h" #include "base/process/launch.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" #include "url/gurl.h" namespace platform_util { @@ -16,8 +20,91 @@ namespace { // In some Tizen releases, there exists a system browser called 'MiniBrowser', // which we can use to open an external link from a web app. const char kWebBrowserPath[] = "/usr/bin/MiniBrowser"; + +typedef base::Callback ParamsWriter; + +struct ProtocolDBusServiceInfo { + const char* scheme; + const char* service; + const char* interface; + const char* method; + const char* object_path; + ParamsWriter params_writer; +}; + +void ParseAndWriteTelParams(const GURL& url, + dbus::MessageWriter* dbus_writer) { + // Phone number + dbus_writer->AppendString(url.GetContent()); + // Always don't auto dial + dbus_writer->AppendBool(false); +} + +void ParseAndWriteMailParams(const GURL& uri, + dbus::MessageWriter* dbus_writer) { +} + +void ParseAndWriteSmsParams(const GURL& url, + dbus::MessageWriter* dbus_writer) { + // Support the case sms:12345678?body=Hello + std::string query = url.query(); + std::string content = url.GetContent(); + // Extract the phone number + const std::string number = content.substr(0, content.find(query) - 1); + // Remove "body=" + const std::string body = query.erase(0, 5); + + dbus_writer->AppendString(number); + dbus_writer->AppendString(body); + // Always don't auto dial + dbus_writer->AppendBool(false); +} + +const ProtocolDBusServiceInfo protocol_dbus_services[] = { + {"tel", "org.tizen.dialer", "org.tizen.dialer.Control", "Dial", "/", + base::Bind(ParseAndWriteTelParams)}, + {"mailto", "org.tizen.email_service", "org.tizen.email_service", "Launch", + "/org/tizen/email_service", + base::Bind(ParseAndWriteMailParams)}, + {"sms", "org.tizen.dialer", "org.tizen.dialer.Control", "Send", "/", + base::Bind(ParseAndWriteSmsParams)}, +}; + +bool CallDbusService(const ProtocolDBusServiceInfo& info, + const GURL& url) { + const dbus::ObjectPath dbus_path(info.object_path); + + dbus::Bus::Options options; + scoped_refptr bus(new dbus::Bus(options)); + dbus::ObjectProxy* app_proxy = + bus->GetObjectProxy(info.service, dbus_path); + if (!app_proxy) { + VLOG(1) << "app_proxy failed."; + return false; + } + + dbus::MethodCall method_call(info.interface, info.method); + dbus::MessageWriter writer(&method_call); + info.params_writer.Run(url, &writer); + + app_proxy->CallMethod(&method_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + dbus::ObjectProxy::EmptyResponseCallback()); + + return true; +} } // namespace +bool HandleExternalProtocol(const GURL& url) { + for (size_t i = 0; i < arraysize(protocol_dbus_services); ++i) { + const ProtocolDBusServiceInfo& info = protocol_dbus_services[i]; + if (url.SchemeIs(info.scheme)) { + return CallDbusService(info, url); + } + } + return false; +} + void OpenExternal(const GURL& url) { if (url.SchemeIsHTTPOrHTTPS()) { LOG(INFO) << "Open in WebBrowser."; @@ -31,6 +118,8 @@ void OpenExternal(const GURL& url) { if (base::LaunchProcess(argv, base::LaunchOptions(), &handle)) base::EnsureProcessGetsReaped(handle); + } else if (!HandleExternalProtocol(url)) { + LOG(ERROR) << "Can not handle url: " << url.spec(); } } diff --git a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.cc b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.cc index 53c1fc4..be3a022 100644 --- a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.cc +++ b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.cc @@ -5,7 +5,6 @@ #include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h" -#include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "content/public/browser/browser_thread.h" @@ -18,14 +17,26 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_request.h" +#include "xwalk/runtime/browser/runtime_platform_util.h" -namespace { -base::LazyInstance - g_runtime_resource_dispatcher_host_delegate = LAZY_INSTANCE_INITIALIZER; -} +#if defined(OS_ANDROID) +#include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h" +#endif namespace xwalk { +// static +scoped_ptr +RuntimeResourceDispatcherHostDelegate::Create() { +#if defined(OS_ANDROID) + return make_scoped_ptr( + static_cast( + new RuntimeResourceDispatcherHostDelegateAndroid())); +#else + return make_scoped_ptr(new RuntimeResourceDispatcherHostDelegate()); +#endif +} + RuntimeResourceDispatcherHostDelegate::RuntimeResourceDispatcherHostDelegate() { } @@ -33,12 +44,6 @@ RuntimeResourceDispatcherHostDelegate:: ~RuntimeResourceDispatcherHostDelegate() { } -// static -void RuntimeResourceDispatcherHostDelegate::ResourceDispatcherHostCreated() { - content::ResourceDispatcherHost::Get()->SetDelegate( - &g_runtime_resource_dispatcher_host_delegate.Get()); -} - void RuntimeResourceDispatcherHostDelegate::RequestBeginning( net::URLRequest* request, content::ResourceContext* resource_context, @@ -62,6 +67,7 @@ bool RuntimeResourceDispatcherHostDelegate::HandleExternalProtocol( const GURL& url, int child_id, int route_id) { + platform_util::OpenExternal(url); return true; } diff --git a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h index c15eea9..b3f5544 100644 --- a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h +++ b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h @@ -16,6 +16,7 @@ class RuntimeResourceDispatcherHostDelegate virtual ~RuntimeResourceDispatcherHostDelegate(); static void ResourceDispatcherHostCreated(); + static scoped_ptr Create(); virtual void RequestBeginning( net::URLRequest* request, diff --git a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.cc b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.cc index 6bbcc49..ba63063 100644 --- a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.cc +++ b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.cc @@ -14,8 +14,6 @@ #include "components/navigation_interception/intercept_navigation_delegate.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_controller.h" -#include "content/public/browser/resource_dispatcher_host.h" -#include "content/public/browser/resource_dispatcher_host_login_delegate.h" #include "content/public/browser/resource_request_info.h" #include "content/public/browser/resource_throttle.h" #include "content/public/common/url_constants.h" @@ -27,16 +25,13 @@ #include "xwalk/runtime/browser/android/xwalk_contents_io_thread_client.h" #include "xwalk/runtime/browser/android/xwalk_download_resource_throttle.h" #include "xwalk/runtime/browser/android/xwalk_login_delegate.h" +#include "xwalk/runtime/browser/xwalk_content_browser_client.h" using content::BrowserThread; using navigation_interception::InterceptNavigationDelegate; using xwalk::XWalkContentsIoThreadClient; namespace { -base::LazyInstance - g_runtime_resource_dispatcher_host_delegate_android = - LAZY_INSTANCE_INITIALIZER; - void SetCacheControlFlag( net::URLRequest* request, int flag) { const int all_cache_control_flags = net::LOAD_BYPASS_CACHE | @@ -93,7 +88,8 @@ IoThreadClientThrottle::IoThreadClientThrottle(int render_process_id, IoThreadClientThrottle::~IoThreadClientThrottle() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - g_runtime_resource_dispatcher_host_delegate_android.Get(). + static_cast( + XWalkContentBrowserClient::Get()->resource_dispatcher_host_delegate())-> RemovePendingThrottleOnIoThread(this); } @@ -206,13 +202,6 @@ RuntimeResourceDispatcherHostDelegateAndroid:: ~RuntimeResourceDispatcherHostDelegateAndroid() { } -// static -void RuntimeResourceDispatcherHostDelegateAndroid:: -ResourceDispatcherHostCreated() { - content::ResourceDispatcherHost::Get()->SetDelegate( - &g_runtime_resource_dispatcher_host_delegate_android.Get()); -} - void RuntimeResourceDispatcherHostDelegateAndroid::RequestBeginning( net::URLRequest* request, content::ResourceContext* resource_context, @@ -358,7 +347,9 @@ void RuntimeResourceDispatcherHostDelegateAndroid::OnIoThreadClientReady( &RuntimeResourceDispatcherHostDelegateAndroid:: OnIoThreadClientReadyInternal, base::Unretained( - g_runtime_resource_dispatcher_host_delegate_android.Pointer()), + static_cast( + XWalkContentBrowserClient::Get()-> + resource_dispatcher_host_delegate())), new_render_process_id, new_render_frame_id)); } @@ -372,7 +363,9 @@ void RuntimeResourceDispatcherHostDelegateAndroid::AddPendingThrottle( &RuntimeResourceDispatcherHostDelegateAndroid:: AddPendingThrottleOnIoThread, base::Unretained( - g_runtime_resource_dispatcher_host_delegate_android.Pointer()), + static_cast( + XWalkContentBrowserClient::Get()-> + resource_dispatcher_host_delegate())), render_process_id, render_frame_id, pending_throttle)); } diff --git a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h index 0cb15e3..ce8dfb6 100644 --- a/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h +++ b/src/xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h @@ -8,7 +8,6 @@ #include #include -#include "base/lazy_instance.h" #include "content/public/browser/content_browser_client.h" #include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h" @@ -31,8 +30,6 @@ class RuntimeResourceDispatcherHostDelegateAndroid RuntimeResourceDispatcherHostDelegateAndroid(); virtual ~RuntimeResourceDispatcherHostDelegateAndroid(); - static void ResourceDispatcherHostCreated(); - virtual void RequestBeginning( net::URLRequest* request, content::ResourceContext* resource_context, @@ -69,8 +66,6 @@ class RuntimeResourceDispatcherHostDelegateAndroid int render_frame_id, IoThreadClientThrottle* pending_throttle); private: - friend struct base::DefaultLazyInstanceTraits< - RuntimeResourceDispatcherHostDelegateAndroid>; // These methods must be called on IO thread. void OnIoThreadClientReadyInternal(int new_render_process_id, int new_render_frame_id); diff --git a/src/xwalk/runtime/browser/runtime_ui_strategy.cc b/src/xwalk/runtime/browser/runtime_ui_strategy.cc new file mode 100644 index 0000000..a2de96c --- /dev/null +++ b/src/xwalk/runtime/browser/runtime_ui_strategy.cc @@ -0,0 +1,75 @@ +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xwalk/runtime/browser/runtime_ui_strategy.h" + +#include "base/command_line.h" +#include "grit/xwalk_resources.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image.h" +#include "xwalk/runtime/browser/image_util.h" +#include "xwalk/runtime/browser/runtime.h" +#include "xwalk/runtime/common/xwalk_switches.h" + +namespace xwalk { +namespace { +#if !defined(OS_ANDROID) +// The default size for web content area size. +const int kDefaultWidth = 840; +const int kDefaultHeight = 600; + +void ApplyWindowDefaultParams(Runtime* runtime, + NativeAppWindow::CreateParams* params) { + if (!params->delegate) + params->delegate = runtime; + if (!params->web_contents) + params->web_contents = runtime->web_contents(); + if (params->bounds.IsEmpty()) + params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight); + + unsigned int fullscreen_options = runtime->fullscreen_options(); + if (params->state == ui::SHOW_STATE_FULLSCREEN) + fullscreen_options |= Runtime::FULLSCREEN_FOR_LAUNCH; + else + fullscreen_options &= ~Runtime::FULLSCREEN_FOR_LAUNCH; + runtime->set_fullscreen_options(fullscreen_options); +} +#endif +} // namespace + +RuntimeUIStrategy::RuntimeUIStrategy() {} + +RuntimeUIStrategy::~RuntimeUIStrategy() {} + +void RuntimeUIStrategy::Show( + Runtime* runtime, const NativeAppWindow::CreateParams& params) { +#if defined(OS_ANDROID) + NOTIMPLEMENTED(); +#else + NativeAppWindow::CreateParams effective_params(params); + ApplyWindowDefaultParams(runtime, &effective_params); + + // Set the app icon if it is passed from command line. + CommandLine* command_line = CommandLine::ForCurrentProcess(); + gfx::Image app_icon; + if (command_line->HasSwitch(switches::kAppIcon)) { + base::FilePath icon_file = + command_line->GetSwitchValuePath(switches::kAppIcon); + app_icon = xwalk_utils::LoadImageFromFilePath(icon_file); + } else { + // Otherwise, use the default icon for Crosswalk app. + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + app_icon = rb.GetNativeImageNamed(IDR_XWALK_ICON_48); + } + + runtime->EnableTitleUpdatedNotification(); + + NativeAppWindow* window = NativeAppWindow::Create(effective_params); + runtime->set_window(window); + + runtime->set_app_icon(app_icon); + window->Show(); +#endif +} +} // namespace xwalk diff --git a/src/xwalk/runtime/browser/runtime_ui_strategy.h b/src/xwalk/runtime/browser/runtime_ui_strategy.h new file mode 100644 index 0000000..e01705c --- /dev/null +++ b/src/xwalk/runtime/browser/runtime_ui_strategy.h @@ -0,0 +1,23 @@ +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef XWALK_RUNTIME_BROWSER_RUNTIME_UI_STRATEGY_H_ +#define XWALK_RUNTIME_BROWSER_RUNTIME_UI_STRATEGY_H_ + +#include "xwalk/runtime/browser/ui/native_app_window.h" + +namespace xwalk { +class Runtime; + +class RuntimeUIStrategy { + public: + RuntimeUIStrategy(); + virtual ~RuntimeUIStrategy(); + virtual void Show(Runtime* runtime, + const NativeAppWindow::CreateParams& params); +}; + +} // namespace xwalk + +#endif // XWALK_RUNTIME_BROWSER_RUNTIME_UI_STRATEGY_H_ diff --git a/src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.cc b/src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.cc new file mode 100644 index 0000000..73bea4f --- /dev/null +++ b/src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.cc @@ -0,0 +1,258 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xwalk/runtime/browser/tizen/render_view_context_menu_impl.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/renderer_context_menu/views/toolkit_delegate_views.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/web_contents.h" +#include "third_party/WebKit/public/web/WebContextMenuData.h" + +namespace xwalk { +using blink::WebContextMenuData; + +namespace { + +enum { + // Nativation + CMD_BACK = 0, + CMD_FORWARD, + CMD_RELOAD, + + // Link + CMD_OPEN_LINK_NEW_ACTIVITY, + + // Edit + CMD_UNDO, + CMD_REDO, + CMD_CUT, + CMD_COPY, + CMD_PASTE, + CMD_PASTE_AND_MATCH_STYLE, + CMD_DELETE, + CMD_SELECT_ALL, + CMD_LAST, +}; + +// Max number of custom command ids allowd. +const int kNumCustomCommandIds = 1000; + +// TODO(oshima): Move IDS for context menus to components/renderer_context_menu +// and replace hardcoded strings below. +void AppendPageItems(ui::SimpleMenuModel* menu_model) { + menu_model->AddItem(CMD_BACK, base::ASCIIToUTF16("Back")); + menu_model->AddItem(CMD_FORWARD, base::ASCIIToUTF16("Forward")); + menu_model->AddItem(CMD_RELOAD, base::ASCIIToUTF16("Reload")); + menu_model->AddSeparator(ui::NORMAL_SEPARATOR); +} + +void AppendLinkItems(const content::ContextMenuParams& params, + ui::SimpleMenuModel* menu_model) { + if (!params.link_url.is_empty()) + menu_model->AddItem(CMD_OPEN_LINK_NEW_ACTIVITY, + base::ASCIIToUTF16("Open Link")); +} + +void AppendEditableItems(ui::SimpleMenuModel* menu_model) { + menu_model->AddItem(CMD_UNDO, base::ASCIIToUTF16("Undo")); + menu_model->AddItem(CMD_REDO, base::ASCIIToUTF16("Redo")); + menu_model->AddSeparator(ui::NORMAL_SEPARATOR); + menu_model->AddItem(CMD_CUT, base::ASCIIToUTF16("Cut")); + menu_model->AddItem(CMD_COPY, base::ASCIIToUTF16("Copy")); + menu_model->AddItem(CMD_PASTE, base::ASCIIToUTF16("Paste")); + menu_model->AddItem(CMD_PASTE_AND_MATCH_STYLE, + base::ASCIIToUTF16("Paste as plain text")); + menu_model->AddItem(CMD_DELETE, base::ASCIIToUTF16("Delete")); + menu_model->AddSeparator(ui::NORMAL_SEPARATOR); + menu_model->AddItem(CMD_SELECT_ALL, base::ASCIIToUTF16("Select All")); +} + +} // namespace + +RenderViewContextMenuImpl::RenderViewContextMenuImpl( + content::RenderFrameHost* render_frame_host, + const content::ContextMenuParams& params) + : RenderViewContextMenuBase(render_frame_host, params) { + SetContentCustomCommandIdRange(CMD_LAST, CMD_LAST + kNumCustomCommandIds); + // TODO(oshima): Support other types + set_content_type( + new ContextMenuContentType(source_web_contents_, params, true)); + set_toolkit_delegate(scoped_ptr(new ToolkitDelegateViews)); +} + +RenderViewContextMenuImpl::~RenderViewContextMenuImpl() { +} + +void RenderViewContextMenuImpl::RunMenuAt(views::Widget* parent, + const gfx::Point& point, + ui::MenuSourceType type) { + static_cast(toolkit_delegate()) + ->RunMenuAt(parent, point, type); +} + +void RenderViewContextMenuImpl::InitMenu() { + RenderViewContextMenuBase::InitMenu(); + bool needs_separator = false; + if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PAGE)) { + AppendPageItems(&menu_model_); + needs_separator = true; + } + + if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_LINK)) { + if (needs_separator) + AddSeparator(); + AppendLinkItems(params_, &menu_model_); + needs_separator = true; + } + + if (content_type_->SupportsGroup( + ContextMenuContentType::ITEM_GROUP_EDITABLE)) { + if (needs_separator) + AddSeparator(); + AppendEditableItems(&menu_model_); + } +} + +void RenderViewContextMenuImpl::RecordShownItem(int id) { + // TODO(oshima): Imelement UMA stats. crbug.com/401673 + NOTIMPLEMENTED(); +} + +void RenderViewContextMenuImpl::RecordUsedItem(int id) { + // TODO(oshima): Imelement UMA stats. crbug.com/401673 + NOTIMPLEMENTED(); +} + +void RenderViewContextMenuImpl::NotifyMenuShown() { +} + +void RenderViewContextMenuImpl::NotifyURLOpened( + const GURL& url, + content::WebContents* new_contents) { +} + +bool RenderViewContextMenuImpl::GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) { + NOTIMPLEMENTED(); + return false; +} + +bool RenderViewContextMenuImpl::IsCommandIdChecked(int command_id) const { + return false; +} + +bool RenderViewContextMenuImpl::IsCommandIdEnabled(int command_id) const { + { + bool enabled = false; + if (RenderViewContextMenuBase::IsCommandIdKnown(command_id, &enabled)) + return enabled; + } + switch (command_id) { + // Navigation + case CMD_BACK: + return source_web_contents_->GetController().CanGoBack(); + case CMD_FORWARD: + return source_web_contents_->GetController().CanGoForward(); + case CMD_RELOAD: + return true; + + // Link + case CMD_OPEN_LINK_NEW_ACTIVITY: + return params_.link_url.is_valid(); + + // Editable + case CMD_UNDO: + return !!(params_.edit_flags & WebContextMenuData::CanUndo); + + case CMD_REDO: + return !!(params_.edit_flags & WebContextMenuData::CanRedo); + + case CMD_CUT: + return !!(params_.edit_flags & WebContextMenuData::CanCut); + + case CMD_COPY: + return !!(params_.edit_flags & WebContextMenuData::CanCopy); + + case CMD_PASTE: + case CMD_PASTE_AND_MATCH_STYLE: + return !!(params_.edit_flags & WebContextMenuData::CanPaste); + + case CMD_DELETE: + return !!(params_.edit_flags & WebContextMenuData::CanDelete); + + case CMD_SELECT_ALL: + return !!(params_.edit_flags & WebContextMenuData::CanSelectAll); + } + return false; +} + +void RenderViewContextMenuImpl::ExecuteCommand(int command_id, + int event_flags) { + RenderViewContextMenuBase::ExecuteCommand(command_id, event_flags); + if (command_executed_) + return; + command_executed_ = true; + switch (command_id) { + // Navigation + case CMD_BACK: + source_web_contents_->GetController().GoBack(); + break; + case CMD_FORWARD: + source_web_contents_->GetController().GoForward(); + break; + case CMD_RELOAD: + source_web_contents_->GetController().Reload(true); + break; + + // Link + case CMD_OPEN_LINK_NEW_ACTIVITY: + OpenURL( + params_.link_url, + params_.frame_url.is_empty() ? params_.page_url : params_.frame_url, + NEW_WINDOW, + ui::PAGE_TRANSITION_LINK); + break; + + // Editable + case CMD_UNDO: + source_web_contents_->Undo(); + break; + + case CMD_REDO: + source_web_contents_->Redo(); + break; + + case CMD_CUT: + source_web_contents_->Cut(); + break; + + case CMD_COPY: + source_web_contents_->Copy(); + break; + + case CMD_PASTE: + source_web_contents_->Paste(); + break; + + case CMD_PASTE_AND_MATCH_STYLE: + source_web_contents_->PasteAndMatchStyle(); + break; + + case CMD_DELETE: + source_web_contents_->Delete(); + break; + + case CMD_SELECT_ALL: + source_web_contents_->SelectAll(); + break; + } +} + +void RenderViewContextMenuImpl::HandleAuthorizeAllPlugins() { +} + +} // namespace xwalk diff --git a/src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.h b/src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.h new file mode 100644 index 0000000..bac1c58 --- /dev/null +++ b/src/xwalk/runtime/browser/tizen/render_view_context_menu_impl.h @@ -0,0 +1,54 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef XWALK_RUNTIME_BROWSER_TIZEN_RENDER_VIEW_CONTEXT_MENU_IMPL_H_ +#define XWALK_RUNTIME_BROWSER_TIZEN_RENDER_VIEW_CONTEXT_MENU_IMPL_H_ + +#include "components/renderer_context_menu/render_view_context_menu_base.h" + +namespace views { +class Widget; +} + +namespace gfx { +class Point; +} + +namespace xwalk { + +class RenderViewContextMenuImpl : public RenderViewContextMenuBase { + public: + RenderViewContextMenuImpl(content::RenderFrameHost* render_frame_host, + const content::ContextMenuParams& params); + virtual ~RenderViewContextMenuImpl(); + + void RunMenuAt(views::Widget* parent, + const gfx::Point& point, + ui::MenuSourceType type); + + private: + // RenderViewContextMenuBase: + void InitMenu() override; + void RecordShownItem(int id) override; + void RecordUsedItem(int id) override; + void NotifyMenuShown() override; + void NotifyURLOpened(const GURL& url, + content::WebContents* new_contents) override; + void HandleAuthorizeAllPlugins() override; + + // ui::SimpleMenuModel: + bool GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) override; + bool IsCommandIdChecked(int command_id) const override; + bool IsCommandIdEnabled(int command_id) const override; + void ExecuteCommand(int command_id, int event_flags) override; + + DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenuImpl); +}; + +} // namespace xwalk + +#endif // XWALK_RUNTIME_BROWSER_TIZEN_RENDER_VIEW_CONTEXT_MENU_IMPL_H_ diff --git a/src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.cc b/src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.cc new file mode 100644 index 0000000..b21d4f0 --- /dev/null +++ b/src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.cc @@ -0,0 +1,169 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h" + +#include "components/web_modal/popup_manager.h" +#include "components/web_modal/single_web_contents_dialog_manager.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_view_delegate.h" +#include "ui/aura/client/screen_position_client.h" +#include "ui/aura/window.h" +#include "xwalk/application/browser/application.h" +#include "xwalk/application/browser/application_system.h" +#include "xwalk/application/browser/application_service.h" +#include "xwalk/application/common/application_manifest_constants.h" +#include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h" +#include "xwalk/runtime/browser/xwalk_runner.h" + +namespace xwalk { +namespace { + +scoped_ptr BuildMenu( + content::WebContents* web_contents, + const content::ContextMenuParams& params) { + scoped_ptr menu; + content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame(); + // If the frame tree does not have a focused frame at this point, do not + // bother creating RenderViewContextMenuViews. + // This happens if the frame has navigated to a different page before + // ContextMenu message was received by the current RenderFrameHost. + if (focused_frame) { + menu.reset(new RenderViewContextMenuImpl(focused_frame, params)); + menu->Init(); + } + return menu.Pass(); +} +} // namespace + +XWalkWebContentsViewDelegate::XWalkWebContentsViewDelegate( + content::WebContents* web_contents, + xwalk::application::ApplicationService* app_service) + : web_contents_(web_contents), + app_service_(app_service) { +} + +XWalkWebContentsViewDelegate::~XWalkWebContentsViewDelegate() { +} + +void XWalkWebContentsViewDelegate::ShowContextMenu( + content::RenderFrameHost* render_frame_host, + const content::ContextMenuParams& params) { + int render_process_id = render_frame_host->GetProcess()->GetID(); + application::Application* app = XWalkRunner::GetInstance()->app_system()-> + application_service()->GetApplicationByRenderHostID(render_process_id); + if (!app) + return; + + application::TizenSettingInfo* info = + static_cast( + app->data()->GetManifestData( + application_widget_keys::kTizenSettingKey)); + if (info && !info->context_menu_enabled()) + return; + + ShowMenu(BuildMenu( + content::WebContents::FromRenderFrameHost(render_frame_host), params)); +} + +content::WebDragDestDelegate* +XWalkWebContentsViewDelegate::GetDragDestDelegate() { + return NULL; +} + +void XWalkWebContentsViewDelegate::StoreFocus() { +} + +void XWalkWebContentsViewDelegate::RestoreFocus() { +} + +bool XWalkWebContentsViewDelegate::Focus() { + web_modal::PopupManager* popup_manager = + web_modal::PopupManager::FromWebContents(web_contents_); + if (popup_manager) + popup_manager->WasFocused(web_contents_); + return false; +} + +void XWalkWebContentsViewDelegate::TakeFocus(bool reverse) { +} + +void XWalkWebContentsViewDelegate::SizeChanged(const gfx::Size& size) { +} + +void* XWalkWebContentsViewDelegate::CreateRenderWidgetHostViewDelegate( + content::RenderWidgetHost* render_widget_host) { + return NULL; +} + +void XWalkWebContentsViewDelegate::ShowMenu( + scoped_ptr menu) { + context_menu_.reset(menu.release()); + + if (!context_menu_.get()) + return; + + // Menus need a Widget to work. If we're not the active tab we won't + // necessarily be in a widget. + views::Widget* top_level_widget = GetTopLevelWidget(); + if (!top_level_widget) + return; + + const content::ContextMenuParams& params = context_menu_->params(); + // Don't show empty menus. + if (context_menu_->menu_model().GetItemCount() == 0) + return; + + gfx::Point screen_point(params.x, params.y); + + // Convert from target window coordinates to root window coordinates. + aura::Window* target_window = GetActiveNativeView(); + aura::Window* root_window = target_window->GetRootWindow(); + aura::client::ScreenPositionClient* screen_position_client = + aura::client::GetScreenPositionClient(root_window); + if (screen_position_client) { + screen_position_client->ConvertPointToScreen(target_window, + &screen_point); + } + // Enable recursive tasks on the message loop so we can get updates while + // the context menu is being displayed. + base::MessageLoop::ScopedNestableTaskAllower allow( + base::MessageLoop::current()); + context_menu_->RunMenuAt( + top_level_widget, screen_point, params.source_type); +} + +aura::Window* XWalkWebContentsViewDelegate::GetActiveNativeView() { + return web_contents_->GetFullscreenRenderWidgetHostView() + ? web_contents_->GetFullscreenRenderWidgetHostView() + ->GetNativeView() + : web_contents_->GetNativeView(); +} + +views::Widget* XWalkWebContentsViewDelegate::GetTopLevelWidget() { + return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView()); +} + +views::FocusManager* XWalkWebContentsViewDelegate::GetFocusManager() { + views::Widget* toplevel_widget = GetTopLevelWidget(); + return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL; +} + +void XWalkWebContentsViewDelegate::SetInitialFocus() { + if (web_contents_->FocusLocationBarByDefault()) { + if (web_contents_->GetDelegate()) + web_contents_->GetDelegate()->SetFocusToLocationBar(false); + } else { + web_contents_->Focus(); + } +} + +} // namespace xwalk diff --git a/src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h b/src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h new file mode 100644 index 0000000..6c7a662 --- /dev/null +++ b/src/xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h @@ -0,0 +1,66 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright (c) 2014 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef XWALK_RUNTIME_BROWSER_TIZEN_XWALK_WEB_CONTENTS_VIEW_DELEGATE_H_ +#define XWALK_RUNTIME_BROWSER_TIZEN_XWALK_WEB_CONTENTS_VIEW_DELEGATE_H_ + +#include "content/public/browser/web_drag_dest_delegate.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_view_delegate.h" +#include "content/public/common/context_menu_params.h" +#include "ui/views/widget/widget.h" +#include "xwalk/application/browser/application_service.h" +#include "xwalk/runtime/browser/tizen/render_view_context_menu_impl.h" + +namespace xwalk { + +class XWalkWebContentsViewDelegate : public content::WebContentsViewDelegate { + public: + XWalkWebContentsViewDelegate( + content::WebContents* web_contents, + xwalk::application::ApplicationService* app_service); + virtual ~XWalkWebContentsViewDelegate(); + + // Overridden from WebContentsViewDelegate: + void ShowContextMenu(content::RenderFrameHost* render_frame_host, + const content::ContextMenuParams& params) override; + content::WebDragDestDelegate* GetDragDestDelegate() override; + void StoreFocus() override; + void RestoreFocus() override; + bool Focus() override; + void TakeFocus(bool reverse) override; + void SizeChanged(const gfx::Size& size) override; + virtual void* CreateRenderWidgetHostViewDelegate( + content::RenderWidgetHost* render_widget_host); + +#if defined(TOOLKIT_VIEWS) || defined(USE_AURA) + void ShowDisambiguationPopup( + const gfx::Rect& target_rect, + const SkBitmap& zoomed_bitmap, + const gfx::NativeView content, + const base::Callback& gesture_cb, + const base::Callback& mouse_cb) override { + NOTIMPLEMENTED(); + } + + void HideDisambiguationPopup() override { NOTIMPLEMENTED(); } +#endif + + private: + aura::Window* GetActiveNativeView(); + views::Widget* GetTopLevelWidget(); + views::FocusManager* GetFocusManager(); + void SetInitialFocus(); + void ShowMenu(scoped_ptr menu); + + content::WebContents* web_contents_; + xwalk::application::ApplicationService* app_service_; + scoped_ptr context_menu_; + + DISALLOW_COPY_AND_ASSIGN(XWalkWebContentsViewDelegate); +}; +} // namespace xwalk + +#endif // XWALK_RUNTIME_BROWSER_TIZEN_XWALK_WEB_CONTENTS_VIEW_DELEGATE_H_ diff --git a/src/xwalk/runtime/browser/ui/native_app_window_views.cc b/src/xwalk/runtime/browser/ui/native_app_window_views.cc index b1542f3..1cb3540 100644 --- a/src/xwalk/runtime/browser/ui/native_app_window_views.cc +++ b/src/xwalk/runtime/browser/ui/native_app_window_views.cc @@ -231,6 +231,10 @@ bool NativeAppWindowViews::CanMaximize() const { return resizable_ && maximum_size_.IsEmpty(); } +bool NativeAppWindowViews::CanMinimize() const { + return true; +} + #if defined(OS_WIN) views::NonClientFrameView* NativeAppWindowViews::CreateNonClientFrameView( views::Widget* widget) { diff --git a/src/xwalk/runtime/browser/ui/native_app_window_views.h b/src/xwalk/runtime/browser/ui/native_app_window_views.h index a234458..c971570 100644 --- a/src/xwalk/runtime/browser/ui/native_app_window_views.h +++ b/src/xwalk/runtime/browser/ui/native_app_window_views.h @@ -78,6 +78,7 @@ class NativeAppWindowViews : public NativeAppWindow, gfx::Rect* bounds, ui::WindowShowState* show_state) const OVERRIDE; virtual bool CanResize() const OVERRIDE; virtual bool CanMaximize() const OVERRIDE; + virtual bool CanMinimize() const OVERRIDE; #if defined(OS_WIN) virtual views::NonClientFrameView* CreateNonClientFrameView( views::Widget* widget) OVERRIDE; diff --git a/src/xwalk/runtime/browser/xwalk_app_extension_bridge.cc b/src/xwalk/runtime/browser/xwalk_app_extension_bridge.cc index c50493d..7b10e55 100644 --- a/src/xwalk/runtime/browser/xwalk_app_extension_bridge.cc +++ b/src/xwalk/runtime/browser/xwalk_app_extension_bridge.cc @@ -6,6 +6,7 @@ #include +#include "content/public/browser/browser_thread.h" #include "xwalk/application/browser/application.h" #include "xwalk/application/browser/application_service.h" #include "xwalk/application/browser/application_system.h" @@ -15,6 +16,7 @@ #include "xwalk/application/browser/application_service_provider_linux.h" #include "xwalk/application/browser/linux/running_application_object.h" #endif +#include "xwalk/runtime/browser/runtime_defered_ui_strategy.h" namespace xwalk { @@ -79,4 +81,21 @@ void XWalkAppExtensionBridge::ExtensionProcessCreated( #endif } +void XWalkAppExtensionBridge::RenderChannelCreated( + int render_process_id) { + CHECK(app_system_); + application::ApplicationService *service = + app_system_->application_service(); + application::Application *app = + service->GetApplicationByRenderHostID(render_process_id); + if (!app) + return; + + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind( + &RuntimeDeferedUIStrategy::ShowStoredRuntimes, + base::Unretained(ToRuntimeDeferedUIStrategy(app->ui_strategy())))); +} } // namespace xwalk diff --git a/src/xwalk/runtime/browser/xwalk_app_extension_bridge.h b/src/xwalk/runtime/browser/xwalk_app_extension_bridge.h index 324dd32..73c019c 100644 --- a/src/xwalk/runtime/browser/xwalk_app_extension_bridge.h +++ b/src/xwalk/runtime/browser/xwalk_app_extension_bridge.h @@ -42,6 +42,7 @@ class XWalkAppExtensionBridge virtual void ExtensionProcessCreated( int render_process_id, const IPC::ChannelHandle& channel_handle) OVERRIDE; + virtual void RenderChannelCreated(int render_process_id) OVERRIDE; private: application::ApplicationSystem* app_system_; diff --git a/src/xwalk/runtime/browser/xwalk_content_browser_client.cc b/src/xwalk/runtime/browser/xwalk_content_browser_client.cc index d36821c..c5743e2 100644 --- a/src/xwalk/runtime/browser/xwalk_content_browser_client.cc +++ b/src/xwalk/runtime/browser/xwalk_content_browser_client.cc @@ -17,6 +17,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/resource_context.h" +#include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/main_function_params.h" @@ -51,7 +52,6 @@ #include "xwalk/runtime/browser/android/xwalk_cookie_access_policy.h" #include "xwalk/runtime/browser/android/xwalk_contents_client_bridge.h" #include "xwalk/runtime/browser/android/xwalk_web_contents_view_delegate.h" -#include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h" #include "xwalk/runtime/browser/xwalk_browser_main_parts_android.h" #include "xwalk/runtime/common/android/xwalk_globals_android.h" #else @@ -68,6 +68,7 @@ #include "xwalk/application/common/application_manifest_constants.h" #include "xwalk/application/common/manifest_handlers/navigation_handler.h" #include "xwalk/runtime/browser/runtime_platform_util.h" +#include "xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h" #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h" #endif @@ -168,6 +169,9 @@ XWalkContentBrowserClient::GetWebContentsViewDelegate( content::WebContents* web_contents) { #if defined(OS_ANDROID) return new XWalkWebContentsViewDelegate(web_contents); +#elif defined(OS_TIZEN) + return new XWalkWebContentsViewDelegate( + web_contents, xwalk_runner_->app_system()->application_service()); #else return NULL; #endif @@ -348,12 +352,12 @@ content::BrowserPpapiHost* return NULL; } -#if defined(OS_ANDROID) void XWalkContentBrowserClient::ResourceDispatcherHostCreated() { - RuntimeResourceDispatcherHostDelegateAndroid:: - ResourceDispatcherHostCreated(); + resource_dispatcher_host_delegate_ = + (RuntimeResourceDispatcherHostDelegate::Create()).Pass(); + content::ResourceDispatcherHost::Get()->SetDelegate( + resource_dispatcher_host_delegate_.get()); } -#endif content::SpeechRecognitionManagerDelegate* XWalkContentBrowserClient::GetSpeechRecognitionManagerDelegate() { diff --git a/src/xwalk/runtime/browser/xwalk_content_browser_client.h b/src/xwalk/runtime/browser/xwalk_content_browser_client.h index 42bb3c3..6018266 100644 --- a/src/xwalk/runtime/browser/xwalk_content_browser_client.h +++ b/src/xwalk/runtime/browser/xwalk_content_browser_client.h @@ -12,6 +12,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/common/main_function_params.h" #include "xwalk/runtime/browser/runtime_geolocation_permission_context.h" +#include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate.h" namespace content { class BrowserContext; @@ -136,8 +137,8 @@ class XWalkContentBrowserClient : public content::ContentBrowserClient { virtual content::BrowserPpapiHost* GetExternalBrowserPpapiHost( int plugin_process_id) OVERRIDE; -#if defined(OS_ANDROID) - virtual void ResourceDispatcherHostCreated(); +#if defined(OS_ANDROID) || defined(OS_TIZEN) || defined(OS_LINUX) + virtual void ResourceDispatcherHostCreated() OVERRIDE; #endif virtual void GetStoragePartitionConfigForSite( @@ -153,6 +154,12 @@ class XWalkContentBrowserClient : public content::ContentBrowserClient { XWalkBrowserMainParts* main_parts() { return main_parts_; } +#if defined(OS_ANDROID) + RuntimeResourceDispatcherHostDelegate* resource_dispatcher_host_delegate() { + return resource_dispatcher_host_delegate_.get(); + } +#endif + private: XWalkRunner* xwalk_runner_; net::URLRequestContextGetter* url_request_context_getter_; @@ -161,6 +168,9 @@ class XWalkContentBrowserClient : public content::ContentBrowserClient { XWalkBrowserMainParts* main_parts_; RuntimeContext* runtime_context_; + scoped_ptr + resource_dispatcher_host_delegate_; + DISALLOW_COPY_AND_ASSIGN(XWalkContentBrowserClient); }; diff --git a/src/xwalk/runtime/browser/xwalk_runtime_browsertest.cc b/src/xwalk/runtime/browser/xwalk_runtime_browsertest.cc index 4c4ba30..cd5186c 100644 --- a/src/xwalk/runtime/browser/xwalk_runtime_browsertest.cc +++ b/src/xwalk/runtime/browser/xwalk_runtime_browsertest.cc @@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "xwalk/runtime/browser/image_util.h" #include "xwalk/runtime/browser/runtime.h" +#include "xwalk/runtime/browser/runtime_ui_strategy.h" #include "xwalk/runtime/common/xwalk_notification_types.h" #include "xwalk/test/base/in_process_browser_test.h" #include "xwalk/test/base/xwalk_test_utils.h" @@ -38,6 +39,21 @@ using xwalk::Runtime; using content::WebContents; using testing::_; +namespace { +Runtime* CreateWithDefaultWindow( + xwalk::RuntimeContext* runtime_context, const GURL& url, + Runtime::Observer* observer = NULL) { + Runtime* runtime = Runtime::Create(runtime_context, observer); + runtime->LoadURL(url); +#if !defined(OS_ANDROID) + xwalk::RuntimeUIStrategy ui_strategy; + xwalk::NativeAppWindow::CreateParams params; + ui_strategy.Show(runtime, params); +#endif + return runtime; +} +} // namespace + // Observer for NOTIFICATION_FULLSCREEN_CHANGED notifications. class FullscreenNotificationObserver : public content::WindowedNotificationObserver { @@ -109,7 +125,7 @@ IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, CreateAndCloseRuntime) { // Create a new Runtime instance. GURL url(test_server()->GetURL("test.html")); - Runtime* new_runtime = Runtime::CreateWithDefaultWindow( + Runtime* new_runtime = CreateWithDefaultWindow( GetRuntimeContext(), url, runtime_registry()); EXPECT_TRUE(url == new_runtime->web_contents()->GetURL()); EXPECT_EQ(new_runtime, WaitForSingleNewRuntime()); @@ -135,7 +151,7 @@ IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, LoadURLAndClose) { IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, CloseNativeWindow) { GURL url(test_server()->GetURL("test.html")); - Runtime* new_runtime = Runtime::CreateWithDefaultWindow( + Runtime* new_runtime = CreateWithDefaultWindow( GetRuntimeContext(), url, runtime_registry()); size_t len = runtimes().size(); new_runtime->window()->Close(); @@ -151,7 +167,9 @@ IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, LaunchWithFullscreenWindow) { NativeAppWindow::CreateParams params; params.state = ui::SHOW_STATE_FULLSCREEN; - new_runtime->AttachWindow(params); + scoped_ptr ui_strategy( + new xwalk::RuntimeUIStrategy); + ui_strategy->Show(new_runtime, params); xwalk_test_utils::NavigateToURL(new_runtime, url); EXPECT_TRUE(new_runtime->window()->IsFullscreen()); diff --git a/src/xwalk/runtime/common/android/xwalk_render_view_messages.h b/src/xwalk/runtime/common/android/xwalk_render_view_messages.h index df898d1..5adbbfc 100644 --- a/src/xwalk/runtime/common/android/xwalk_render_view_messages.h +++ b/src/xwalk/runtime/common/android/xwalk_render_view_messages.h @@ -10,6 +10,7 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_message_macros.h" #include "ipc/ipc_platform_file.h" +#include "third_party/skia/include/core/SkColor.h" // Singly-included section for enums and custom IPC traits. #ifndef XWALK_RUNTIME_COMMON_ANDROID_XWALK_RENDER_VIEW_MESSAGES_H_ @@ -84,6 +85,10 @@ IPC_MESSAGE_CONTROL2(XWalkViewMsg_SetOriginAccessWhitelist, // NOLINT(*) std::string /* base url */, std::string /* match pattern content*/) +// Set the background color +IPC_MESSAGE_ROUTED1(XWalkViewMsg_SetBackgroundColor, // NOLINT(*) + SkColor) + //----------------------------------------------------------------------------- // RenderView messages // These are messages sent from the renderer to the browser process. diff --git a/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.cc b/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.cc index 359316e..27a226f 100644 --- a/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.cc +++ b/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.cc @@ -149,6 +149,7 @@ bool XWalkRenderViewExt::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(XWalkViewMsg_ResetScrollAndScaleState, OnResetScrollAndScaleState) IPC_MESSAGE_HANDLER(XWalkViewMsg_SetInitialPageScale, OnSetInitialPageScale) + IPC_MESSAGE_HANDLER(XWalkViewMsg_SetBackgroundColor, OnSetBackgroundColor) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -261,4 +262,10 @@ void XWalkRenderViewExt::OnSetInitialPageScale(double page_scale_factor) { page_scale_factor); } +void XWalkRenderViewExt::OnSetBackgroundColor(SkColor c) { + if (!render_view() || !render_view()->GetWebView()) + return; + render_view()->GetWebView()->setBaseBackgroundColor(c); +} + } // namespace xwalk diff --git a/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.h b/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.h index 44ae82d..78d5ae0 100644 --- a/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.h +++ b/src/xwalk/runtime/renderer/android/xwalk_render_view_ext.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "content/public/renderer/render_view_observer.h" +#include "third_party/skia/include/core/SkColor.h" #include "third_party/WebKit/public/web/WebPermissionClient.h" namespace blink { @@ -15,7 +16,7 @@ namespace blink { class WebNode; class WebURL; -} // namespace WebKit +} // namespace blink namespace xwalk { @@ -49,7 +50,7 @@ class XWalkRenderViewExt : public content::RenderViewObserver { void UpdatePageScaleFactor(); - bool capture_picture_enabled_; + void OnSetBackgroundColor(SkColor c); float page_scale_factor_; diff --git a/src/xwalk/runtime/resources/devtools_discovery_page.html b/src/xwalk/runtime/resources/devtools_discovery_page.html index b98d39e..966fd58 100644 --- a/src/xwalk/runtime/resources/devtools_discovery_page.html +++ b/src/xwalk/runtime/resources/devtools_discovery_page.html @@ -39,6 +39,7 @@ body { border-radius: 5px; height: 132px; width: 212px; + -webkit-background-size: cover; -webkit-transition-property: background-color, border-color; -webkit-transition: background-color 0.15s, 0.15s; -webkit-transition-delay: 0, 0; @@ -114,6 +115,8 @@ function appendItem(itemObject) { var thumbnail = document.createElement('div'); thumbnail.className = itemObject.devtoolsFrontendUrl ? 'thumbnail' : 'thumbnail connected'; + if (itemObject.thumbnailUrl === undefined) + itemObject.thumbnailUrl = "/thumb/" + itemObject.id; thumbnail.style.cssText = 'background-image:url(' + itemObject.thumbnailUrl + ')'; diff --git a/src/xwalk/sysapps/raw_socket/udp_socket_object.cc b/src/xwalk/sysapps/raw_socket/udp_socket_object.cc index c974e65..cc3f9f7 100644 --- a/src/xwalk/sysapps/raw_socket/udp_socket_object.cc +++ b/src/xwalk/sysapps/raw_socket/udp_socket_object.cc @@ -28,6 +28,7 @@ UDPSocketObject::UDPSocketObject() is_reading_(false), read_buffer_(new net::IOBuffer(kBufferSize)), write_buffer_(new net::IOBuffer(kBufferSize)), + write_buffer_size_(0), resolver_(net::HostResolver::CreateDefaultResolver(NULL)), single_resolver_(new net::SingleRequestHostResolver(resolver_.get())) { handler_.Register("init", diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnCreateWindowRequestedTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnCreateWindowRequestedTest.java new file mode 100644 index 0000000..3a4e3ae --- /dev/null +++ b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnCreateWindowRequestedTest.java @@ -0,0 +1,53 @@ +// Copyright (c) 2014 Intel Corporation. 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.xwalk.core.xwview.test; + +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; +import android.webkit.ValueCallback; + +import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.Feature; +import org.xwalk.core.XWalkUIClient; +import org.xwalk.core.XWalkView; + +/** + * Test suite for OnCreateWindowRequested(). + */ +public class OnCreateWindowRequestedTest extends XWalkViewTestBase { + private TestHelperBridge.OnCreateWindowRequestedHelper mOnCreateWindowRequestedHelper; + + @Override + public void setUp() throws Exception { + super.setUp(); + + mOnCreateWindowRequestedHelper = mTestHelperBridge.getOnCreateWindowRequestedHelper(); + + setUIClient(new XWalkUIClient(getXWalkView()){ + @Override + public boolean onCreateWindowRequested(XWalkView view, InitiateBy initiator, + ValueCallback callback) { + Log.d("XWalkView", "onCreateWindowRequested: " + initiator); + XWalkView newView = new XWalkView(getActivity(), getActivity()); + + callback.onReceiveValue(newView); + mOnCreateWindowRequestedHelper.notifyCalled(newView); + return true; + } + + }); + } + + @DisabledTest + public void testOnCreateWindowRequested() throws Throwable { + String fileContent = getFileContent("create_window_1.html"); + int count = mOnCreateWindowRequestedHelper.getCallCount(); + + loadDataAsync(null, fileContent, "text/html", false); + clickOnElementId("new_window", null); + mOnCreateWindowRequestedHelper.waitForCallback(count); + assertNotNull(mOnCreateWindowRequestedHelper.getXWalkView()); + } +} diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnReceivedIconTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnReceivedIconTest.java new file mode 100644 index 0000000..46f1778 --- /dev/null +++ b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnReceivedIconTest.java @@ -0,0 +1,53 @@ +// Copyright (c) 2014 Intel Corporation. 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.xwalk.core.xwview.test; + +import android.graphics.Bitmap; +import android.os.Message; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.Feature; +import org.xwalk.core.XWalkUIClient; +import org.xwalk.core.XWalkView; + +/** + * Test suite for OnReceivedIcon(). + */ +public class OnReceivedIconTest extends XWalkViewTestBase { + private TestHelperBridge.OnReceivedIconHelper mOnReceivedIconHelper; + + @Override + public void setUp() throws Exception { + super.setUp(); + + mOnReceivedIconHelper = mTestHelperBridge.getOnReceivedIconHelper(); + + setUIClient(new XWalkUIClient(getXWalkView()){ + @Override + public void onIconAvailable(XWalkView view, String url, Message msg) { + Log.d("XWalkView", "onIconAvailable"); + msg.sendToTarget(); + } + + @Override + public void onReceivedIcon(XWalkView view, String url, Bitmap icon) { + Log.d("XWalkView", "onReceivedIcon"); + mOnReceivedIconHelper.notifyCalled(icon); + } + }); + } + + @DisabledTest + public void testOnReceivedIcon() throws Throwable { + String fileContent = getFileContent("favicon.html"); + int count = mOnReceivedIconHelper.getCallCount(); + + loadDataAsync(null, fileContent, "text/html", false); + mOnReceivedIconHelper.waitForCallback(count); + assertNotNull(mOnReceivedIconHelper.getIcon()); + } +} diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/TestHelperBridge.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/TestHelperBridge.java index a5bed93..61601c1 100644 --- a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/TestHelperBridge.java +++ b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/TestHelperBridge.java @@ -5,6 +5,7 @@ package org.xwalk.core.xwview.test; +import android.graphics.Bitmap; import android.net.Uri; import android.util.Log; import android.view.KeyEvent; @@ -279,6 +280,34 @@ class TestHelperBridge { } } + public class OnCreateWindowRequestedHelper extends CallbackHelper { + private XWalkView mXWalkView; + + public XWalkView getXWalkView() { + assert getCallCount() > 0; + return mXWalkView; + } + + public void notifyCalled(XWalkView view) { + mXWalkView = view; + notifyCalled(); + } + } + + public class OnReceivedIconHelper extends CallbackHelper { + private Bitmap mIcon; + + public Bitmap getIcon() { + assert getCallCount() > 0; + return mIcon; + } + + public void notifyCalled(Bitmap icon) { + mIcon = icon; + notifyCalled(); + } + } + private String mChangedTitle; private LoadStatus mLoadStatus; private final OnPageStartedHelper mOnPageStartedHelper; @@ -299,6 +328,8 @@ class TestHelperBridge { private final OpenFileChooserHelper mOpenFileChooserHelper; private final OnFullscreenToggledHelper mOnFullscreenToggledHelper; private final OverrideOrUnhandledKeyEventHelper mOverrideOrUnhandledKeyEventHelper; + private final OnCreateWindowRequestedHelper mOnCreateWindowRequestedHelper; + private final OnReceivedIconHelper mOnReceivedIconHelper; public TestHelperBridge() { mOnPageStartedHelper = new OnPageStartedHelper(); @@ -317,6 +348,8 @@ class TestHelperBridge { mOpenFileChooserHelper = new OpenFileChooserHelper(); mOnFullscreenToggledHelper = new OnFullscreenToggledHelper(); mOverrideOrUnhandledKeyEventHelper = new OverrideOrUnhandledKeyEventHelper(); + mOnCreateWindowRequestedHelper = new OnCreateWindowRequestedHelper(); + mOnReceivedIconHelper = new OnReceivedIconHelper(); } public OnPageStartedHelper getOnPageStartedHelper() { @@ -383,6 +416,14 @@ class TestHelperBridge { return mOverrideOrUnhandledKeyEventHelper; } + public OnCreateWindowRequestedHelper getOnCreateWindowRequestedHelper() { + return mOnCreateWindowRequestedHelper; + } + + public OnReceivedIconHelper getOnReceivedIconHelper() { + return mOnReceivedIconHelper; + } + public void onTitleChanged(String title) { mChangedTitle = title; mOnTitleUpdatedHelper.notifyCalled(title); diff --git a/src/xwalk/test/android/data/create_window_1.html b/src/xwalk/test/android/data/create_window_1.html new file mode 100644 index 0000000..6a82470 --- /dev/null +++ b/src/xwalk/test/android/data/create_window_1.html @@ -0,0 +1,13 @@ + + + + + Create Window 1 + + + +

Create window by click

+ + diff --git a/src/xwalk/test/android/data/create_window_2.html b/src/xwalk/test/android/data/create_window_2.html new file mode 100644 index 0000000..2f65c0b --- /dev/null +++ b/src/xwalk/test/android/data/create_window_2.html @@ -0,0 +1,10 @@ + + + + + Create Window 2 + + +

Create window by open link

+ + diff --git a/src/xwalk/test/android/data/favicon.html b/src/xwalk/test/android/data/favicon.html new file mode 100644 index 0000000..6e60d4d --- /dev/null +++ b/src/xwalk/test/android/data/favicon.html @@ -0,0 +1,11 @@ + + + + + Favicon + + + +

The favicon will be shown by Toast

+ + diff --git a/src/xwalk/test/android/data/icon.png b/src/xwalk/test/android/data/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d94fd20efdad671f015b23b4889962b05b77aa01 GIT binary patch literal 2662 zcmV-s3YqnZP)k7C187(-y>c(SRf_RSOxO~VN(i`B zM2!@RQAtpwO}#KcWm}~{3SmomDKE;FwiF6TID)cly?{Idc4to(T5WQoOGi8w%HgOaj8QV2=f-jepVLGWP) z?X8R(KvuE=s}MxyLX$>d9B4Weoyr6PwY1q#l?fuf!O7YmSp=s;)6)c~`Vpvpf=DlL zU~4z*^rsQ1q7BplK_uVbq>6$S8YiMUVgH7z=64-uxUdp@spmt(}dw3wH%UF|Ah_GBQQtI-pV+fPdsAMUwx=I94Ai;1)8QU^Gk%+uccwWhl zNcqS^gq2s3%J$GSVsBa56`UmzAPBhw1W>4gwk_4ok%|UH_C-OMJxbM=6hRxG!iqN< z>CC>EBKe82M66LAwNIcP~VI;zvtXHY+ zNHuz`*(i3iNR*>CBk?jp5RrJ5=Y|OH;&xD*k?Pcex4*a|QI^_^?q7W%)N~?z`Lv2KI(F=?$4>r;OBgunS3_Mzt%1A+@Q7uGiY8z5eh{z9- z{6mDxfoPPP#H-Fmk%&?m$&+elJX(~>NIsRWhbTpDLh`6(X4+&z^jN#DA6 z-)D1e>*XHwrS)uR>Yns#y+1z2t_}@KjYJMaQdV@FoMY_cSDvz$CBI|M8a~bvAMTcV z%oCGSEcu4q0RL=mhK>DjP}bp+jY|B`b@NG;?O#|U{oA=XHqIU$+9~aLr*BNLYt>cK zuXD8LbM|OvMtX&2HJfM@md?yAvZIS@r8n^E-+pJ)gMFbN=i-f9Z1kCYfW{B*W%sXN zmtCPHok*0FeZfZ_EV6Tn)zTaK)xK|R&oC0&{wJqyvolrs*LC;LK{k2zw6Y3K*^7jG zDvV88a=)?F*?HD};4?NqJ1ucudAqH5 z&8%W`iG*B`ZvV&Deesd-{r>Uq19o@eiF6}<{@VlW>B3{>5GhksjJ7HxJ$7IZo4t2W zWf!KELlgz0t;$GW?fZ(|y>eM~_a(J}$Yi6f(nw1hP}D!2nQXMB*lDv#IlcGaY5=cv89=ZB<6PGJ2Mc|9V`c1GHWbf%lp9=>*+jI;|x6`fB| zwb8zObBdi~@{g~xk#^)fDBTkAHsYun?K_9RV?!6mq#qXs6g4%{Ez{Yw?k6hSXoDBq zduM?S_3mHtCNh1{@ZN3{*cqvZNc(6c+i353v}VbZ!E{rYb}CE5yFS(4NY|G4wGfp} zIBQu(8$8%Q^NY(r!?aVFej2vM_7#jU(x?F=A(COV!Fz!Rd%@_QJN`X#jE!oGDk z(se4=Lo{I0*@tDc!E^Prs8z?0|FmR!!!Xhpj`cCaR5s2Ng>AIKYk}vQZ!sVZUS*`% zBh+XcWTYFG_sbCBQ?DjWx(Lxm8@v{HE;orb+ORJ}jC8}wtTqxEm(oNUZSYv&wRk1U zXscK&CfZaR50MC?-ONb4DX7tgzg4tWj35$ewB3xfYb5b$w3kMt?Y}ixjUmF9qD`23 zRbGuYkCAp0co~?k>cwa;-I=$|xq&`t*$>sfva0?re!r<#<``|!M%qmJW_?&Zq?x9#D^)h0XcKOv-305w8X0XJ*NTaXLd_s5M&W9ARuU@) zB1IT!KSo>EwPHS1X%I+ zLW4a>?H7CXVrKFV5f6c+SjaUawSOZlPg3NjbiPENVJ-v81#XeR=Lk;qAFRINovJN%?EM-Ar_ z@oMv?jW8J1Nqu0n;MPVa$PR)&JvK}J$ao)=4Z4#+5aEDSmiod-!IwYl*9VD=M9#gn zZPX{mDKF~D!9pH}Zl6q%jJ8qQhJ7YPfsAznqYWpvmHJ3)!QJ_s$Q=rOEd!n$P4JHq zK*Av+km3hWC=d}y@d79`hzO+k02C@jH6ZPvepFh8<-$IQ(CVy3)dm;xCH1K^!9ZeO zWErm)K_>0Zi+E80(g^i)Xo6KaDcSF^lNO2Uq7po&6h?y0F(f=+lD^p_&Q4LHP_IwG; z1}fXdO(2UELVE+S08> + + + + New Window + + +

This is a new window

+ + diff --git a/src/xwalk/test/base/in_process_browser_test.cc b/src/xwalk/test/base/in_process_browser_test.cc index 9be97d0..c1b10b3 100644 --- a/src/xwalk/test/base/in_process_browser_test.cc +++ b/src/xwalk/test/base/in_process_browser_test.cc @@ -50,6 +50,19 @@ base::LazyInstance::Leaky g_xwalk_content_renderer_client = LAZY_INSTANCE_INITIALIZER; #endif +Runtime* CreateWithDefaultWindow( + xwalk::RuntimeContext* runtime_context, const GURL& url, + Runtime::Observer* observer = NULL) { + Runtime* runtime = Runtime::Create(runtime_context, observer); + runtime->LoadURL(url); +#if !defined(OS_ANDROID) + xwalk::RuntimeUIStrategy ui_strategy; + xwalk::NativeAppWindow::CreateParams params; + ui_strategy.Show(runtime, params); +#endif + return runtime; +} + } // namespace RuntimeRegistry::RuntimeRegistry() { @@ -148,7 +161,7 @@ void InProcessBrowserTest::RunTestOnMainThreadLoop() { // method, instead they should just create runtimes themselves // when needed and thus the 'runtime()' method should be removed // as well as 'runtime_' initialization below. - runtime_ = Runtime::CreateWithDefaultWindow( + runtime_ = CreateWithDefaultWindow( GetRuntimeContext(), GURL(), runtime_registry_.get()); content::WaitForLoadStop(runtime_->web_contents()); diff --git a/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc b/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc index b5b4253..82d05f0 100644 --- a/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc +++ b/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc @@ -5,6 +5,8 @@ #include "xwalk/tizen/browser/media/browser_mediaplayer_manager.h" +#include "content/browser/renderer_host/media/audio_renderer_host.h" +#include "content/browser/renderer_host/render_process_host_impl.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "xwalk/tizen/common/media/media_player_messages.h" @@ -80,10 +82,15 @@ void BrowserMediaPlayerManager::OnInitialize( MediaPlayerID player_id, int process_id, const GURL& url) { + scoped_refptr audio_host = + static_cast( + render_frame_host_->GetProcess())->audio_renderer_host(); + // Create murphy resource for the given player id. if (resource_manager_ && resource_manager_->IsConnected()) { - MurphyResource* resource = new MurphyResource(this, - player_id, resource_manager_); + MurphyResource* resource = new MurphyResource( + this, player_id, audio_host->app_id(), + audio_host->app_class(), resource_manager_); RemoveMurphyResource(player_id); AddMurphyResource(resource); } diff --git a/src/xwalk/tizen/browser/media/murphy_resource.cc b/src/xwalk/tizen/browser/media/murphy_resource.cc index 711c02a..2201ff5 100644 --- a/src/xwalk/tizen/browser/media/murphy_resource.cc +++ b/src/xwalk/tizen/browser/media/murphy_resource.cc @@ -8,9 +8,7 @@ namespace { -const char kMediaApplicationClass[] = "player"; const char kMediaStreamName[] = "audio_playback"; -const char kMediaRole[] = "browser"; static void NotifyCallback(mrp_res_context_t* context, const mrp_res_resource_set_t* resource_set, @@ -32,6 +30,8 @@ namespace tizen { MurphyResource::MurphyResource( BrowserMediaPlayerManager* manager, MediaPlayerID player_id, + const std::string& app_id, + const std::string& app_class, MurphyResourceManager* resource_manager) : manager_(manager), player_id_(player_id), @@ -42,17 +42,20 @@ MurphyResource::MurphyResource( return; resource_set_ = mrp_res_create_resource_set(context, - kMediaApplicationClass, NotifyCallback, this); + app_class.c_str(), NotifyCallback, this); if (!resource_set_) return; mrp_res_resource_t* resource = mrp_res_create_resource( resource_set_, kMediaStreamName, true, true); - mrp_res_attribute_t* attr = mrp_res_get_attribute_by_name( - resource, "role"); + mrp_res_attribute_t* attr = mrp_res_get_attribute_by_name(resource, "role"); if (attr) - mrp_res_set_attribute_string(attr, kMediaRole); + mrp_res_set_attribute_string(attr, app_class.c_str()); + + attr = mrp_res_get_attribute_by_name(resource, "resource.set.appid"); + if (attr) + mrp_res_set_attribute_string(attr, app_id.c_str()); mrp_res_release_resource_set(resource_set_); } diff --git a/src/xwalk/tizen/browser/media/murphy_resource.h b/src/xwalk/tizen/browser/media/murphy_resource.h index 895810d..4473aff 100644 --- a/src/xwalk/tizen/browser/media/murphy_resource.h +++ b/src/xwalk/tizen/browser/media/murphy_resource.h @@ -5,6 +5,8 @@ #ifndef XWALK_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_H_ #define XWALK_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_H_ +#include + #include "xwalk/tizen/browser/media/murphy_resource_manager.h" namespace tizen { @@ -15,6 +17,8 @@ class MurphyResource { public: MurphyResource(BrowserMediaPlayerManager* manager, MediaPlayerID player_id, + const std::string& app_id, + const std::string& app_calss, MurphyResourceManager* resource_manager); ~MurphyResource(); diff --git a/src/xwalk/tools/upstream_revision.py b/src/xwalk/tools/upstream_revision.py new file mode 100755 index 0000000..4586d0d --- /dev/null +++ b/src/xwalk/tools/upstream_revision.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Copyright (c) 2014 Intel Corp. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +upstream_revision.py -- Upstream revision fetching utility. +""" + +import optparse +import os +import sys + + +def WriteIfChanged(file_name, contents): + """ + Writes the specified contents to the specified file_name + iff the contents are different than the current contents. + """ + try: + old_contents = open(file_name, 'r').read() + except EnvironmentError: + pass + else: + if contents == old_contents: + return + os.unlink(file_name) + open(file_name, 'w').write(contents) + + +def main(argv=None): + if argv is None: + argv = sys.argv + + parser = optparse.OptionParser(usage="upstream_revision.py [options]") + parser.add_option("-r", "--revision", + help="The revision number.") + parser.add_option("-o", "--output", metavar="FILE", + help="Write revision to FILE. ") + opts, _ = parser.parse_args(argv[1:]) + + contents = 'UPSTREAM_REVISION=%s' % opts.revision + WriteIfChanged(opts.output, contents) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/xwalk/xwalk.gyp b/src/xwalk/xwalk.gyp index fe20cd4..f2cadd6 100644 --- a/src/xwalk/xwalk.gyp +++ b/src/xwalk/xwalk.gyp @@ -4,11 +4,6 @@ 'xwalk_version': '