Upstream version 9.38.204.0 22/27522/1
authorEurogiciel-BOT <eurogiciel.tizen@gmail.com>
Mon, 15 Sep 2014 09:30:49 +0000 (09:30 +0000)
committerEurogiciel-BOT <eurogiciel.tizen@gmail.com>
Mon, 15 Sep 2014 09:30:49 +0000 (09:30 +0000)
Upstream commit-id 5db15ede94e2f6469663b9f898a29ffceca2c03d

Change-Id: Ia75ca07dc000d3e48b2dbb526a73332ab9451604
Signed-off-by: Eurogiciel-BOT <eurogiciel.tizen@gmail.com>
243 files changed:
packaging/crosswalk-tizen-audio-session-manager.patch [deleted file]
packaging/crosswalk.spec
packaging/xwalk.service.in
src/build/common.gypi
src/build/linux/system.gyp
src/content/browser/renderer_host/render_view_host_impl.cc
src/content/browser/renderer_host/render_view_host_impl.h
src/content/common/content_message_generator.h
src/content/content_browser.gypi
src/content/content_common.gypi
src/content/content_renderer.gypi
src/content/renderer/render_frame_impl.cc
src/content/renderer/render_frame_impl.h
src/ozone/AUTHORS
src/ozone/media/va_wayland.sigs
src/ozone/media/vaapi_video_decode_accelerator.cc
src/ozone/media/vaapi_video_decode_accelerator.h
src/ozone/media/vaapi_wrapper.cc
src/ozone/media/vaapi_wrapper.h
src/ozone/patches/0007-Introduce-vaLockBuffer-APIs-in-libva.patch [new file with mode: 0644]
src/ozone/ui/desktop_aura/desktop_window_tree_host_wayland.cc
src/ozone/ui/desktop_aura/desktop_window_tree_host_wayland.h
src/ozone/ui/desktop_aura/window_tree_host_delegate_wayland.cc
src/ozone/ui/desktop_aura/window_tree_host_delegate_wayland.h
src/ozone/ui/events/event_converter_in_process.cc
src/ozone/ui/events/event_converter_in_process.h
src/ozone/ui/events/event_converter_ozone_wayland.h
src/ozone/ui/events/remote_event_dispatcher.cc
src/ozone/ui/events/remote_event_dispatcher.h
src/ozone/ui/events/window_change_observer.h
src/ozone/ui/public/messages.h
src/ozone/ui/public/ozone_channel_host.cc
src/ozone/ui/public/ozone_channel_host.h
src/ozone/wayland/shell/shell_surface.cc
src/ozone/wayland/shell/shell_surface.h
src/ozone/wayland/shell/wl_shell_surface.cc
src/ozone/wayland/shell/wl_shell_surface.h
src/ozone/wayland/shell/xdg_shell_surface.cc
src/ozone/wayland/shell/xdg_shell_surface.h
src/third_party/libva/va/va.h
src/third_party/libva/va/va_backend.h
src/v8/include/v8-profiler.h
src/v8/src/api.cc
src/v8/src/cpu-profiler.cc
src/v8/src/full-codegen.cc
src/v8/src/profile-generator-inl.h
src/v8/src/profile-generator.cc
src/v8/src/profile-generator.h
src/v8/test/cctest/test-cpu-profiler.cc
src/xwalk/DEPS.xwalk
src/xwalk/VERSION
src/xwalk/app/android/app_hello_world/AndroidManifest.xml
src/xwalk/app/android/app_template/AndroidManifest.xml
src/xwalk/app/android/runtime_activity/src/org/xwalk/app/XWalkRuntimeActivityBase.java
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapper.java [deleted file]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapperExceptionHandler.java [deleted file]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkCoreProviderImpl.java [moved from src/xwalk/runtime/android/runtime/src/org/xwalk/runtime/XWalkCoreProviderImpl.java with 86% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeClient.java [deleted file]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeTestHelper.java [moved from src/xwalk/runtime/android/runtime/src/org/xwalk/runtime/XWalkRuntimeTestHelper.java with 99% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeView.java [moved from src/xwalk/runtime/android/runtime/src/org/xwalk/runtime/XWalkRuntimeView.java with 90% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeViewProvider.java [moved from src/xwalk/runtime/android/runtime/src/org/xwalk/runtime/XWalkRuntimeViewProvider.java with 94% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeViewProviderFactory.java [moved from src/xwalk/runtime/android/runtime/src/org/xwalk/runtime/XWalkRuntimeViewProviderFactory.java with 95% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/extension/XWalkCoreExtensionBridge.java [moved from src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkCoreExtensionBridge.java with 78% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/extension/XWalkExtensionClient.java
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/extension/XWalkExtensionContextClient.java
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/extension/XWalkRuntimeExtensionBridge.java [moved from src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionBridge.java with 97% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/extension/XWalkRuntimeExtensionBridgeFactory.java [moved from src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionBridgeFactory.java with 67% similarity]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/extension/XWalkRuntimeExtensionManager.java [moved from src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionManager.java with 52% similarity]
src/xwalk/app/android/runtime_client_embedded_shell/AndroidManifest.xml
src/xwalk/app/android/runtime_client_embedded_shell/src/org/xwalk/runtime/client/embedded/shell/XWalkRuntimeClientEmbeddedShellActivity.java
src/xwalk/app/android/runtime_client_shell/AndroidManifest.xml
src/xwalk/app/android/runtime_client_shell/src/org/xwalk/runtime/client/shell/XWalkRuntimeClientShellActivity.java
src/xwalk/app/tools/android/customize.py
src/xwalk/app/tools/android/customize_launch_screen.py
src/xwalk/app/tools/android/extension_manager.py [new file with mode: 0755]
src/xwalk/app/tools/android/make_apk.py
src/xwalk/app/tools/android/util.py [new file with mode: 0644]
src/xwalk/application/browser/application.cc
src/xwalk/application/browser/application.h
src/xwalk/application/browser/application_service.cc
src/xwalk/application/browser/application_service.h
src/xwalk/application/browser/application_service_tizen.cc [new file with mode: 0644]
src/xwalk/application/browser/application_service_tizen.h [new file with mode: 0644]
src/xwalk/application/browser/application_system.cc
src/xwalk/application/browser/application_system.h
src/xwalk/application/browser/application_tizen.cc
src/xwalk/application/browser/application_tizen.h
src/xwalk/application/browser/linux/running_applications_manager.cc
src/xwalk/application/common/application_data.cc
src/xwalk/application/common/application_data.h
src/xwalk/application/common/application_file_util.cc
src/xwalk/application/common/application_file_util.h
src/xwalk/application/common/application_file_util_unittest.cc
src/xwalk/application/common/application_manifest_constants.cc
src/xwalk/application/common/application_manifest_constants.h
src/xwalk/application/common/application_storage.h
src/xwalk/application/common/application_storage_impl.cc
src/xwalk/application/common/application_storage_impl_tizen.cc
src/xwalk/application/common/application_storage_impl_unittest.cc
src/xwalk/application/common/application_unittest.cc
src/xwalk/application/common/installer/package_installer.h [deleted file]
src/xwalk/application/common/installer/package_installer_tizen.cc [deleted file]
src/xwalk/application/common/installer/package_installer_tizen.h [deleted file]
src/xwalk/application/common/manifest.cc
src/xwalk/application/common/manifest.h
src/xwalk/application/common/manifest_handler_unittest.cc
src/xwalk/application/common/manifest_handlers/csp_handler_unittest.cc
src/xwalk/application/common/manifest_handlers/navigation_handler_unittest.cc
src/xwalk/application/common/manifest_handlers/permissions_handler_unittest.cc
src/xwalk/application/common/manifest_handlers/warp_handler_unittest.cc
src/xwalk/application/common/manifest_handlers/widget_handler_unittest.cc
src/xwalk/application/common/manifest_unittest.cc
src/xwalk/application/common/package/package.cc [moved from src/xwalk/application/common/installer/package.cc with 61% similarity]
src/xwalk/application/common/package/package.h [moved from src/xwalk/application/common/installer/package.h with 78% similarity]
src/xwalk/application/common/package/package_unittest.cc [moved from src/xwalk/application/common/installer/package_unittest.cc with 84% similarity]
src/xwalk/application/common/package/wgt_package.cc [moved from src/xwalk/application/common/installer/wgt_package.cc with 87% similarity]
src/xwalk/application/common/package/wgt_package.h [moved from src/xwalk/application/common/installer/wgt_package.h with 67% similarity]
src/xwalk/application/common/package/xpk_package.cc [moved from src/xwalk/application/common/installer/xpk_package.cc with 94% similarity]
src/xwalk/application/common/package/xpk_package.h [moved from src/xwalk/application/common/installer/xpk_package.h with 77% similarity]
src/xwalk/application/common/tizen/configuration/signature_schema.xsd [moved from src/xwalk/application/common/installer/tizen/configuration/signature_schema.xsd with 100% similarity]
src/xwalk/application/common/tizen/signature_data.cc [moved from src/xwalk/application/common/installer/signature_data.cc with 93% similarity]
src/xwalk/application/common/tizen/signature_data.h [moved from src/xwalk/application/common/installer/signature_data.h with 93% similarity]
src/xwalk/application/common/tizen/signature_parser.cc [moved from src/xwalk/application/common/installer/signature_parser.cc with 99% similarity]
src/xwalk/application/common/tizen/signature_parser.h [moved from src/xwalk/application/common/installer/signature_parser.h with 68% similarity]
src/xwalk/application/common/tizen/signature_validator.cc [moved from src/xwalk/application/common/installer/tizen/signature_validator.cc with 97% similarity]
src/xwalk/application/common/tizen/signature_validator.h [moved from src/xwalk/application/common/installer/tizen/signature_validator.h with 70% similarity]
src/xwalk/application/common/xwalk_application_common.gypi
src/xwalk/application/test/application_browsertest.cc
src/xwalk/application/test/application_multi_app_test.cc
src/xwalk/application/test/application_testapi_test.cc
src/xwalk/application/tools/linux/xwalk_application_tools.gyp
src/xwalk/application/tools/linux/xwalk_launcher_main.cc
src/xwalk/application/tools/tizen/xwalk_backend_plugin.cc
src/xwalk/application/tools/tizen/xwalk_backend_wrapper.sh
src/xwalk/application/tools/tizen/xwalk_package_helper.cc
src/xwalk/application/tools/tizen/xwalk_package_installer.cc [moved from src/xwalk/application/common/installer/package_installer.cc with 50% similarity]
src/xwalk/application/tools/tizen/xwalk_package_installer.h [new file with mode: 0644]
src/xwalk/application/tools/tizen/xwalk_package_installer_helper.cc
src/xwalk/application/tools/tizen/xwalk_package_installer_helper.h
src/xwalk/application/tools/tizen/xwalk_packageinfo_constants.cc [moved from src/xwalk/application/common/installer/tizen/packageinfo_constants.cc with 90% similarity]
src/xwalk/application/tools/tizen/xwalk_packageinfo_constants.h [moved from src/xwalk/application/common/installer/tizen/packageinfo_constants.h with 76% similarity]
src/xwalk/application/tools/tizen/xwalk_tizen_tools.gyp
src/xwalk/application/tools/tizen/xwalk_tizen_user.cc [moved from src/xwalk/application/tools/linux/xwalk_tizen_user.cc with 100% similarity]
src/xwalk/application/tools/tizen/xwalk_tizen_user.h [moved from src/xwalk/application/tools/linux/xwalk_tizen_user.h with 75% similarity]
src/xwalk/application/tools/tizen/xwalkctl_main.cc [moved from src/xwalk/application/tools/linux/xwalkctl_main.cc with 94% similarity]
src/xwalk/application/xwalk_application.gypi
src/xwalk/build/android/generate_app_packaging_tool.py
src/xwalk/build/android/generate_xwalk_core_library_aar.py
src/xwalk/build/common.gypi
src/xwalk/experimental/native_file_system/native_file_system_api.js
src/xwalk/experimental/native_file_system/native_file_system_extension.cc
src/xwalk/experimental/native_file_system/native_file_system_extension.h
src/xwalk/packaging/crosswalk-tizen-audio-session-manager.patch [deleted file]
src/xwalk/packaging/crosswalk.spec
src/xwalk/packaging/xwalk.service.in
src/xwalk/runtime/android/core/src/org/xwalk/core/SharedXWalkExceptionHandler.java [new file with mode: 0644]
src/xwalk/runtime/android/core/src/org/xwalk/core/SharedXWalkView.java [new file with mode: 0644]
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkApplication.java [moved from src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeApplication.java with 60% similarity]
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkMixedResources.java [moved from src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkMixedResources.java with 98% similarity]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/MixedContext.java [moved from src/xwalk/runtime/android/runtime/src/org/xwalk/runtime/MixedContext.java with 97% similarity]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/ReflectionHelper.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/XWalkPathHelper.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/XWalkPreferencesInternal.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/XWalkViewInternal.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/XWalkWebContentsDelegateAdapter.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/BuiltinXWalkExtensions.java [new file with mode: 0644]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtension.java [deleted file]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionClientImpl.java [deleted file]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionContext.java [deleted file]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionContextWrapper.java [deleted file]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionWithActivityStateListener.java [new file with mode: 0644]
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/contacts/Contacts.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/DeviceCapabilities.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/DeviceCapabilitiesCPU.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/DeviceCapabilitiesCodecs.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/DeviceCapabilitiesDisplay.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/DeviceCapabilitiesMemory.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/DeviceCapabilitiesStorage.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/launchscreen/LaunchScreenExtension.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/messaging/Messaging.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/messaging/MessagingSmsManager.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/presentation/PresentationExtension.java
src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/presentation/XWalkPresentationContent.java
src/xwalk/runtime/android/runtime/res/values/strings.xml [deleted file]
src/xwalk/runtime/android/runtime_lib/AndroidManifest.xml
src/xwalk/runtime/android/runtime_lib/src/README.md [new file with mode: 0644]
src/xwalk/runtime/android/runtime_lib/src/org/xwalk/runtime/lib/RuntimeLibApplication.java [deleted file]
src/xwalk/runtime/android/runtime_shell/AndroidManifest.xml [deleted file]
src/xwalk/runtime/android/runtime_shell/res/layout/testshell_activity.xml [deleted file]
src/xwalk/runtime/android/runtime_shell/res/values/strings.xml [deleted file]
src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/shell/XWalkRuntimeShellActivity.java [deleted file]
src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/test/TestContentProvider.java [deleted file]
src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/test/XWalkRuntimeTestRunnerActivity.java [deleted file]
src/xwalk/runtime/browser/android/xwalk_content.cc
src/xwalk/runtime/browser/xwalk_browser_main_parts_tizen.cc
src/xwalk/runtime/common/xwalk_content_client.cc
src/xwalk/runtime/common/xwalk_paths.cc
src/xwalk/runtime/common/xwalk_paths.h
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/EnterAndLeaveFullscreenTest.java
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnRequestFocusTest.java [new file with mode: 0644]
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/ShouldOverrideUrlLoadingTest.java
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/TestHelperBridge.java
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/XWalkViewTestBase.java
src/xwalk/test/android/data/request_focus_left_frame.html [new file with mode: 0644]
src/xwalk/test/android/data/request_focus_main.html [new file with mode: 0644]
src/xwalk/test/android/data/request_focus_right_frame.html [new file with mode: 0644]
src/xwalk/test/android/data/request_focus_right_frame1.html [new file with mode: 0644]
src/xwalk/test/android/runtime/javatests/AndroidManifest.xml [deleted file]
src/xwalk/test/android/runtime/javatests/src/org/xwalk/runtime/test/XWalkRuntimeTestBase.java [deleted file]
src/xwalk/test/android/runtime_client/javatests/src/org/xwalk/runtime/client/test/XWalkRuntimeClientTestBase.java
src/xwalk/test/android/runtime_client_embedded/javatests/src/org/xwalk/runtime/client/embedded/test/XWalkRuntimeClientTestBase.java
src/xwalk/test/android/util/runtime_client/src/org/xwalk/test/util/XWalkRuntimeClientTestGeneric.java
src/xwalk/test/android/util/runtime_client/src/org/xwalk/test/util/XWalkRuntimeClientTestUtilBase.java
src/xwalk/tizen/browser/audio_session_manager.cc [deleted file]
src/xwalk/tizen/browser/audio_session_manager.h [deleted file]
src/xwalk/tizen/browser/audio_session_manager.sigs [deleted file]
src/xwalk/tizen/browser/audio_session_manager_init.cc [deleted file]
src/xwalk/tizen/browser/audio_session_manager_init.h [deleted file]
src/xwalk/tizen/browser/audio_session_manager_stub_headers.fragment [deleted file]
src/xwalk/tizen/browser/browser_mediaplayer_manager.cc [deleted file]
src/xwalk/tizen/browser/browser_mediaplayer_manager.h [deleted file]
src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc [new file with mode: 0644]
src/xwalk/tizen/browser/media/browser_mediaplayer_manager.h [new file with mode: 0644]
src/xwalk/tizen/browser/media/media_webcontents_observer.cc [new file with mode: 0644]
src/xwalk/tizen/browser/media/media_webcontents_observer.h [new file with mode: 0644]
src/xwalk/tizen/browser/media/murphy_mainloop.cc [new file with mode: 0644]
src/xwalk/tizen/browser/media/murphy_mainloop.h [new file with mode: 0644]
src/xwalk/tizen/browser/media/murphy_resource.cc [new file with mode: 0644]
src/xwalk/tizen/browser/media/murphy_resource.h [new file with mode: 0644]
src/xwalk/tizen/browser/media/murphy_resource_manager.cc [new file with mode: 0644]
src/xwalk/tizen/browser/media/murphy_resource_manager.h [new file with mode: 0644]
src/xwalk/tizen/common/media/media_player_messages.h [moved from src/xwalk/tizen/common/media_player_messages.h with 94% similarity]
src/xwalk/tizen/renderer/media/mediaplayer_impl.cc [moved from src/xwalk/tizen/renderer/mediaplayer_impl.cc with 82% similarity]
src/xwalk/tizen/renderer/media/mediaplayer_impl.h [moved from src/xwalk/tizen/renderer/mediaplayer_impl.h with 73% similarity]
src/xwalk/tizen/renderer/media/renderer_mediaplayer_manager.cc [moved from src/xwalk/tizen/renderer/renderer_mediaplayer_manager.cc with 87% similarity]
src/xwalk/tizen/renderer/media/renderer_mediaplayer_manager.h [moved from src/xwalk/tizen/renderer/renderer_mediaplayer_manager.h with 82% similarity]
src/xwalk/tools/reflection_generator/reflection_generator.py
src/xwalk/xwalk.gyp
src/xwalk/xwalk_android.gypi
src/xwalk/xwalk_android_app.gypi
src/xwalk/xwalk_android_tests.gypi
src/xwalk/xwalk_core_library_android.gypi
src/xwalk/xwalk_tests.gypi

diff --git a/packaging/crosswalk-tizen-audio-session-manager.patch b/packaging/crosswalk-tizen-audio-session-manager.patch
deleted file mode 100644 (file)
index 5669694..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-Author: Sudarsana Nagineni <sudarsana.nagineni@intel.com>
-
-This patch includes Chromium side changes needed for integrating
-WebMediaPlayer with the Tizen Audio Session Manager.
-
-Also, it has changes that are needed for generating audio-session-manager
-stubs and load the library dynamically in the Browser process.
-
-audio-session-manager is using an _attribute_((constructor)) to initialize
-code and setup signal handlers at startup. So, linking with this library
-is causing a sandbox violation by executing the code in Renderer Process,
-since the Renderer Process and the Browser Process are linked with the
-same libraries.
-
-To prevent the problem, we load the audio-session-manager dynamically in
-the Browser process.
-
-diff --git src/build/linux/system.gyp src/build/linux/system.gyp
-index 4a7e857..f89d256 100644
---- src/build/linux/system.gyp
-+++ src/build/linux/system.gyp
-@@ -874,5 +874,19 @@
-         }],
-       ],
-     },
-+    {
-+      'target_name': 'audio_session_manager',
-+      'type': 'none',
-+      'toolsets': ['host', 'target'],
-+      'conditions': [
-+        ['tizen_mobile == 1', {
-+          'direct_dependent_settings': {
-+            'cflags': [
-+              '<!@(<(pkg-config) --cflags audio-session-mgr)',
-+            ],
-+          },
-+        }],
-+      ],
-+    },
-   ],
- }
-diff --git src/content/browser/renderer_host/render_view_host_impl.cc src/content/browser/renderer_host/render_view_host_impl.cc
-index 0912144..adf0a1b 100644
---- src/content/browser/renderer_host/render_view_host_impl.cc
-+++ src/content/browser/renderer_host/render_view_host_impl.cc
-@@ -89,4 +89,6 @@
- #include "content/browser/media/android/browser_media_player_manager.h"
-+#elif defined(OS_TIZEN_MOBILE)
-+#include "xwalk/tizen/browser/browser_mediaplayer_manager.h"
- #elif defined(OS_WIN)
- #include "base/win/win_util.h"
- #endif
-
- using base::TimeDelta;
-@@ -223,6 +225,8 @@ RenderViewHostImpl::RenderViewHostImpl(
-
- #if defined(OS_ANDROID)
-   media_player_manager_.reset(BrowserMediaPlayerManager::Create(this));
-+#elif defined(OS_TIZEN_MOBILE)
-+  media_player_manager_.reset(tizen::BrowserMediaPlayerManager::Create(this));
- #endif
- }
-
-diff --git src/content/browser/renderer_host/render_view_host_impl.h src/content/browser/renderer_host/render_view_host_impl.h
-index d63bae3..d0602c7 100644
---- src/content/browser/renderer_host/render_view_host_impl.h
-+++ src/content/browser/renderer_host/render_view_host_impl.h
-@@ -42,6 +42,12 @@ struct ViewHostMsg_ShowPopup_Params;
- struct ViewMsg_Navigate_Params;
- struct ViewMsg_PostMessage_Params;
-
-+#if defined(OS_TIZEN_MOBILE)
-+namespace tizen {
-+class BrowserMediaPlayerManager;
-+}
-+#endif
-+
- namespace base {
- class ListValue;
- }
-@@ -704,6 +710,8 @@ class CONTENT_EXPORT RenderViewHostImpl
- #if defined(OS_ANDROID)
-   // Manages all the android mediaplayer objects and handling IPCs for video.
-   scoped_ptr<BrowserMediaPlayerManager> media_player_manager_;
-+#elif defined(OS_TIZEN_MOBILE)
-+  scoped_ptr<tizen::BrowserMediaPlayerManager> media_player_manager_;
- #endif
-
-   DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl);
-diff --git src/content/common/content_message_generator.h src/content/common/content_message_generator.h
-index 78e7c53..a3cda01 100644
---- src/content/common/content_message_generator.h
-+++ src/content/common/content_message_generator.h
-@@ -57,3 +57,6 @@
- #include "content/common/view_messages.h"
- #include "content/common/websocket_messages.h"
- #include "content/common/worker_messages.h"
-+#if defined(OS_TIZEN_MOBILE)
-+#include "xwalk/tizen/common/media_player_messages.h"
-+#endif
-diff --git src/content/content_browser.gypi src/content/content_browser.gypi
-index 6570d15..d47cee2 100644
---- src/content/content_browser.gypi
-+++ src/content/content_browser.gypi
-@@ -1641,5 +1641,69 @@
-         'browser/geolocation/wifi_data_provider_linux.cc',
-       ],
-     }],
-+    ['tizen_mobile == 1', {
-+      'sources': [
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager.cc',
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager.h',
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager_init.cc',
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager_init.h',
-+        '<(DEPTH)/xwalk/tizen/browser/browser_mediaplayer_manager.cc',
-+        '<(DEPTH)/xwalk/tizen/browser/browser_mediaplayer_manager.h',
-+      ],
-+      'variables': {
-+        'generate_stubs_script': '../tools/generate_stubs/generate_stubs.py',
-+        'extra_header': '../xwalk/tizen/browser/audio_session_manager_stub_headers.fragment',
-+        'sig_files': ['../xwalk/tizen/browser/audio_session_manager.sigs'],
-+        'outfile_type': 'posix_stubs',
-+        'stubs_filename_root': 'audio_session_manager_stubs',
-+        'project_path': 'xwalk/tizen/browser',
-+        'intermediate_dir': '<(INTERMEDIATE_DIR)',
-+        'output_root': '<(SHARED_INTERMEDIATE_DIR)/audio_session_manager',
-+      },
-+      'include_dirs': [
-+        '<(output_root)',
-+      ],
-+      'actions': [
-+        {
-+          'action_name': 'generate_stubs',
-+          'inputs': [
-+          '<(generate_stubs_script)',
-+          '<(extra_header)',
-+          '<@(sig_files)',
-+          ],
-+          'outputs': [
-+            '<(intermediate_dir)/<(stubs_filename_root).cc',
-+            '<(output_root)/<(project_path)/<(stubs_filename_root).h',
-+          ],
-+          'action': ['python',
-+            '<(generate_stubs_script)',
-+            '-i', '<(intermediate_dir)',
-+            '-o', '<(output_root)/<(project_path)',
-+            '-t', '<(outfile_type)',
-+            '-e', '<(extra_header)',
-+            '-s', '<(stubs_filename_root)',
-+            '-p', '<(project_path)',
-+            '<@(_inputs)',
-+          ],
-+          'process_outputs_as_sources': 1,
-+          'message': 'Generating audio session manager stubs for dynamic loading',
-+        },
-+      ],
-+      'conditions': [
-+        ['OS=="linux" or OS=="solaris"', {
-+          'link_settings': {
-+            'libraries': [
-+            '-ldl',
-+            ],
-+          },
-+        }],
-+      ],
-+      'dependencies': [
-+        '../build/linux/system.gyp:audio_session_manager',
-+      ],
-+      'export_dependent_settings': [
-+        '../build/linux/system.gyp:audio_session_manager',
-+      ],
-+    }],
-   ],
- }
-diff --git src/content/content_common.gypi src/content/content_common.gypi
-index 1bfcccd..46db168 100644
---- src/content/content_common.gypi
-+++ src/content/content_common.gypi
-@@ -656,5 +656,10 @@
-     }, {
-       'defines': ['USE_SECCOMP_BPF'],
-     }],
-+    ['tizen_mobile == 1', {
-+      'sources': [
-+        '<(DEPTH)/xwalk/tizen/common/media_player_messages.h',
-+      ],
-+    }],
-     ['OS=="win" and directxsdk_exists=="True"', {
-       'actions': [
-       {
-diff --git src/content/content_renderer.gypi src/content/content_renderer.gypi
-index 1e72a81..3bceb70 100644
---- src/content/content_renderer.gypi
-+++ src/content/content_renderer.gypi
-@@ -752,6 +752,14 @@
-         }],
-       ],
-     }],
-+    ['tizen_mobile == 1', {
-+      'sources': [
-+        '<(DEPTH)/xwalk/tizen/renderer/mediaplayer_impl.cc',
-+        '<(DEPTH)/xwalk/tizen/renderer/mediaplayer_impl.h',
-+        '<(DEPTH)/xwalk/tizen/renderer/renderer_mediaplayer_manager.cc',
-+        '<(DEPTH)/xwalk/tizen/renderer/renderer_mediaplayer_manager.h',
-+      ],
-+    }],
-   ],
-   'target_conditions': [
-     ['OS=="android"', {
-diff --git src/content/renderer/render_view_impl.cc src/content/renderer/render_view_impl.cc
-index c5a7059..cd42b4c 100644
---- src/content/renderer/render_view_impl.cc
-+++ src/content/renderer/render_view_impl.cc
-@@ -245,6 +245,11 @@
- #include "content/renderer/media/rtc_peer_connection_handler.h"
- #endif
-
-+#if defined(OS_TIZEN_MOBILE)
-+#include "xwalk/tizen/renderer/mediaplayer_impl.h"
-+#include "xwalk/tizen/renderer/renderer_mediaplayer_manager.h"
-+#endif
-+
- using blink::WebAXObject;
- using blink::WebApplicationCacheHost;
- using blink::WebApplicationCacheHostClient;
-@@ -844,6 +849,8 @@ RenderViewImpl::RenderViewImpl(RenderViewImplParams* params)
-       body_background_color_(SK_ColorWHITE),
-       expected_content_intent_id_(0),
-       media_player_manager_(NULL),
-+#elif defined(OS_TIZEN_MOBILE)
-+      media_player_manager_(NULL),
- #endif
- #if defined(OS_WIN)
-       focused_plugin_id_(-1),
-@@ -967,6 +974,8 @@ void RenderViewImpl::Initialize(RenderViewImplParams* params) {
- #if defined(OS_ANDROID)
-   media_player_manager_ = new RendererMediaPlayerManager(this);
-   new JavaBridgeDispatcher(this);
-+#elif defined(OS_TIZEN_MOBILE)
-+  media_player_manager_ = new tizen::RendererMediaPlayerManager(this);
- #endif
-
-   // The next group of objects all implement RenderViewObserver, so are deleted
-@@ -3044,6 +3053,13 @@ blink::WebMediaPlayer* RenderViewImpl::CreateMediaPlayer(
-                  base::Unretained(GetContentClient()->renderer()),
-                  static_cast<RenderFrame*>(render_frame)),
-       sink);
-+
-+#if defined(OS_TIZEN_MOBILE)
-+  tizen::MediaPlayerImpl* media_player = new tizen::MediaPlayerImpl(
-+      frame, client, AsWeakPtr(), media_player_manager_, params);
-+  return media_player;
-+#endif
-+
-   return new WebMediaPlayerImpl(frame, client, AsWeakPtr(), params);
- #endif  // defined(OS_ANDROID)
- }
-diff --git src/content/renderer/render_view_impl.h src/content/renderer/render_view_impl.h
-index ccfd1b5..8949cd0 100644
---- src/content/renderer/render_view_impl.h
-+++ src/content/renderer/render_view_impl.h
-@@ -128,6 +128,12 @@ namespace webkit_glue {
- class WebURLResponseExtraDataImpl;
- }
-
-+#if defined(OS_TIZEN_MOBILE)
-+namespace tizen {
-+class RendererMediaPlayerManager;
-+}
-+#endif
-+
- namespace content {
- class BrowserPluginManager;
- class DeviceOrientationDispatcher;
-@@ -1403,6 +1409,10 @@ class CONTENT_EXPORT RenderViewImpl
-
-   // A date/time picker object for date and time related input elements.
-   scoped_ptr<RendererDateTimePicker> date_time_picker_client_;
-+#elif defined(OS_TIZEN_MOBILE)
-+  // The media player manager for managing all the media players on this view
-+  // and for communicating with the audio session manager in browser process.
-+  tizen::RendererMediaPlayerManager* media_player_manager_;
- #endif
-
-   // Plugins -------------------------------------------------------------------
index de425ce..7dd4b67 100644 (file)
@@ -16,9 +16,9 @@
 %endif
 
 Name:           crosswalk
-Version:        9.38.198.0
+Version:        9.38.204.0
 Release:        0
-Summary:        Crosswalk is an app runtime based on Chromium
+Summary:        Chromium-based app runtime
 License:        (BSD-3-Clause and LGPL-2.1+)
 Group:          Web Framework/Web Run Time
 Url:            https://github.com/otcshare/crosswalk
@@ -89,6 +89,11 @@ BuildRequires:  pkgconfig(xt)
 BuildRequires:  pkgconfig(xtst)
 %endif
 
+%if "%{profile}" == "ivi"
+BuildRequires:  pkgconfig(murphy-common)
+BuildRequires:  pkgconfig(murphy-resource)
+%endif
+
 %if %{with wayland}
 BuildRequires:  pkgconfig(wayland-client)
 BuildRequires:  pkgconfig(wayland-cursor)
@@ -167,7 +172,7 @@ if [ -n "${BUILDDIR_NAME}" ]; then
 fi
 
 %if %{with wayland}
-GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Duse_ozone=1 -Denable_ozone_wayland_vkb=1 -Denable_xdg_shell=0"
+GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Duse_ozone=1 -Denable_ozone_wayland_vkb=1 -Denable_xdg_shell=1"
 %endif
 
 GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Ddisable_nacl=%{_disable_nacl}"
@@ -195,6 +200,10 @@ export CXXFLAGS=`echo $CXXFLAGS | sed s,-mfpu=vfpv3,-mfpu=neon,g`
 export FFLAGS=`echo $FFLAGS | sed s,-mfpu=vfpv3,-mfpu=neon,g`
 %endif
 
+%if "%{profile}" == "ivi"
+GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Denable_murphy=1"
+%endif
+
 # --no-parallel is added because chroot does not mount a /dev/shm, this will
 # cause python multiprocessing.SemLock error.
 export GYP_GENERATORS='ninja'
@@ -236,7 +245,7 @@ install -p -D src/out/Release/icudtl.dat %{buildroot}%{_libdir}/xwalk/icudtl.dat
 install -p -D src/out/Release/libffmpegsumo.so %{buildroot}%{_libdir}/xwalk/libffmpegsumo.so
 install -p -D src/out/Release/xwalk.pak %{buildroot}%{_libdir}/xwalk/xwalk.pak
 mkdir -p %{buildroot}%{_datadir}/xwalk
-install -p -D src/xwalk/application/common/installer/tizen/configuration/*.xsd %{buildroot}%{_datadir}/xwalk/
+install -p -D src/xwalk/application/common/tizen/configuration/*.xsd %{buildroot}%{_datadir}/xwalk/
 
 # PNaCl
 %if ! %{_disable_nacl}
index 0e2f345..4018075 100644 (file)
@@ -4,4 +4,5 @@ Description=Crosswalk
 [Service]
 Type=dbus
 BusName=org.crosswalkproject.Runtime1
+Environment=OZONE_WAYLAND_USE_XDG_SHELL='defined'
 ExecStart=@LIB_INSTALL_DIR@/xwalk/xwalk --external-extensions-path=@LIB_INSTALL_DIR@/tizen-extensions-crosswalk
index 609041c..5ce3249 100644 (file)
 
     # Whether to allow building of the GPU-related isolates.
     'archive_gpu_tests%': 0,
+
+    # Flags to enable Murphy resource policy daemon integration on Tizen.
+    'tizen%': 0,
+    'enable_murphy%': 0,
   },
   'target_defaults': {
     'variables': {
index e33f22d..9c9def9 100644 (file)
         }],
       ],
     },
+    {
+      'target_name': 'resource_manager',
+      'type': 'none',
+      'toolsets': ['host', 'target'],
+      'conditions': [
+        ['tizen==1 and enable_murphy==1', {
+          'direct_dependent_settings': {
+            'cflags': [
+              '<!@(<(pkg-config) --cflags murphy-common murphy-resource)',
+            ],
+          },
+          'link_settings': {
+            'ldflags': [
+              '<!@(<(pkg-config) --libs-only-L --libs-only-other murphy-common murphy-resource)',
+            ],
+            'libraries': [
+              '<!@(<(pkg-config) --libs-only-l murphy-common  murphy-resource)',
+            ],
+          },
+        }],
+      ],
+    },
   ],
 }
index bb4b9fd..ad11596 100644 (file)
 #include "content/browser/media/media_web_contents_observer.h"
 #endif
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+#include "xwalk/tizen/browser/media/media_webcontents_observer.h"
+#endif
+
 using base::TimeDelta;
 using blink::WebConsoleMessage;
 using blink::WebDragOperation;
@@ -223,6 +227,10 @@ RenderViewHostImpl::RenderViewHostImpl(
   media_web_contents_observer_.reset(new MediaWebContentsObserver(this));
 #endif
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+  media_webcontents_observer_.reset(new tizen::MediaWebContentsObserver(this));
+#endif
+
   unload_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind(
       &RenderViewHostImpl::OnSwappedOut, weak_factory_.GetWeakPtr(), true)));
 }
index fa76384..1a28abf 100644 (file)
@@ -35,6 +35,12 @@ struct ViewHostMsg_ShowPopup_Params;
 struct FrameMsg_Navigate_Params;
 struct ViewMsg_PostMessage_Params;
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+namespace tizen {
+class MediaWebContentsObserver;
+}
+#endif
+
 namespace base {
 class ListValue;
 }
@@ -544,6 +550,11 @@ class CONTENT_EXPORT RenderViewHostImpl
   scoped_ptr<MediaWebContentsObserver> media_web_contents_observer_;
 #endif
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+  // Manages all the media player managers and forwards IPCs to them.
+  scoped_ptr<tizen::MediaWebContentsObserver> media_webcontents_observer_;
+#endif
+
   // Used to swap out or shutdown this RVH when the unload event is taking too
   // long to execute, depending on the number of active views in the
   // SiteInstance.
index e0ce7f6..00cd397 100644 (file)
@@ -71,3 +71,7 @@
 #include "content/common/gin_java_bridge_messages.h"
 #include "content/common/media/media_player_messages_android.h"
 #endif  // defined(OS_ANDROID)
+
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+#include "xwalk/tizen/common/media/media_player_messages.h"
+#endif
index 3fe89ad..b30478b 100644 (file)
         'browser/power_save_blocker_x11.cc',
       ],
     }],
+    ['tizen==1 and enable_murphy==1', {
+      'sources': [
+        '<(DEPTH)/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc',
+        '<(DEPTH)/xwalk/tizen/browser/media/browser_mediaplayer_manager.h',
+        '<(DEPTH)/xwalk/tizen/browser/media/media_webcontents_observer.cc',
+        '<(DEPTH)/xwalk/tizen/browser/media/media_webcontents_observer.h',
+        '<(DEPTH)/xwalk/tizen/browser/media/murphy_mainloop.cc',
+        '<(DEPTH)/xwalk/tizen/browser/media/murphy_mainloop.h',
+        '<(DEPTH)/xwalk/tizen/browser/media/murphy_resource.cc',
+        '<(DEPTH)/xwalk/tizen/browser/media/murphy_resource.h',
+        '<(DEPTH)/xwalk/tizen/browser/media/murphy_resource_manager.cc',
+        '<(DEPTH)/xwalk/tizen/browser/media/murphy_resource_manager.h',
+      ],
+      'dependencies': [
+        '../build/linux/system.gyp:resource_manager',
+      ],
+      'export_dependent_settings': [
+        '../build/linux/system.gyp:resource_manager',
+      ],
+    }],
     ['os_bsd==1', {
       'sources/': [
         ['exclude', '^browser/gamepad/gamepad_platform_data_fetcher_linux\\.cc$'],
index 048ab0d..67d8912 100644 (file)
         '<(DEPTH)/third_party/khronos',
       ],
     }],
+    ['tizen==1 and enable_murphy==1', {
+      'sources': [
+        '<(DEPTH)/xwalk/tizen/common/media/media_player_messages.h',
+      ],
+    }],
     ['OS=="win" and directxsdk_exists=="True"', {
       'actions': [
       {
index 1d63e16..1d549db 100644 (file)
         'renderer/media/crypto/renderer_cdm_manager.h',
       ],
     }],
+    ['tizen==1 and enable_murphy==1', {
+      'sources': [
+        '<(DEPTH)/xwalk/tizen/renderer/media/mediaplayer_impl.cc',
+        '<(DEPTH)/xwalk/tizen/renderer/media/mediaplayer_impl.h',
+        '<(DEPTH)/xwalk/tizen/renderer/media/renderer_mediaplayer_manager.cc',
+        '<(DEPTH)/xwalk/tizen/renderer/media/renderer_mediaplayer_manager.h',
+      ],
+    }],
   ],
   'target_conditions': [
     ['OS=="android"', {
index 30d405f..7458aa4 100644 (file)
 #include "content/renderer/media/crypto/renderer_cdm_manager.h"
 #endif
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+#include "xwalk/tizen/renderer/media/renderer_mediaplayer_manager.h"
+#include "xwalk/tizen/renderer/media/mediaplayer_impl.h"
+#endif
+
 using blink::WebContextMenuData;
 using blink::WebData;
 using blink::WebDataSource;
@@ -444,6 +449,9 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id)
 #if defined(VIDEO_HOLE)
       contains_media_player_(false),
 #endif
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+      media_player_manager_(NULL),
+#endif
       geolocation_dispatcher_(NULL),
       push_messaging_dispatcher_(NULL),
       screen_orientation_dispatcher_(NULL),
@@ -1513,11 +1521,29 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
                  static_cast<RenderFrame*>(this)),
       RenderThreadImpl::current()->GetAudioRendererMixerManager()->CreateInput(
           render_view_->routing_id_, routing_id_));
+
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+  tizen::MediaPlayerImpl* media_player = new tizen::MediaPlayerImpl(
+      frame, client, weak_factory_.GetWeakPtr(),
+      GetTizenMediaPlayerManager(), params);
+  return media_player;
+#endif
+
   return new WebMediaPlayerImpl(frame, client, weak_factory_.GetWeakPtr(),
                                 params);
 #endif  // defined(OS_ANDROID)
 }
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+tizen::RendererMediaPlayerManager*
+RenderFrameImpl::GetTizenMediaPlayerManager() {
+  if (!media_player_manager_)
+    media_player_manager_ = new tizen::RendererMediaPlayerManager(this);
+
+  return media_player_manager_;
+}
+#endif
+
 blink::WebContentDecryptionModule*
 RenderFrameImpl::createContentDecryptionModule(
     blink::WebLocalFrame* frame,
index 0252170..7fdbe24 100644 (file)
@@ -56,6 +56,12 @@ class Range;
 class Rect;
 }
 
+#if defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+namespace tizen {
+class RendererMediaPlayerManager;
+}
+#endif
+
 namespace content {
 
 class ChildFrameCompositingHelper;
@@ -591,6 +597,8 @@ class CONTENT_EXPORT RenderFrameImpl
       blink::WebMediaPlayerClient* client);
 
   RendererMediaPlayerManager* GetMediaPlayerManager();
+#elif defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+  tizen::RendererMediaPlayerManager* GetTizenMediaPlayerManager();
 #endif
 
 #if defined(ENABLE_BROWSER_CDMS)
@@ -675,6 +683,8 @@ class CONTENT_EXPORT RenderFrameImpl
   // real media player in the browser process. It's okay to use a raw pointer
   // since it's a RenderFrameObserver.
   RendererMediaPlayerManager* media_player_manager_;
+#elif defined(OS_TIZEN) && defined(ENABLE_MURPHY)
+  tizen::RendererMediaPlayerManager* media_player_manager_;
 #endif
 
 #if defined(ENABLE_BROWSER_CDMS)
index a50c955..baf72bc 100644 (file)
@@ -1,3 +1,4 @@
+Changbin Shao <changbin.shao@intel.com>
 Daniel Narvaez <dwnarvaez@gmail.com>
 Dongseong Hwang <dongseong.hwang@intel.com>
 Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
index 04daf9f..12912d7 100644 (file)
@@ -32,7 +32,8 @@ VAStatus vaSetDisplayAttributes(VADisplay dpy, VADisplayAttribute *attr_list, in
 VAStatus vaSyncSurface(VADisplay dpy, VASurfaceID render_target);
 VAStatus vaTerminate(VADisplay dpy);
 VAStatus vaUnmapBuffer(VADisplay dpy, VABufferID buf_id);
-
+VAStatus vaLockBuffer(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info_ptr);
+VAStatus vaUnlockBuffer(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info_ptr);
 
 #------------------------------------------------
 # Functions from libva-wayland used in chromium code.
index 3c5ac59..8f5109b 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "ozone/media/vaapi_video_decode_accelerator.h"
 
+#include <string>
+
 #include "base/bind.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
@@ -15,8 +17,9 @@
 #include "content/common/gpu/gpu_channel.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/video/picture.h"
-#include "ui/gl/scoped_binders.h"
+#include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/scoped_binders.h"
 
 static void ReportToUMA(
     media::VaapiH264Decoder::VAVDAH264DecoderFailure failure) {
@@ -88,9 +91,17 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
     return size_;
   }
 
+  VAImage* va_image() {
+    return va_image_.get();
+  }
+
   // Upload vaimage data to texture. Needs to be called every frame.
   bool Upload(VASurfaceID id);
 
+  // Bind EGL image to texture. Needs to be called every frame.
+  bool Bind();
+  bool UpdateEGLImage(VASurfaceID id);
+
  private:
   TFPPicture(const base::Callback<bool(void)>& make_context_current, //NOLINT
              VaapiWrapper* va_wrapper,
@@ -100,6 +111,10 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
 
   bool Initialize();
 
+  EGLImageKHR CreateEGLImage(
+      EGLDisplay egl_display, VASurfaceID surface, VAImage* va_image);
+  bool DestroyEGLImage(EGLDisplay egl_display, EGLImageKHR egl_image);
+
   base::Callback<bool(void)> make_context_current_; //NOLINT
 
   VaapiWrapper* va_wrapper_;
@@ -109,7 +124,9 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
   uint32 texture_id_;
 
   gfx::Size size_;
-  VAImage va_image_;
+  scoped_ptr<VAImage> va_image_;
+  EGLImageKHR egl_image_;
+  EGLDisplay egl_display_;
 
   DISALLOW_COPY_AND_ASSIGN(TFPPicture);
 };
@@ -124,9 +141,12 @@ VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture(
       va_wrapper_(va_wrapper),
       picture_buffer_id_(picture_buffer_id),
       texture_id_(texture_id),
-      size_(size) {
+      size_(size),
+      va_image_(new VAImage()),
+      egl_display_(gfx::GLSurfaceEGL::GetHardwareDisplay()) {
   DCHECK(!make_context_current_.is_null());
-};
+  DCHECK(va_image_);
+}
 
 linked_ptr<VaapiVideoDecodeAccelerator::TFPPicture>
 VaapiVideoDecodeAccelerator::TFPPicture::Create(
@@ -150,7 +170,7 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize() {
   if (!make_context_current_.Run())
     return false;
 
-  if (!va_wrapper_->CreateRGBImage(size_, &va_image_)) {
+  if (!va_wrapper_->CreateRGBImage(size_, va_image_.get())) {
     DVLOG(1) << "Failed to create VAImage";
     return false;
   }
@@ -161,9 +181,31 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize() {
 VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
   DCHECK(CalledOnValidThread());
 
+  if (egl_image_ != EGL_NO_IMAGE_KHR)
+    DestroyEGLImage(egl_display_, egl_image_);
+
   if (va_wrapper_) {
-    va_wrapper_->DestroyImage(&va_image_);
+    va_wrapper_->DestroyImage(va_image_.get());
+  }
+}
+
+bool VaapiVideoDecodeAccelerator::TFPPicture::UpdateEGLImage(
+    VASurfaceID surface) {
+  DCHECK(CalledOnValidThread());
+
+  if (!make_context_current_.Run())
+    return false;
+
+  if (egl_image_ != EGL_NO_IMAGE_KHR)
+    DestroyEGLImage(egl_display_, egl_image_);
+
+  egl_image_ = CreateEGLImage(egl_display_, surface, va_image_.get());
+  if (egl_image_ == EGL_NO_IMAGE_KHR) {
+    DVLOG(1) << "Failed to create EGL image";
+    return false;
   }
+
+  return true;
 }
 
 bool VaapiVideoDecodeAccelerator::TFPPicture::Upload(VASurfaceID surface) {
@@ -172,13 +214,13 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Upload(VASurfaceID surface) {
   if (!make_context_current_.Run())
     return false;
 
-  if (!va_wrapper_->PutSurfaceIntoImage(surface, &va_image_)) {
+  if (!va_wrapper_->PutSurfaceIntoImage(surface, va_image_.get())) {
     DVLOG(1) << "Failed to put va surface to image";
     return false;
   }
 
   void* buffer = NULL;
-  if (!va_wrapper_->MapImage(&va_image_, &buffer)) {
+  if (!va_wrapper_->MapImage(va_image_.get(), &buffer)) {
     DVLOG(1) << "Failed to map VAImage";
     return false;
   }
@@ -192,23 +234,85 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Upload(VASurfaceID surface) {
   // texture output implementation. It can be removed when zero buffer copy
   // is implemented.
   unsigned int al = 4 * size_.width();
-  if (al != va_image_.pitches[0]) {
+  if (al != va_image_->pitches[0]) {
     // Not aligned phenomenon occurs only in special size video in None-X11.
     // So re-check RGBA data alignment and realign filled video frame in need.
     unsigned char* bhandle = static_cast<unsigned char*>(buffer);
     for (int i = 0; i < size_.height(); i++) {
-      memcpy(bhandle + (i * al), bhandle + (i * (va_image_.pitches[0])), al);
+      memcpy(bhandle + (i * al), bhandle + (i * (va_image_->pitches[0])), al);
     }
   }
 
-  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(),
-               0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+  glTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_BGRA,
+               size_.width(),
+               size_.height(),
+               0,
+               GL_BGRA,
+               GL_UNSIGNED_BYTE,
+               buffer);
+
+  va_wrapper_->UnmapImage(va_image_.get());
+
+  return true;
+}
 
-  va_wrapper_->UnmapImage(&va_image_);
+bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() {
+  DCHECK(CalledOnValidThread());
+  if (!make_context_current_.Run())
+    return false;
 
+  gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_);
   return true;
 }
 
+EGLImageKHR VaapiVideoDecodeAccelerator::TFPPicture::CreateEGLImage(
+    EGLDisplay egl_display, VASurfaceID va_surface, VAImage* va_image) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(va_image);
+
+  VABufferInfo buffer_info;
+  if (!va_wrapper_->LockBuffer(va_surface, va_image->buf, &buffer_info)) {
+    DVLOG(1) << "Failed to lock Buffer";
+    return EGL_NO_IMAGE_KHR;
+  }
+
+  EGLint attribs[] = {
+      EGL_WIDTH, 0,
+      EGL_HEIGHT, 0,
+      EGL_DRM_BUFFER_STRIDE_MESA, 0,
+      EGL_DRM_BUFFER_FORMAT_MESA,
+      EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+      EGL_DRM_BUFFER_USE_MESA,
+      EGL_DRM_BUFFER_USE_SHARE_MESA,
+      EGL_NONE };
+  attribs[1] = va_image->width;
+  attribs[3] = va_image->height;
+  attribs[5] = va_image->pitches[0] / 4;
+
+  EGLImageKHR egl_image =  eglCreateImageKHR(
+       egl_display,
+       EGL_NO_CONTEXT,
+       EGL_DRM_BUFFER_MESA,
+       (EGLClientBuffer) buffer_info.handle,
+       attribs);
+
+  if (va_wrapper_) {
+    va_wrapper_->UnlockBuffer(va_surface, va_image->buf, &buffer_info);
+  }
+
+  return egl_image;
+}
+
+bool VaapiVideoDecodeAccelerator::TFPPicture::DestroyEGLImage(
+    EGLDisplay egl_display, EGLImageKHR egl_image) {
+  return eglDestroyImageKHR(egl_display, egl_image);
+}
+
 VaapiVideoDecodeAccelerator::TFPPicture*
     VaapiVideoDecodeAccelerator::TFPPictureById(int32 picture_buffer_id) {
   TFPPictures::iterator it = tfp_pictures_.find(picture_buffer_id);
@@ -267,6 +371,11 @@ bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
     return false;
   }
 
+  supports_valockBuffer_apis_ = vaapi_wrapper_->SupportsVaLockBufferApis();
+  std::string query =
+      supports_valockBuffer_apis_ ? "supports" : "doesn't support";
+  LOG(INFO) << "VAAPI " << query << " vaLockBuffer apis";
+
   decoder_.reset(
       new VaapiH264Decoder(
           vaapi_wrapper_.get(),
@@ -312,11 +421,31 @@ void VaapiVideoDecodeAccelerator::OutputPicture(
                "output_id", output_id);
 
   DVLOG(3) << "Outputting VASurface " << va_surface->id()
-           << " into pixmap bound to picture buffer id " << output_id;
+           << " into texture bound to picture buffer id " << output_id;
 
-  RETURN_AND_NOTIFY_ON_FAILURE(tfp_picture->Upload(va_surface->id()),
-                               "Failed to upload VASurface to texture",
-                               PLATFORM_FAILURE, ); //NOLINT
+  if (supports_valockBuffer_apis_) {
+    RETURN_AND_NOTIFY_ON_FAILURE(
+        vaapi_wrapper_->PutSurfaceIntoImage(
+            va_surface->id(),
+            tfp_picture->va_image()),
+        "Failed putting surface into vaimage",
+        PLATFORM_FAILURE, );  //NOLINT
+
+    RETURN_AND_NOTIFY_ON_FAILURE(
+        tfp_picture->UpdateEGLImage(va_surface->id()),
+        "Failed to update egl image per vaimage info",
+        PLATFORM_FAILURE, );  //NOLINT
+
+    RETURN_AND_NOTIFY_ON_FAILURE(
+        tfp_picture->Bind(),
+        "Failed to bind egl image to texture",
+        PLATFORM_FAILURE, ); //NOLINT
+  } else {
+    RETURN_AND_NOTIFY_ON_FAILURE(
+        tfp_picture->Upload(va_surface->id()),
+        "Failed to upload VASurface to texture",
+        PLATFORM_FAILURE, ); //NOLINT
+  }
 
   // Notify the client a picture is ready to be displayed.
   ++num_frames_at_client_;
index 2b6c67a..cc3cea8 100644 (file)
@@ -268,6 +268,9 @@ private:
   // The WeakPtrFactory for |weak_this_|.
   base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_;
 
+  // Whether VaapiWrapper supports vaLockBuffer apis.
+  bool supports_valockBuffer_apis_;
+
   DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator);
 };
 
index 7b09808..08dba6a 100644 (file)
@@ -15,6 +15,7 @@
 #include "media/media/va_stubs.h"
 
 #include "third_party/libva/va/wayland/va_wayland.h"
+#include "third_party/libva/va/va_drmcommon.h"
 
 using media_media::kModuleVa_wayland;
 using media_media::InitializeStubs;
@@ -23,6 +24,9 @@ using media_media::StubPathMap;
 static const base::FilePath::CharType kVaLib[] =
     FILE_PATH_LITERAL("libva-wayland.so.1");
 
+static const char kVaLockBufferSymbol[] = "vaLockBuffer";
+static const char kVaUnlockBufferSymbol[] = "vaUnlockBuffer";
+
 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg)         \
   do {                                                     \
     DVLOG(1) << err_msg                                    \
@@ -370,14 +374,15 @@ bool VaapiWrapper::CreateRGBImage(gfx::Size size, VAImage* image) {
   base::AutoLock auto_lock(va_lock_);
   VAStatus va_res;
   VAImageFormat format;
-  format.fourcc = VA_FOURCC_RGBX;
+  format.fourcc = VA_FOURCC_BGRX;
   format.byte_order = VA_LSB_FIRST;
   format.bits_per_pixel = 32;
   format.depth = 24;
-  format.red_mask = 0xff;
-  format.green_mask = 0xff00;
+  format.red_mask = 0x0000ff;
+  format.green_mask = 0x00ff00;
   format.blue_mask = 0xff0000;
   format.alpha_mask = 0;
+
   va_res = vaCreateImage(va_display_,
                          &format,
                          size.width(),
@@ -421,6 +426,32 @@ bool VaapiWrapper::PutSurfaceIntoImage(VASurfaceID va_surface_id,
   VA_SUCCESS_OR_RETURN(va_res, "Failed to put surface into image", false);
   return true;
 }
+
+bool VaapiWrapper::LockBuffer(VASurfaceID va_surface_id,
+                              VABufferID buf_id,
+                              VABufferInfo* buf_info) {
+  DCHECK(buf_info);
+  base::AutoLock auto_lock(va_lock_);
+
+  buf_info->mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
+  VAStatus va_res = vaLockBuffer(va_display_, buf_id, buf_info);
+  VA_SUCCESS_OR_RETURN(va_res, "Failed to lock vabuffer", false);
+
+  return true;
+}
+
+bool VaapiWrapper::UnlockBuffer(VASurfaceID va_surface_id,
+                                VABufferID buf_id,
+                                VABufferInfo* buf_info) {
+  DCHECK(buf_info);
+  base::AutoLock auto_lock(va_lock_);
+  VAStatus va_res = vaUnlockBuffer(va_display_, buf_id, buf_info);
+  VA_SUCCESS_OR_RETURN(va_res, "Failed to unlock vabuffer", false);
+
+  return true;
+}
+
+
 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id,
                                         VAImage* image,
                                         void** mem) {
@@ -462,4 +493,14 @@ bool VaapiWrapper::PostSandboxInitialization() {
   return ret;
 }
 
+bool VaapiWrapper::SupportsVaLockBufferApis() {
+  void* handle = dlopen(kVaLib, RTLD_LAZY);
+  if (!handle) {
+    LOG(ERROR) << "Could not open " << kVaLib;
+    return false;
+  }
+  return dlsym(handle, kVaLockBufferSymbol) &&
+         dlsym(handle, kVaUnlockBufferSymbol);
+}
+
 }  // namespace media
index d2b0e21..37ee77b 100644 (file)
@@ -82,6 +82,14 @@ class CONTENT_EXPORT VaapiWrapper {
   // Put data from |va_surface_id| into |va_image|, converting/scaling it.
   bool PutSurfaceIntoImage(VASurfaceID va_surface_id,
                            VAImage* va_image);
+
+  bool LockBuffer(VASurfaceID va_surface_id,
+                  VABufferID buf_id,
+                  VABufferInfo* buf_info);
+  bool UnlockBuffer(VASurfaceID va_surface_id,
+                    VABufferID buf_id,
+                    VABufferInfo* buf_info);
+
   // Returns true if the VAAPI version is less than the specified version.
   bool VAAPIVersionLessThan(int major, int minor);
 
@@ -96,6 +104,9 @@ class CONTENT_EXPORT VaapiWrapper {
   // GetVaImage(). This is intended for testing only.
   void ReturnVaImageForTesting(VAImage* image);
 
+  // Return true if libva supports vaLockBuffer & vaUnlockBuffer apis.
+  bool SupportsVaLockBufferApis();
+
  private:
   VaapiWrapper();
 
diff --git a/src/ozone/patches/0007-Introduce-vaLockBuffer-APIs-in-libva.patch b/src/ozone/patches/0007-Introduce-vaLockBuffer-APIs-in-libva.patch
new file mode 100644 (file)
index 0000000..cc17bec
--- /dev/null
@@ -0,0 +1,167 @@
+From e06df3445ac9a82446ddba30e2978cc693d39574 Mon Sep 17 00:00:00 2001
+From: Shao Changbin <changbin.shao@intel.com>
+Date: Thu, 4 Sep 2014 12:44:01 +0800
+Subject: [PATCH] Introduce vaLockBuffer APIs in libva.
+
+---
+ third_party/libva/va/va.h         | 111 ++++++++++++++++++++++++++++++++++++++
+ third_party/libva/va/va_backend.h |  14 +++++
+ 2 files changed, 125 insertions(+)
+
+diff --git a/third_party/libva/va/va.h b/third_party/libva/va/va.h
+index 845760c..9455023 100644
+--- a/third_party/libva/va/va.h
++++ b/third_party/libva/va/va.h
+@@ -78,6 +78,7 @@
+ #ifndef _VA_H_
+ #define _VA_H_
+
++#include <stddef.h>
+ #include <stdint.h>
+ #include <va/va_version.h>
+
+@@ -1851,6 +1852,116 @@ VAStatus vaDestroyBuffer (
+     VABufferID buffer_id
+ );
+
++/** VA buffer information */
++typedef struct {
++    /** Buffer handle */
++    uintptr_t           handle;
++    /** Buffer type (See VABufferType). */
++    uint32_t            type;
++    /**
++     * Buffer memory type (See VASurfaceAttribMemoryType).
++     *
++     * On input to vaLockBuffer(), this field can serve as a hint to
++     * specify the set of memory types the caller is interested in. On
++     * successful return from vaLockBuffer(), the field is updated
++     * with the best matching memory type.
++     */
++    uint32_t            mem_type;
++    /** Size of the underlying buffer. */
++    size_t              mem_size;
++} VABufferInfo;
++
++/**
++ * Locks buffer for external API usage.
++ *
++ * Locks the VA buffer object buf_id for external API usage like
++ * EGL or OpenCL (OCL). This function is a synchronization point. This
++ * means that any pending operation is guaranteed to be completed
++ * prior to returning from the function.
++ *
++ * If the referenced VA buffer object is the backing store of a VA
++ * surface, then this function acts as if vaSyncSurface() on the
++ * parent surface was called first.
++ *
++ * The VABufferInfo argument shall be zero'ed on input. On
++ * successful output, the data structure is filled in with all the
++ * necessary buffer level implementation details like handle, type,
++ * memory type and memory size.
++ *
++ * Note: the external API implementation, or the application, can
++ * express the memory types it is interested in by filling in the
++ * mem_type field accordingly. On successful output, the memory type
++ * that fits best the request and that was used is updated in the
++ * VABufferInfo data structure. If none of the supplied memory types
++ * is supported, then a VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE
++ * error is returned.
++ *
++ * The VABufferInfo data is valid until vaUnlockBuffer() is
++ * called. Besides, no additional operation is allowed on any of the
++ * buffer parent object until vaUnlockBuffer() is called. e.g. decoding
++ * into a VA surface backed with the supplied VA buffer object
++ * buf_id would fail with a VA_STATUS_ERROR_SURFACE_BUSY error.
++ *
++ * Possible errors:
++ * - VA_STATUS_ERROR_UNIMPLEMENTED: the VA driver implementation
++ *   does not support this interface
++ * - VA_STATUS_ERROR_INVALID_DISPLAY: an invalid display was supplied
++ * - VA_STATUS_ERROR_INVALID_BUFFER: an invalid buffer was supplied
++ * - VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: the implementation
++ *   does not support exporting buffers of the specified type
++ * - VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE: none of the requested
++ *   memory types in \ref VABufferInfo.mem_type was supported
++ *
++ * @param[in] dpy               the VA display
++ * @param[in] buf_id            the VA buffer
++ * @param[in,out] buf_info_ptr  the VA buffer information
++ * @return VA_STATUS_SUCCESS if successful
++ */
++VAStatus
++vaLockBuffer(
++    VADisplay           dpy,
++    VABufferID          buf_id,
++    VABufferInfo *      buf_info_ptr
++);
++
++/**
++ * Unlocks buffer after usage from external API.
++ *
++ * Unlocks the VA buffer object buf_id from external API usage like
++ * EGL or OpenCL (OCL). This function is a synchronization point. This
++ * means that any pending operation is guaranteed to be completed
++ * prior to returning from the function.
++ *
++ * The VABufferInfo argument shall point to the original data
++ * structure that was obtained from vaLockBuffer(), unaltered. This is
++ * necessary so that the VA driver implementation could deallocate any
++ * resources that were needed.
++ *
++ * In any case, returning from this function invalidates any contents
++ * in VABufferInfo. i.e. the underlyng buffer handle is no longer
++ * valid. Therefore, VA driver implementations are free to reset this
++ * data structure to safe defaults.
++ *
++ * Possible errors:
++ * - VA_STATUS_ERROR_UNIMPLEMENTED: the VA driver implementation
++ *   does not support this interface
++ * - VA_STATUS_ERROR_INVALID_DISPLAY: an invalid display was supplied
++ * - VA_STATUS_ERROR_INVALID_BUFFER: an invalid buffer was supplied
++ * - VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: the implementation
++ *   does not support exporting buffers of the specified type
++ *
++ * @param[in] dpy               the VA display
++ * @param[in] buf_id            the VA buffer
++ * @param[in,out] buf_info_ptr  the VA buffer information
++ * @return VA_STATUS_SUCCESS if successful
++ */
++VAStatus
++vaUnlockBuffer(
++    VADisplay           dpy,
++    VABufferID          buf_id,
++    VABufferInfo *      buf_info_ptr
++);
++
+ /*
+ Render (Decode) Pictures
+
+diff --git a/third_party/libva/va/va_backend.h b/third_party/libva/va/va_backend.h
+index bd82849..150f8ef 100644
+--- a/third_party/libva/va/va_backend.h
++++ b/third_party/libva/va/va_backend.h
+@@ -420,6 +420,20 @@ struct VADriverVTable
+             VASurfaceAttrib    *attrib_list,
+             unsigned int       *num_attribs
+         );
++
++        VAStatus
++        (*vaLockBuffer)(
++            VADriverContextP    ctx,
++            VABufferID          buf_id,
++            VABufferInfo *      buf_info_ptr
++        );
++
++        VAStatus
++        (*vaUnlockBuffer)(
++            VADriverContextP    ctx,
++            VABufferID          buf_id,
++            VABufferInfo *      buf_info_ptr
++        );
+ };
+
+ struct VADriverContext
+--
+1.9.1
+
index cecfae3..117a872 100644 (file)
@@ -363,10 +363,10 @@ void DesktopWindowTreeHostWayland::GetWindowPlacement(
     ui::WindowShowState* show_state) const {
   *bounds = GetRestoredBounds();
 
-  if (IsFullscreen()) {
-    *show_state = ui::SHOW_STATE_FULLSCREEN;
-  } else if (IsMinimized()) {
+  if (IsMinimized()) {
     *show_state = ui::SHOW_STATE_MINIMIZED;
+  } else if (IsFullscreen()) {
+    *show_state = ui::SHOW_STATE_FULLSCREEN;
   } else if (IsMaximized()) {
     *show_state = ui::SHOW_STATE_MAXIMIZED;
   } else if (!IsActive()) {
@@ -455,9 +455,7 @@ void DesktopWindowTreeHostWayland::Minimize() {
   if (state_ & Minimized)
     return;
 
-  state_ &= ~Maximized;
   state_ |= Minimized;
-  state_ &= ~Normal;
   previous_bounds_ = bounds_;
   ui::WindowStateChangeHandler::GetInstance()->SetWidgetState(window_,
                                                               ui::MINIMIZED);
@@ -791,6 +789,10 @@ void DesktopWindowTreeHostWayland::HandleWindowResize(unsigned width,
   }
 }
 
+void DesktopWindowTreeHostWayland::HandleWindowUnminimized() {
+  state_ &= ~Minimized;
+}
+
 void DesktopWindowTreeHostWayland::HandleCommit(const std::string& text) {
   ui::InputMethodAuraLinux* inputMethod =
       static_cast<ui::InputMethodAuraLinux*>(desktop_native_widget_aura_->
index 1377ae6..4eeda04 100644 (file)
@@ -171,6 +171,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWayland
 
   void HandleNativeWidgetActivationChanged(bool active);
   void HandleWindowResize(unsigned width, unsigned height);
+  void HandleWindowUnminimized();
 
   void HandlePreeditChanged(const std::string& text, const std::string& commit);
   void HandleCommit(const std::string& text);
index 02e478b..75a5477 100644 (file)
@@ -289,6 +289,13 @@ void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
   window->HandleWindowResize(width, height);
 }
 
+void WindowTreeHostDelegateWayland::OnWindowUnminimized(unsigned handle) {
+  DesktopWindowTreeHostWayland* window =
+      DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
+  DCHECK(window);
+  window->HandleWindowUnminimized();
+}
+
 void WindowTreeHostDelegateWayland::OnCommit(unsigned handle,
                                              const std::string& text) {
   DesktopWindowTreeHostWayland* window =
index 03cc0e7..1679c5d 100644 (file)
@@ -57,6 +57,7 @@ class WindowTreeHostDelegateWayland
   virtual void OnWindowResized(unsigned windowhandle,
                                unsigned width,
                                unsigned height) OVERRIDE;
+  virtual void OnWindowUnminimized(unsigned windowhandle) OVERRIDE;
   virtual void OnPreeditChanged(unsigned handle,
                                 const std::string& text,
                                 const std::string& commit) OVERRIDE;
index af563ed..7e63077 100644 (file)
@@ -94,6 +94,11 @@ void EventConverterInProcess::WindowResized(unsigned handle,
           height));
 }
 
+void EventConverterInProcess::WindowUnminimized(unsigned handle) {
+  ui::EventConverterOzoneWayland::PostTaskOnMainLoop(base::Bind(
+      &EventConverterInProcess::NotifyWindowUnminimized, this, handle));
+}
+
 void EventConverterInProcess::Commit(unsigned handle, const std::string& text) {
   ui::EventConverterOzoneWayland::PostTaskOnMainLoop(base::Bind(
       &EventConverterInProcess::NotifyCommit, this, handle, text));
@@ -240,6 +245,13 @@ EventConverterInProcess::NotifyWindowResized(EventConverterInProcess* data,
 }
 
 void
+EventConverterInProcess::NotifyWindowUnminimized(EventConverterInProcess* data,
+                                                 unsigned handle) {
+  if (data->observer_)
+    data->observer_->OnWindowUnminimized(handle);
+}
+
+void
 EventConverterInProcess::NotifyCommit(EventConverterInProcess* data,
                                       unsigned handle,
                                       const std::string& text) {
index 63d5dab..2007e18 100644 (file)
@@ -47,6 +47,7 @@ class EventConverterInProcess : public ui::EventConverterOzoneWayland,
   virtual void WindowResized(unsigned windowhandle,
                              unsigned width,
                              unsigned height) OVERRIDE;
+  virtual void WindowUnminimized(unsigned windowhandle) OVERRIDE;
 
   virtual void Commit(unsigned handle, const std::string& text) OVERRIDE;
   virtual void PreeditChanged(unsigned handle, const std::string& text,
@@ -104,6 +105,8 @@ class EventConverterInProcess : public ui::EventConverterOzoneWayland,
                                   unsigned handle,
                                   unsigned width,
                                   unsigned height);
+  static void NotifyWindowUnminimized(EventConverterInProcess* data,
+                                      unsigned handle);
   static void NotifyCommit(EventConverterInProcess* data, unsigned handle,
                            const std::string& text);
   static void NotifyPreeditChanged(EventConverterInProcess* data,
index f448418..095ef79 100644 (file)
@@ -48,6 +48,7 @@ class OZONE_WAYLAND_EXPORT EventConverterOzoneWayland {
   virtual void WindowResized(unsigned windowhandle,
                              unsigned width,
                              unsigned height) = 0;
+  virtual void WindowUnminimized(unsigned windowhandle) = 0;
   virtual void CloseWidget(unsigned handle) = 0;
   virtual void Commit(unsigned handle, const std::string& text) = 0;
   virtual void PreeditChanged(unsigned handle, const std::string& text,
index 4719600..1850705 100644 (file)
@@ -78,6 +78,10 @@ void RemoteEventDispatcher::WindowResized(unsigned handle,
   Dispatch(new WaylandWindow_Resized(handle, width, height));
 }
 
+void RemoteEventDispatcher::WindowUnminimized(unsigned handle) {
+  Dispatch(new WaylandWindow_Unminimized(handle));
+}
+
 void RemoteEventDispatcher::CloseWidget(unsigned handle) {
   Dispatch(new WaylandInput_CloseWidget(handle));
 }
index 8004a89..a80cfca 100644 (file)
@@ -48,6 +48,7 @@ class RemoteEventDispatcher : public ui::EventConverterOzoneWayland {
   virtual void WindowResized(unsigned handle,
                              unsigned width,
                              unsigned height) OVERRIDE;
+  virtual void WindowUnminimized(unsigned windowhandle) OVERRIDE;
   virtual void CloseWidget(unsigned handle) OVERRIDE;
 
   virtual void Commit(unsigned handle, const std::string& text) OVERRIDE;
index aee64a0..71d2089 100644 (file)
@@ -28,6 +28,7 @@ class OZONE_WAYLAND_EXPORT WindowChangeObserver {
   virtual void OnWindowResized(unsigned windowhandle,
                                unsigned width,
                                unsigned height) = 0;
+  virtual void OnWindowUnminimized(unsigned windowhandle) = 0;
   // FIXME(joone): Move to IMEChangeObserver?
   virtual void OnPreeditChanged(unsigned handle,
                                 const std::string& text,
index 8a46069..ca351a9 100644 (file)
@@ -80,6 +80,9 @@ IPC_MESSAGE_CONTROL3(WaylandWindow_Resized,  // NOLINT(readability/fn_size)
                      unsigned /* width */,
                      unsigned /* height */)
 
+IPC_MESSAGE_CONTROL1(WaylandWindow_Unminimized,  // NOLINT(readability/fn_size)
+                     unsigned /*handle*/)
+
 IPC_MESSAGE_CONTROL4(WaylandWindow_State,  // NOLINT(readability/fn_size)
                      unsigned /* window handle */,
                      ui::WidgetState /*state*/,
index 57e1081..88fba8c 100644 (file)
@@ -56,6 +56,7 @@ bool OzoneChannelHost::OnMessageReceived(const IPC::Message& message) {
   IPC_MESSAGE_HANDLER(WaylandInput_OutputSize, OnOutputSizeChanged)
   IPC_MESSAGE_HANDLER(WaylandInput_CloseWidget, OnCloseWidget)
   IPC_MESSAGE_HANDLER(WaylandWindow_Resized, OnWindowResized)
+  IPC_MESSAGE_HANDLER(WaylandWindow_Unminimized, OnWindowUnminimized)
   IPC_MESSAGE_HANDLER(WaylandInput_Commit, OnCommit)
   IPC_MESSAGE_HANDLER(WaylandInput_PreeditChanged, OnPreeditChanged)
   IPC_MESSAGE_HANDLER(WaylandInput_PreeditEnd, OnPreeditEnd)
@@ -126,6 +127,10 @@ void OzoneChannelHost::OnWindowResized(unsigned handle,
   event_converter_->WindowResized(handle, width, height);
 }
 
+void OzoneChannelHost::OnWindowUnminimized(unsigned handle) {
+  event_converter_->WindowUnminimized(handle);
+}
+
 void OzoneChannelHost::OnCommit(unsigned handle, std::string text) {
   event_converter_->Commit(handle, text);
 }
index fa4dc7f..ca73db7 100644 (file)
@@ -46,6 +46,7 @@ class OzoneChannelHost : public GpuPlatformSupportHost {
   void OnWindowResized(unsigned handle,
                        unsigned width,
                        unsigned height);
+  void OnWindowUnminimized(unsigned handle);
   void OnCommit(unsigned handle, std::string text);
   void OnPreeditChanged(unsigned handle, std::string text, std::string commit);
   void OnPreeditEnd();
index b38b27b..799f97b 100644 (file)
@@ -52,4 +52,17 @@ void WaylandShellSurface::WindowResized(void* data,
   dispatcher->WindowResized(window->Handle(), width, height);
 }
 
+void WaylandShellSurface::WindowActivated(void *data) {
+  WaylandWindow *window = static_cast<WaylandWindow*>(data);
+  WaylandShellSurface* shellSurface = window->ShellSurface();
+
+  if (shellSurface->IsMinimized()) {
+    shellSurface->Unminimize();
+
+    ui::EventConverterOzoneWayland* dispatcher =
+      ui::EventFactoryOzoneWayland::GetInstance()->EventConverter();
+    dispatcher->WindowUnminimized(window->Handle());
+  }
+}
+
 }  // namespace ozonewayland
index 28e4e51..35251af 100644 (file)
@@ -31,10 +31,13 @@ class WaylandShellSurface {
   virtual void SetWindowTitle(const base::string16& title) = 0;
   virtual void Maximize() = 0;
   virtual void Minimize() = 0;
+  virtual void Unminimize() = 0;
+  virtual bool IsMinimized() const = 0;
 
   // static functions.
   static void PopupDone();
   static void WindowResized(void *data, unsigned width, unsigned height);
+  static void WindowActivated(void *data);
 
  protected:
   void FlushDisplay() const;
index cf2adfe..6206ac3 100644 (file)
@@ -94,6 +94,13 @@ void WLShellSurface::Maximize() {
 void WLShellSurface::Minimize() {
 }
 
+void WLShellSurface::Unminimize() {
+}
+
+bool WLShellSurface::IsMinimized() const {
+  return false;
+}
+
 void WLShellSurface::HandleConfigure(void* data,
                                      struct wl_shell_surface* surface,
                                      uint32_t edges,
index f4ae13b..4b09b9e 100644 (file)
@@ -25,6 +25,8 @@ class WLShellSurface : public WaylandShellSurface {
   virtual void SetWindowTitle(const base::string16& title) OVERRIDE;
   virtual void Maximize() OVERRIDE;
   virtual void Minimize() OVERRIDE;
+  virtual void Unminimize() OVERRIDE;
+  virtual bool IsMinimized() const OVERRIDE;
 
   static void HandleConfigure(void* data,
                               struct wl_shell_surface* shell_surface,
index 264bd6e..57b4d0a 100644 (file)
@@ -18,7 +18,8 @@ XDGShellSurface::XDGShellSurface()
     : WaylandShellSurface(),
       xdg_surface_(NULL),
       xdg_popup_(NULL),
-      maximized_(false) {
+      maximized_(false),
+      minimized_(false) {
 }
 
 XDGShellSurface::~XDGShellSurface() {
@@ -118,6 +119,15 @@ void XDGShellSurface::Maximize() {
 
 void XDGShellSurface::Minimize() {
   xdg_surface_set_minimized(xdg_surface_);
+  minimized_ = true;
+}
+
+void XDGShellSurface::Unminimize() {
+  minimized_ = false;
+}
+
+bool XDGShellSurface::IsMinimized() const {
+  return minimized_;
 }
 
 void XDGShellSurface::HandleConfigure(void* data,
@@ -137,6 +147,7 @@ void XDGShellSurface::HandleChangeState(void* data,
 
 void XDGShellSurface::HandleActivate(void* data,
                                  struct xdg_surface* xdg_surface) {
+  WaylandShellSurface::WindowActivated(data);
 }
 
 void XDGShellSurface::HandleDeactivate(void* data,
index 764013f..a2fb0c4 100644 (file)
@@ -28,6 +28,8 @@ class XDGShellSurface : public WaylandShellSurface {
   virtual void SetWindowTitle(const base::string16& title) OVERRIDE;
   virtual void Maximize() OVERRIDE;
   virtual void Minimize() OVERRIDE;
+  virtual void Unminimize() OVERRIDE;
+  virtual bool IsMinimized() const OVERRIDE;
 
   static void HandleConfigure(void* data,
                               struct xdg_surface* xdg_surface,
@@ -53,6 +55,7 @@ class XDGShellSurface : public WaylandShellSurface {
   xdg_surface* xdg_surface_;
   xdg_popup* xdg_popup_;
   bool maximized_;
+  bool minimized_;
   DISALLOW_COPY_AND_ASSIGN(XDGShellSurface);
 };
 
index 845760c..9455023 100644 (file)
@@ -78,6 +78,7 @@
 #ifndef _VA_H_
 #define _VA_H_
 
+#include <stddef.h>
 #include <stdint.h>
 #include <va/va_version.h>
 
@@ -1851,6 +1852,116 @@ VAStatus vaDestroyBuffer (
     VABufferID buffer_id
 );
 
+/** VA buffer information */
+typedef struct {
+    /** Buffer handle */
+    uintptr_t           handle;
+    /** Buffer type (See VABufferType). */
+    uint32_t            type;
+    /**
+     * Buffer memory type (See VASurfaceAttribMemoryType).
+     *
+     * On input to vaLockBuffer(), this field can serve as a hint to
+     * specify the set of memory types the caller is interested in. On
+     * successful return from vaLockBuffer(), the field is updated
+     * with the best matching memory type.
+     */
+    uint32_t            mem_type;
+    /** Size of the underlying buffer. */
+    size_t              mem_size;
+} VABufferInfo;
+
+/**
+ * Locks buffer for external API usage.
+ *
+ * Locks the VA buffer object buf_id for external API usage like
+ * EGL or OpenCL (OCL). This function is a synchronization point. This
+ * means that any pending operation is guaranteed to be completed
+ * prior to returning from the function.
+ *
+ * If the referenced VA buffer object is the backing store of a VA
+ * surface, then this function acts as if vaSyncSurface() on the
+ * parent surface was called first.
+ *
+ * The VABufferInfo argument shall be zero'ed on input. On
+ * successful output, the data structure is filled in with all the
+ * necessary buffer level implementation details like handle, type,
+ * memory type and memory size.
+ *
+ * Note: the external API implementation, or the application, can
+ * express the memory types it is interested in by filling in the
+ * mem_type field accordingly. On successful output, the memory type
+ * that fits best the request and that was used is updated in the
+ * VABufferInfo data structure. If none of the supplied memory types
+ * is supported, then a VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE
+ * error is returned.
+ *
+ * The VABufferInfo data is valid until vaUnlockBuffer() is
+ * called. Besides, no additional operation is allowed on any of the
+ * buffer parent object until vaUnlockBuffer() is called. e.g. decoding
+ * into a VA surface backed with the supplied VA buffer object
+ * buf_id would fail with a VA_STATUS_ERROR_SURFACE_BUSY error.
+ *
+ * Possible errors:
+ * - VA_STATUS_ERROR_UNIMPLEMENTED: the VA driver implementation
+ *   does not support this interface
+ * - VA_STATUS_ERROR_INVALID_DISPLAY: an invalid display was supplied
+ * - VA_STATUS_ERROR_INVALID_BUFFER: an invalid buffer was supplied
+ * - VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: the implementation
+ *   does not support exporting buffers of the specified type
+ * - VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE: none of the requested
+ *   memory types in \ref VABufferInfo.mem_type was supported
+ *
+ * @param[in] dpy               the VA display
+ * @param[in] buf_id            the VA buffer
+ * @param[in,out] buf_info_ptr  the VA buffer information
+ * @return VA_STATUS_SUCCESS if successful
+ */
+VAStatus
+vaLockBuffer(
+    VADisplay           dpy,
+    VABufferID          buf_id,
+    VABufferInfo *      buf_info_ptr
+);
+
+/**
+ * Unlocks buffer after usage from external API.
+ *
+ * Unlocks the VA buffer object buf_id from external API usage like
+ * EGL or OpenCL (OCL). This function is a synchronization point. This
+ * means that any pending operation is guaranteed to be completed
+ * prior to returning from the function.
+ *
+ * The VABufferInfo argument shall point to the original data
+ * structure that was obtained from vaLockBuffer(), unaltered. This is
+ * necessary so that the VA driver implementation could deallocate any
+ * resources that were needed.
+ *
+ * In any case, returning from this function invalidates any contents
+ * in VABufferInfo. i.e. the underlyng buffer handle is no longer
+ * valid. Therefore, VA driver implementations are free to reset this
+ * data structure to safe defaults.
+ *
+ * Possible errors:
+ * - VA_STATUS_ERROR_UNIMPLEMENTED: the VA driver implementation
+ *   does not support this interface
+ * - VA_STATUS_ERROR_INVALID_DISPLAY: an invalid display was supplied
+ * - VA_STATUS_ERROR_INVALID_BUFFER: an invalid buffer was supplied
+ * - VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: the implementation
+ *   does not support exporting buffers of the specified type
+ *
+ * @param[in] dpy               the VA display
+ * @param[in] buf_id            the VA buffer
+ * @param[in,out] buf_info_ptr  the VA buffer information
+ * @return VA_STATUS_SUCCESS if successful
+ */
+VAStatus
+vaUnlockBuffer(
+    VADisplay           dpy,
+    VABufferID          buf_id,
+    VABufferInfo *      buf_info_ptr
+);
+
 /*
 Render (Decode) Pictures
 
index bd82849..150f8ef 100644 (file)
@@ -420,6 +420,20 @@ struct VADriverVTable
             VASurfaceAttrib    *attrib_list,
             unsigned int       *num_attribs
         );
+
+        VAStatus
+        (*vaLockBuffer)(
+            VADriverContextP    ctx,
+            VABufferID          buf_id,
+            VABufferInfo *      buf_info_ptr
+        );
+
+        VAStatus
+        (*vaUnlockBuffer)(
+            VADriverContextP    ctx,
+            VABufferID          buf_id,
+            VABufferInfo *      buf_info_ptr
+        );
 };
 
 struct VADriverContext
index 7fc193d..d021520 100644 (file)
@@ -22,6 +22,14 @@ typedef uint32_t SnapshotObjectId;
  */
 class V8_EXPORT CpuProfileNode {
  public:
+  struct LineTick {
+    /** The 1-based number of the source line where the function originates. */
+    int line;
+
+    /** The count of samples associated with the source line. */
+    unsigned int hit_count;
+  };
+
   /** Returns function name (empty string for anonymous functions.) */
   Handle<String> GetFunctionName() const;
 
@@ -43,6 +51,18 @@ class V8_EXPORT CpuProfileNode {
    */
   int GetColumnNumber() const;
 
+  /**
+   * Returns the number of the function's source lines that collect the samples.
+   */
+  unsigned int GetHitLineCount() const;
+
+  /** Returns the set of source lines that collect the samples.
+   *  The caller allocates buffer and responsible for releasing it.
+   *  True if all available entries are copied, otherwise false.
+   *  The function copies nothing if buffer is not large enough.
+   */
+  bool GetLineTicks(LineTick* entries, unsigned int length) const;
+
   /** Returns bailout reason for the function
     * if the optimization was disabled for it.
     */
index 3d9e9d8..0552d6f 100644 (file)
@@ -7037,6 +7037,19 @@ int CpuProfileNode::GetColumnNumber() const {
 }
 
 
+unsigned int CpuProfileNode::GetHitLineCount() const {
+  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+  return node->GetHitLineCount();
+}
+
+
+bool CpuProfileNode::GetLineTicks(LineTick* entries,
+                                  unsigned int length) const {
+  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+  return node->GetLineTicks(entries, length);
+}
+
+
 const char* CpuProfileNode::GetBailoutReason() const {
   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
   return node->entry()->bailout_reason();
index 68a565c..115324c 100644 (file)
@@ -256,20 +256,38 @@ 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;
+  JITLineInfoTable* line_table = NULL;
+  if (shared->script()->IsScript()) {
+    DCHECK(Script::cast(shared->script()));
+    script = Script::cast(shared->script());
+    line_table = new JITLineInfoTable();
+    for (RelocIterator it(code); !it.done(); it.next()) {
+      RelocInfo::Mode mode = it.rinfo()->rmode();
+      if (RelocInfo::IsPosition(mode)) {
+        int position = static_cast<int>(it.rinfo()->data());
+        if (position >= 0) {
+          int pc_offset = static_cast<int>(it.rinfo()->pc() - code->address());
+          int line_number = script->GetLineNumber(position) + 1;
+          line_table->SetPosition(pc_offset, line_number);
+        }
+      }
+    }
+  }
   rec->entry = profiles_->NewCodeEntry(
       tag, profiles_->GetFunctionName(shared->DebugName()),
       CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line,
-      column);
+      column, line_table);
   if (info) {
     rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
   }
-  DCHECK(Script::cast(shared->script()));
-  Script* script = Script::cast(shared->script());
-  rec->entry->set_script_id(script->id()->value());
-  rec->size = code->ExecutableSize();
-  rec->shared = shared->address();
+  if (script) {
+    rec->entry->set_script_id(script->id()->value());
+  }
   rec->entry->set_bailout_reason(
       GetBailoutReason(shared->DisableOptimizationReason()));
+  rec->size = code->ExecutableSize();
+  rec->shared = shared->address();
   processor_->Enqueue(evt_rec);
 }
 
index 0297f88..ea8b73f 100644 (file)
@@ -848,6 +848,7 @@ void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
 void FullCodeGenerator::SetSourcePosition(int pos) {
   if (pos != RelocInfo::kNoPosition) {
     masm_->positions_recorder()->RecordPosition(pos);
+    masm_->positions_recorder()->WriteRecordedPositions();
   }
 }
 
index 58c124f..b27a009 100644 (file)
@@ -15,7 +15,8 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
                      const char* name_prefix,
                      const char* resource_name,
                      int line_number,
-                     int column_number)
+                     int column_number,
+                     JITLineInfoTable* line_info)
     : tag_(tag),
       builtin_id_(Builtins::builtin_count),
       name_prefix_(name_prefix),
@@ -26,7 +27,8 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
       shared_id_(0),
       script_id_(v8::UnboundScript::kNoScriptId),
       no_frame_ranges_(NULL),
-      bailout_reason_(kEmptyBailoutReason) { }
+      bailout_reason_(kEmptyBailoutReason),
+      line_info_(line_info) { }
 
 
 bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) {
@@ -39,12 +41,18 @@ bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) {
 }
 
 
+static bool LineTickMatch(void* a, void* b) {
+    return a == b;
+}
+
+
 ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry)
     : tree_(tree),
       entry_(entry),
       self_ticks_(0),
       children_(CodeEntriesMatch),
-      id_(tree->next_node_id()) { }
+      id_(tree->next_node_id()),
+      line_ticks_(LineTickMatch) { }
 
 } }  // namespace v8::internal
 
index 6017f12..3f79c6a 100644 (file)
@@ -139,6 +139,7 @@ const char* const CodeEntry::kEmptyBailoutReason = "";
 
 CodeEntry::~CodeEntry() {
   delete no_frame_ranges_;
+  delete line_info_;
 }
 
 
@@ -181,6 +182,14 @@ void CodeEntry::SetBuiltinId(Builtins::Name id) {
 }
 
 
+int CodeEntry::GetSourceLine(int pc_offset) const {
+  if (line_info_ && !line_info_->Empty()) {
+    return line_info_->GetSourceLineNumber(pc_offset);
+  }
+  return v8::CpuProfileNode::kNoLineNumberInfo;
+}
+
+
 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
   HashMap::Entry* map_entry =
       children_.Lookup(entry, CodeEntryHash(entry), false);
@@ -202,6 +211,41 @@ ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) {
 }
 
 
+void ProfileNode::IncrementLineTicks(int src_line) {
+  if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) return;
+  // 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<void*>(src_line), src_line, true);
+  DCHECK(e);
+  e->value = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(e->value) + 1);
+}
+
+
+bool ProfileNode::GetLineTicks(v8::CpuProfileNode::LineTick* entries,
+                               unsigned int length) const {
+  if (entries == NULL || length == 0) return false;
+
+  unsigned line_count = line_ticks_.occupancy();
+
+  if (line_count == 0) return false;
+  if (length < line_count) return false;
+
+  v8::CpuProfileNode::LineTick* entry = entries;
+
+  for (HashMap::Entry* p = line_ticks_.Start();
+       p != NULL;
+       p = line_ticks_.Next(p), entry++) {
+    entry->line =
+      static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->key));
+    entry->hit_count =
+      static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->value));
+  }
+
+  return true;
+}
+
+
 void ProfileNode::Print(int indent) {
   base::OS::Print("%5u %*s %s%s %d #%d %s", self_ticks_, indent, "",
                   entry_->name_prefix(), entry_->name(), entry_->script_id(),
@@ -242,7 +286,8 @@ ProfileTree::~ProfileTree() {
 }
 
 
-ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
+ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path,
+                                         int src_line) {
   ProfileNode* node = root_;
   for (CodeEntry** entry = path.start() + path.length() - 1;
        entry != path.start() - 1;
@@ -252,11 +297,15 @@ ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
     }
   }
   node->IncrementSelfTicks();
+  if (src_line != v8::CpuProfileNode::kNoLineNumberInfo) {
+    node->IncrementLineTicks(src_line);
+  }
   return node;
 }
 
 
-void ProfileTree::AddPathFromStart(const Vector<CodeEntry*>& path) {
+void ProfileTree::AddPathFromStart(const Vector<CodeEntry*>& path,
+                                   int src_line) {
   ProfileNode* node = root_;
   for (CodeEntry** entry = path.start();
        entry != path.start() + path.length();
@@ -266,6 +315,9 @@ void ProfileTree::AddPathFromStart(const Vector<CodeEntry*>& path) {
     }
   }
   node->IncrementSelfTicks();
+  if (src_line != v8::CpuProfileNode::kNoLineNumberInfo) {
+    node->IncrementLineTicks(src_line);
+  }
 }
 
 
@@ -327,8 +379,9 @@ CpuProfile::CpuProfile(const char* title, bool record_samples)
 
 
 void CpuProfile::AddPath(base::TimeTicks timestamp,
-                         const Vector<CodeEntry*>& path) {
-  ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path);
+                         const Vector<CodeEntry*>& path,
+                         int src_line) {
+  ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path, src_line);
   if (record_samples_) {
     timestamps_.Add(timestamp);
     samples_.Add(top_frame_node);
@@ -517,13 +570,15 @@ void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) {
 
 
 void CpuProfilesCollection::AddPathToCurrentProfiles(
-    base::TimeTicks timestamp, const Vector<CodeEntry*>& path) {
+    base::TimeTicks timestamp,
+    const Vector<CodeEntry*>& path,
+    int src_line) {
   // As starting / stopping profiles is rare relatively to this
   // method, we don't bother minimizing the duration of lock holding,
   // e.g. copying contents of the list to a local vector.
   current_profiles_semaphore_.Wait();
   for (int i = 0; i < current_profiles_.length(); ++i) {
-    current_profiles_[i]->AddPath(timestamp, path);
+    current_profiles_[i]->AddPath(timestamp, path, src_line);
   }
   current_profiles_semaphore_.Signal();
 }
@@ -535,13 +590,15 @@ CodeEntry* CpuProfilesCollection::NewCodeEntry(
       const char* name_prefix,
       const char* resource_name,
       int line_number,
-      int column_number) {
+      int column_number,
+      JITLineInfoTable* line_info) {
   CodeEntry* code_entry = new CodeEntry(tag,
                                         name,
                                         name_prefix,
                                         resource_name,
                                         line_number,
-                                        column_number);
+                                        column_number,
+                                        line_info);
   code_entries_.Add(code_entry);
   return code_entry;
 }
@@ -579,6 +636,14 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
   // entries vector with NULL values.
   CodeEntry** entry = entries.start();
   memset(entry, 0, entries.length() * sizeof(*entry));
+
+  // The ProfileNode knows nothing about all versions of generated code for
+  // 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.
+  int src_line = v8::CpuProfileNode::kNoLineNumberInfo;
+
   if (sample.pc != NULL) {
     if (sample.has_external_callback && sample.state == EXTERNAL &&
         sample.top_frame_type == StackFrame::EXIT) {
@@ -595,10 +660,10 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
       // frame. Check for this case and just skip such samples.
       if (pc_entry) {
         List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
+        Code* code = Code::cast(HeapObject::FromAddress(start));
+        int pc_offset = static_cast<int>(sample.pc - code->instruction_start());
+        src_line = pc_entry->GetSourceLine(pc_offset);
         if (ranges) {
-          Code* code = Code::cast(HeapObject::FromAddress(start));
-          int pc_offset = static_cast<int>(
-              sample.pc - code->instruction_start());
           for (int i = 0; i < ranges->length(); i++) {
             OffsetRange& range = ranges->at(i);
             if (range.from <= pc_offset && pc_offset < range.to) {
@@ -622,11 +687,29 @@ 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;
          ++stack_pos) {
-      *entry++ = code_map_.FindEntry(*stack_pos);
+      Address start = NULL;
+      *entry = code_map_.FindEntry(*stack_pos, &start);
+
+      // Skip unresolved frames (e.g. internal frame) and get source line of
+      // the JS caller.
+      if (src_line_not_found && *entry) {
+        Code* code = Code::cast(HeapObject::FromAddress(start));
+        int pc_offset =
+            static_cast<int>(*stack_pos - code->instruction_start());
+        src_line = (*entry)->GetSourceLine(pc_offset);
+        if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) {
+          src_line = (*entry)->line_number();
+        }
+        src_line_not_found = false;
+      }
+
+      entry++;
     }
   }
 
@@ -644,7 +727,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
     }
   }
 
-  profiles_->AddPathToCurrentProfiles(sample.timestamp, entries);
+  profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line);
 }
 
 
index 5ebb92b..f973eb2 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef V8_PROFILE_GENERATOR_H_
 #define V8_PROFILE_GENERATOR_H_
 
+#include <map>
 #include "include/v8-profiler.h"
 #include "src/allocation.h"
 #include "src/hashmap.h"
@@ -44,6 +45,36 @@ class StringsStorage {
 };
 
 
+// Provides a mapping from the offsets within generated code to
+// the source line.
+class JITLineInfoTable : public Malloced {
+ public:
+  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));
+  }
+
+  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(); }
+
+ private:
+  // pc_offset -> source line
+  typedef std::map<int, int> PcOffsetMap;
+  PcOffsetMap pc_offset_map_;
+  DISALLOW_COPY_AND_ASSIGN(JITLineInfoTable);
+};
+
 class CodeEntry {
  public:
   // CodeEntry doesn't own name strings, just references them.
@@ -52,7 +83,8 @@ class CodeEntry {
                    const char* name_prefix = CodeEntry::kEmptyNamePrefix,
                    const char* resource_name = CodeEntry::kEmptyResourceName,
                    int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
-                   int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
+                   int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
+                   JITLineInfoTable* line_info = NULL);
   ~CodeEntry();
 
   bool is_js_function() const { return is_js_function_tag(tag_); }
@@ -62,6 +94,7 @@ class CodeEntry {
   const char* resource_name() const { return resource_name_; }
   int line_number() const { return line_number_; }
   int column_number() const { return column_number_; }
+  const JITLineInfoTable* line_info() const { return line_info_; }
   void set_shared_id(int shared_id) { shared_id_ = shared_id; }
   int script_id() const { return script_id_; }
   void set_script_id(int script_id) { script_id_ = script_id; }
@@ -83,6 +116,8 @@ class CodeEntry {
   uint32_t GetCallUid() const;
   bool IsSameAs(CodeEntry* entry) const;
 
+  int GetSourceLine(int pc_offset) const;
+
   static const char* const kEmptyNamePrefix;
   static const char* const kEmptyResourceName;
   static const char* const kEmptyBailoutReason;
@@ -99,6 +134,7 @@ class CodeEntry {
   int script_id_;
   List<OffsetRange>* no_frame_ranges_;
   const char* bailout_reason_;
+  JITLineInfoTable* line_info_;
 
   DISALLOW_COPY_AND_ASSIGN(CodeEntry);
 };
@@ -114,11 +150,15 @@ class ProfileNode {
   ProfileNode* FindOrAddChild(CodeEntry* entry);
   void IncrementSelfTicks() { ++self_ticks_; }
   void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; }
+  void IncrementLineTicks(int src_line);
 
   CodeEntry* entry() const { return entry_; }
   unsigned self_ticks() const { return self_ticks_; }
   const List<ProfileNode*>* children() const { return &children_list_; }
   unsigned id() const { return id_; }
+  unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); }
+  bool GetLineTicks(v8::CpuProfileNode::LineTick* entries,
+                    unsigned int length) const;
 
   void Print(int indent);
 
@@ -139,6 +179,7 @@ class ProfileNode {
   HashMap children_;
   List<ProfileNode*> children_list_;
   unsigned id_;
+  HashMap line_ticks_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileNode);
 };
@@ -149,8 +190,11 @@ class ProfileTree {
   ProfileTree();
   ~ProfileTree();
 
-  ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
-  void AddPathFromStart(const Vector<CodeEntry*>& path);
+  ProfileNode* AddPathFromEnd(
+    const Vector<CodeEntry*>& path,
+    int src_line = v8::CpuProfileNode::kNoLineNumberInfo);
+  void AddPathFromStart(const Vector<CodeEntry*>& path,
+                        int src_line = v8::CpuProfileNode::kNoLineNumberInfo);
   ProfileNode* root() const { return root_; }
   unsigned next_node_id() { return next_node_id_++; }
 
@@ -175,7 +219,9 @@ class CpuProfile {
   CpuProfile(const char* title, bool record_samples);
 
   // Add pc -> ... -> main() call path to the profile.
-  void AddPath(base::TimeTicks timestamp, const Vector<CodeEntry*>& path);
+  void AddPath(base::TimeTicks timestamp,
+               const Vector<CodeEntry*>& path,
+               int src_line);
   void CalculateTotalTicksAndSamplingRate();
 
   const char* title() const { return title_; }
@@ -282,11 +328,13 @@ class CpuProfilesCollection {
       const char* name_prefix = CodeEntry::kEmptyNamePrefix,
       const char* resource_name = CodeEntry::kEmptyResourceName,
       int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
-      int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
+      int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
+      JITLineInfoTable* line_info = NULL);
 
   // Called from profile generator thread.
-  void AddPathToCurrentProfiles(
-      base::TimeTicks timestamp, const Vector<CodeEntry*>& path);
+  void AddPathToCurrentProfiles(base::TimeTicks timestamp,
+                                const Vector<CodeEntry*>& path,
+                                int src_line);
 
   // Limits the number of profiles that can be simultaneously collected.
   static const int kMaxSimultaneousProfiles = 100;
index 6051c3f..ee2d149 100644 (file)
@@ -1064,6 +1064,111 @@ TEST(BoundFunctionCall) {
 }
 
 
+// This tests checks distribution of the samples through the source lines.
+TEST(TickLines) {
+  CcTest::InitializeVM();
+  LocalContext env;
+  i::Isolate* isolate = CcTest::i_isolate();
+  i::Factory* factory = isolate->factory();
+  i::HandleScope scope(isolate);
+
+  i::EmbeddedVector<char, 512> script;
+
+  const char* func_name = "func";
+  i::SNPrintF(script,
+      "function %s() {\n"
+      "  for (var i = 0; i < 10; ++i) {\n"
+      "    var n = 0;\n"
+      "    var m = 100*100;\n"
+      "    while (m > 1) {\n"
+      "      m--;\n"
+      "      n += m * m * m;\n"
+      "    }\n"
+      "  }\n"
+      "}\n"
+      "%s();\n", func_name, func_name);
+
+  CompileRun(script.start());
+
+  i::Handle<i::JSFunction> func = v8::Utils::OpenHandle(
+      *v8::Local<v8::Function>::Cast(
+      (*env)->Global()->Get(v8_str(func_name))));
+  CHECK_NE(NULL, func->shared());
+  CHECK_NE(NULL, func->shared()->code());
+  i::Code* code = NULL;
+  if (func->code()->is_optimized_code()) {
+    code = func->code();
+  } else {
+    CHECK(func->shared()->code() == func->code() || !i::FLAG_crankshaft);
+    code = func->shared()->code();
+  }
+  CHECK_NE(NULL, code);
+  i::Address code_address = code->address();
+  CHECK_NE(NULL, code_address);
+
+  CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap());
+  profiles->StartProfiling("", false);
+  ProfileGenerator generator(profiles);
+  SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
+      &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100)));
+  processor->Start();
+  CpuProfiler profiler(isolate, profiles, &generator, processor.get());
+
+  // Enqueue code creation events.
+  i::Handle<i::String> str = factory->NewStringFromAsciiChecked(func_name);
+  int line = 1;
+  int column = 1;
+  profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG,
+                           code,
+                           func->shared(),
+                           NULL,
+                           *str,
+                           line,
+                           column);
+
+  // Enqueue a tick event to enable code events processing.
+  EnqueueTickSampleEvent(processor.get(), code_address);
+
+  processor->StopSynchronously();
+
+  CpuProfile* profile = profiles->StopProfiling("");
+  CHECK_NE(NULL, profile);
+
+  // Check the state of profile generator.
+  CodeEntry* func_entry = generator.code_map()->FindEntry(code_address);
+  CHECK_NE(NULL, func_entry);
+  CHECK_EQ(func_name, func_entry->name());
+  const i::JITLineInfoTable* line_info = func_entry->line_info();
+  CHECK_NE(NULL, line_info);
+  CHECK_EQ(false, line_info->Empty());
+
+  // Check the hit source lines using V8 Public APIs.
+  const i::ProfileTree* tree = profile->top_down();
+  ProfileNode* root = tree->root();
+  CHECK_NE(NULL, root);
+  ProfileNode* func_node = root->FindChild(func_entry);
+  CHECK_NE(NULL, func_node);
+
+  // Add 10 faked ticks to source line #5.
+  int hit_line = 5;
+  int hit_count = 10;
+  for (int i = 0; i < hit_count; i++)
+    func_node->IncrementLineTicks(hit_line);
+
+  unsigned int line_count = func_node->GetHitLineCount();
+  CHECK_EQ(2, line_count);  // Expect two hit source lines - #1 and #5.
+  ScopedVector<v8::CpuProfileNode::LineTick> entries(line_count);
+  CHECK_EQ(true, func_node->GetLineTicks(&entries[0], line_count));
+  int value = 0;
+  for (int i = 0; i < entries.length(); i++)
+    if (entries[i].line == hit_line) {
+      value = entries[i].hit_count;
+      break;
+    }
+  CHECK_EQ(hit_count, value);
+}
+
+
 static const char* call_function_test_source = "function bar(iterations) {\n"
 "}\n"
 "function start(duration) {\n"
index c279ba4..37a0fdb 100644 (file)
 # Edit these when rolling DEPS.xwalk.
 # -----------------------------------
 
-chromium_crosswalk_rev = 'e5698a22dd1587355fd53fa7142be15776985608'
+chromium_crosswalk_rev = '04ba13a65546e6e6309e560b9a2491b904ed57a8'
 blink_crosswalk_rev = '92e5d6adee53362b3f5aaec11bcb0526d5f0715d'
-v8_crosswalk_rev = '0bb343f5ed1becef0996a234d5d7d431e60ef72a'
-ozone_wayland_rev = 'db2f41907a6c63f8c1dfc100f4db4ce5b2259a76'
+v8_crosswalk_rev = '6264ffa1bef0681640afbafb5194c55a172ef6df'
+ozone_wayland_rev = 'd301e5c546a7dea0de8fde5b07a2a57afd02103b'
 
 crosswalk_git = 'https://github.com/crosswalk-project'
 ozone_wayland_git = 'https://github.com/01org'
index 828bb76..20b37ca 100644 (file)
@@ -1,4 +1,4 @@
 MAJOR=9
 MINOR=38
-BUILD=198
+BUILD=204
 PATCH=0
index 8b7384f..391a7cc 100644 (file)
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.xwalk.app.hello.world">
 
-    <application android:name="org.xwalk.app.runtime.XWalkRuntimeApplication"
+    <application android:name="org.xwalk.core.XWalkApplication"
         android:label="XWalkAppHelloWorld" android:hardwareAccelerated="true"
         android:icon="@drawable/crosswalk">
         <activity android:name="org.xwalk.app.hello.world.HelloWorldActivity"
index 81b4710..5fd2cbb 100644 (file)
@@ -10,7 +10,7 @@
     package="org.xwalk.app.template"
     android:installLocation="auto">
 
-    <application android:name="org.xwalk.app.runtime.XWalkRuntimeApplication"
+    <application android:name="org.xwalk.core.XWalkApplication"
         android:label="XWalkAppTemplate" android:hardwareAccelerated="true"
         android:icon="@drawable/crosswalk">
         <activity android:name="org.xwalk.app.template.AppTemplateActivity"
index c031579..a7842bf 100644 (file)
@@ -14,18 +14,18 @@ import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.View;
-import android.widget.Toast;
 
-import org.xwalk.app.runtime.CrossPackageWrapper;
-import org.xwalk.app.runtime.CrossPackageWrapperExceptionHandler;
-import org.xwalk.app.runtime.XWalkRuntimeClient;
+import org.xwalk.app.runtime.extension.XWalkRuntimeExtensionManager;
 import org.xwalk.app.runtime.XWalkRuntimeLibraryException;
+import org.xwalk.app.runtime.XWalkRuntimeView;
+import org.xwalk.core.ReflectionHelper;
+import org.xwalk.core.XWalkPreferences;
 
-public abstract class XWalkRuntimeActivityBase extends Activity implements CrossPackageWrapperExceptionHandler {
+public abstract class XWalkRuntimeActivityBase extends Activity {
 
     private static final String DEFAULT_LIBRARY_APK_URL = null;
 
-    private XWalkRuntimeClient mRuntimeView;
+    private XWalkRuntimeView mRuntimeView;
 
     private boolean mShownNotFoundDialog = false;
 
@@ -35,6 +35,8 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
 
     private AlertDialog mLibraryNotFoundDialog = null;
 
+    private XWalkRuntimeExtensionManager mExtensionManager;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         IntentFilter intentFilter = new IntentFilter("org.xwalk.intent");
@@ -50,10 +52,9 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
                 if (bundle.containsKey("remotedebugging")) {
                     String extra = bundle.getString("remotedebugging");
                     if (extra.equals("true")) {
-                        String mPackageName = getApplicationContext().getPackageName();
-                        mRuntimeView.enableRemoteDebugging("", mPackageName);
+                        XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
                     } else if (extra.equals("false")) {
-                        mRuntimeView.disableRemoteDebugging();
+                        XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
                     }
                 }
             }
@@ -61,50 +62,52 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
         registerReceiver(mReceiver, intentFilter);
         super.onCreate(savedInstanceState);
         tryLoadRuntimeView();
-        mRuntimeView.onCreate();
+        if (mRuntimeView != null) mRuntimeView.onCreate();
     }
 
     @Override
     public void onStart() {
         super.onStart();
-        tryLoadRuntimeView();
-        mRuntimeView.onStart();
+        if (mExtensionManager != null) mExtensionManager.onStart();
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        mRuntimeView.onPause();
+        if (mRuntimeView != null) mRuntimeView.onPause();
+        if (mExtensionManager != null) mExtensionManager.onPause();
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        mRuntimeView.onResume();
+        if (mRuntimeView != null) mRuntimeView.onResume();
+        if (mExtensionManager != null) mExtensionManager.onResume();
     }
 
     @Override
     public void onStop() {
         super.onStop();
-        mRuntimeView.onStop();
+        if (mExtensionManager != null) mExtensionManager.onStop();
     }
 
     @Override
     public void onDestroy() {
         unregisterReceiver(mReceiver);
+        if (mExtensionManager != null) mExtensionManager.onDestroy();
         super.onDestroy();
-        mRuntimeView.onDestroy();
     }
 
     @Override
     public void onNewIntent(Intent intent) {
-       if (!mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
+        if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
     }
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-        mRuntimeView.onActivityResult(requestCode, resultCode, data);
+        if (mRuntimeView != null) mRuntimeView.onActivityResult(requestCode, resultCode, data);
+        if (mExtensionManager != null) mExtensionManager.onActivityResult(requestCode, resultCode, data);
     }
 
     private String getLibraryApkDownloadUrl() {
@@ -120,30 +123,39 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
     }
 
     private void tryLoadRuntimeView() {
-        if (mRuntimeView == null || mRuntimeView.get() == null) {
-            mRuntimeView = new XWalkRuntimeClient(this, null, this);
-            if (mRuntimeView.get() != null) {
-                mShownNotFoundDialog = false;
-                if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
-            }
+        try {
+            mRuntimeView = new XWalkRuntimeView(this, this, null);
+            mShownNotFoundDialog = false;
+            if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
             if (mRemoteDebugging) {
-                String mPackageName = getApplicationContext().getPackageName();
-                mRuntimeView.enableRemoteDebugging("", mPackageName);
+                XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
             } else {
-                mRuntimeView.disableRemoteDebugging();
+                XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
             }
-
-            didTryLoadRuntimeView(mRuntimeView.get());
+            // XWalkPreferences.ENABLE_EXTENSIONS
+            if (XWalkPreferences.getValue("enable-extensions")) {
+                // Enable xwalk extension mechanism and start load extensions here.
+                // Note that it has to be after above initialization.
+                mExtensionManager = new XWalkRuntimeExtensionManager(getApplicationContext(), this);
+                mExtensionManager.loadExtensions();
+            }
+        } catch (Exception e) {
+            handleException(e);
         }
+        didTryLoadRuntimeView(mRuntimeView);
     }
 
-    public XWalkRuntimeClient getRuntimeView() {
+    public XWalkRuntimeView getRuntimeView() {
         return mRuntimeView;
     }
 
-    @Override
-    public void onException(Exception e) {
-        if (e.getClass() == XWalkRuntimeLibraryException.class) {
+    public void handleException(Throwable e) {
+        if (e instanceof RuntimeException) {
+            handleException(e.getCause());
+            return;
+        }
+
+        if (e instanceof XWalkRuntimeLibraryException) {
             String title = "";
             String message = "";
             XWalkRuntimeLibraryException runtimeException = (XWalkRuntimeLibraryException) e;
@@ -163,26 +175,20 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
             case XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_INVOKE_FAILED:
             default:
                 Exception originException = runtimeException.getOriginException();
-                if (originException != null) onException(originException);
+                if (originException != null) handleException(originException);
                 return;
             }
             showRuntimeLibraryExceptionDialog(title, message);
         } else {
             e.printStackTrace();
-            onException(e.getLocalizedMessage());
             throw new RuntimeException(e);
         }
     }
 
-    @Override
-    public void onException(String message) {
-        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
-    }
-
     private void showRuntimeLibraryExceptionDialog(String title, String message) {
         if (!mShownNotFoundDialog) {
             AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            if (XWalkRuntimeClient.libraryIsEmbedded()) {
+            if (!ReflectionHelper.shouldUseLibrary()) {
                 builder.setPositiveButton(android.R.string.ok,
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int id) {
@@ -212,7 +218,7 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
                             public void onClick(DialogInterface dialog, int id) {
                                 Intent goToMarket = new Intent(Intent.ACTION_VIEW);
                                 goToMarket.setData(Uri.parse(
-                                        "market://details?id="+CrossPackageWrapper.LIBRARY_APK_PACKAGE_NAME));
+                                        "market://details?id=org.xwalk.core"));
                                 startActivity(goToMarket);
                             }
                         });
diff --git a/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapper.java b/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapper.java
deleted file mode 100644 (file)
index 27307d4..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2013 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.app.runtime;
-
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public abstract class CrossPackageWrapper {
-    public final static String LIBRARY_APK_PACKAGE_NAME = "org.xwalk.runtime.lib";
-    private Context mLibCtx;
-    private Class<?> mTargetClass;
-    private Constructor<?> mCreator;
-    private CrossPackageWrapperExceptionHandler mExceptionHandler;
-    private static boolean sLibraryEmbedded = true;
-
-    public CrossPackageWrapper(Context ctx, String className,
-            CrossPackageWrapperExceptionHandler handler, Class<?>... parameters) {
-        try {
-            mTargetClass = ctx.getClassLoader().loadClass(className);
-            sLibraryEmbedded = true;
-        } catch (ClassNotFoundException e) {
-            sLibraryEmbedded = false;
-        }
-        mExceptionHandler = handler;
-        try {
-            if (sLibraryEmbedded) {
-                mLibCtx = ctx;
-            } else {
-                mLibCtx = ctx.createPackageContext(
-                        LIBRARY_APK_PACKAGE_NAME,
-                        Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
-                Context app = ctx.getApplicationContext();
-                assert(app instanceof XWalkRuntimeApplication);
-                XWalkRuntimeApplication xwalkApp = (XWalkRuntimeApplication) app;
-                xwalkApp.addResource(mLibCtx.getResources());
-
-                mTargetClass =
-                        mLibCtx.getClassLoader().loadClass(className);
-            }
-            mCreator = mTargetClass.getConstructor(parameters);
-        } catch (NameNotFoundException e) {
-            handleException(e);
-        } catch (ClassNotFoundException e) {
-            handleException(e);
-        } catch (NoSuchMethodException e) {
-            handleException(e);
-        }
-    }
-
-    public Object createInstance(Object... parameters) {
-        Object ret = null;
-        if (mCreator != null) {
-            try {
-                ret = mCreator.newInstance(parameters);
-            } catch (IllegalArgumentException e) {
-                handleException(e);
-            } catch (InstantiationException e) {
-                handleException(e);
-            } catch (IllegalAccessException e) {
-                handleException(e);
-            } catch (InvocationTargetException e) {
-                handleException(e);
-            }
-        }
-        return ret;
-    }
-
-    public void handleException(Exception e) {
-        if (mExceptionHandler != null) mExceptionHandler.onException(e);
-    }
-
-    public void handleException(String e) {
-        if (mExceptionHandler != null) mExceptionHandler.onException(e);
-    }
-
-    public Class<?> getTargetClass() {
-        return mTargetClass;
-    }
-
-    public Context getLibraryContext() {
-        return mLibCtx;
-    }
-
-    public Method lookupMethod(String method, Class<?>... parameters) {
-        if (mTargetClass == null) return null;
-        try {
-            return mTargetClass.getMethod(method, parameters);
-        } catch (NoSuchMethodException e) {
-            handleException(e);
-        }
-        return null;
-    }
-
-    public Object invokeMethod(Method m, Object instance, Object... parameters) {
-        Object ret = null;
-        if (m != null) {
-            try {
-                ret = m.invoke(instance, parameters);
-            } catch (IllegalArgumentException e) {
-                handleException(e);
-            } catch (IllegalAccessException e) {
-                handleException(e);
-            } catch (InvocationTargetException e) {
-                handleException(e);
-            } catch (NullPointerException e) {
-                handleException(e);
-            }
-        }
-        return ret;
-    }
-
-    public static boolean libraryIsEmbedded() {
-        return sLibraryEmbedded;
-    }
-}
diff --git a/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapperExceptionHandler.java b/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapperExceptionHandler.java
deleted file mode 100644 (file)
index 1cd3065..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2013 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.app.runtime;
-
-public interface CrossPackageWrapperExceptionHandler {
-    public void onException(Exception e);
-    public void onException(String msg);
-}
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.runtime;
+package org.xwalk.app.runtime;
 
 import android.app.Activity;
 import android.content.Context;
@@ -10,6 +10,8 @@ import android.content.Intent;
 import android.view.View;
 import android.widget.FrameLayout;
 
+import org.xwalk.core.SharedXWalkExceptionHandler;
+import org.xwalk.core.SharedXWalkView;
 import org.xwalk.core.XWalkView;
 import org.xwalk.core.XWalkPreferences;
 
@@ -31,7 +33,13 @@ class XWalkCoreProviderImpl implements XWalkRuntimeViewProvider {
     private void init(Context context, Activity activity) {
         // TODO(yongsheng): do customizations for XWalkView. There will
         // be many callback classes which are needed to be implemented.
-        mXWalkView = new XWalkView(context, activity);
+        mXWalkView = new SharedXWalkView(context, activity, new SharedXWalkExceptionHandler() {
+            @Override
+            public void onSharedLibraryNotFound() {
+                throw new RuntimeException(new XWalkRuntimeLibraryException(
+                        XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_INSTALLED));
+            }
+        });
     }
 
     @Override
@@ -49,10 +57,6 @@ class XWalkCoreProviderImpl implements XWalkRuntimeViewProvider {
     }
 
     @Override
-    public void onStart() {
-    }
-
-    @Override
     public void onResume() {
     }
 
@@ -61,10 +65,6 @@ class XWalkCoreProviderImpl implements XWalkRuntimeViewProvider {
     }
 
     @Override
-    public void onStop() {
-    }
-
-    @Override
     public void onDestroy() {
     }
 
diff --git a/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeClient.java b/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeClient.java
deleted file mode 100644 (file)
index f7317aa..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright (c) 2013 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.app.runtime;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import java.lang.reflect.Method;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * This class is to encapsulate the reflection detail of
- * invoking XWalkRuntimeView class in library APK.
- *
- * A web application APK should use this class in its Activity.
- */
-public class XWalkRuntimeClient extends CrossPackageWrapper {
-    private final static String RUNTIME_VIEW_CLASS_NAME = "org.xwalk.runtime.XWalkRuntimeView";
-    private boolean mRuntimeLoaded = false;
-    private Object mInstance;
-    private Method mLoadAppFromUrl;
-    private Method mLoadAppFromManifest;
-    private Method mOnCreate;
-    private Method mOnStart;
-    private Method mOnResume;
-    private Method mOnPause;
-    private Method mOnStop;
-    private Method mOnDestroy;
-    private Method mOnActivityResult;
-    private Method mOnNewIntent;
-    private Method mEnableRemoteDebugging;
-    private Method mDisableRemoteDebugging;
-
-    // For instrumentation test.
-    private Method mGetTitleForTest;
-    private Method mSetCallbackForTest;
-    private Method mLoadDataForTest;
-
-    public XWalkRuntimeClient(Activity activity, AttributeSet attrs, CrossPackageWrapperExceptionHandler exceptionHandler) {
-        super(activity, RUNTIME_VIEW_CLASS_NAME, exceptionHandler, Activity.class, Context.class, AttributeSet.class);
-        Context libCtx = getLibraryContext();
-        mInstance = this.createInstance(activity, libCtx, attrs);
-        Method getVersion = lookupMethod("getVersion");
-        String libVersion = (String) invokeMethod(getVersion, mInstance);
-        if (libVersion == null) {
-            // If the code executes to here and libVersion got is null, it means
-            // the library package is available but native library is not.
-            // It probably meets CPU arch mismatch, stop execution here to avoid crash.
-            // A dialog should be prompt to user for this information.
-            return;
-        }
-        if (!compareVersion(libVersion, getVersion())) {
-            handleException(new XWalkRuntimeLibraryException(
-                    XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_UP_TO_DATE_CRITICAL));
-            mInstance = null;
-            return;
-        }
-        mRuntimeLoaded = true;
-        mLoadAppFromUrl = lookupMethod("loadAppFromUrl", String.class);
-        mLoadAppFromManifest = lookupMethod("loadAppFromManifest", String.class);
-        mOnCreate = lookupMethod("onCreate");
-        mOnStart = lookupMethod("onStart");
-        mOnResume = lookupMethod("onResume");
-        mOnPause = lookupMethod("onPause");
-        mOnStop = lookupMethod("onStop");
-        mOnDestroy = lookupMethod("onDestroy");
-        mOnActivityResult = lookupMethod("onActivityResult", int.class, int.class, Intent.class);
-        mOnNewIntent = lookupMethod("onNewIntent", Intent.class);
-        mEnableRemoteDebugging = lookupMethod("enableRemoteDebugging", String.class, String.class);
-        mDisableRemoteDebugging = lookupMethod("disableRemoteDebugging");
-    }
-
-    /**
-     * Compare the given versions.
-     * @param libVersion version of library apk
-     * @param clientVersion version of client
-     * @return true if library is not older than client, false otherwise or either of the version string
-     * is invalid. Valid string should be \d+[\.\d+]*
-     */
-    private static boolean compareVersion(String libVersion, String clientVersion) {
-        if (libVersion.equals(clientVersion)) {
-            return true;
-        }
-        Pattern version = Pattern.compile("\\d+(\\.\\d+)*");
-        Matcher lib = version.matcher(libVersion);
-        Matcher client = version.matcher(clientVersion);
-        if (lib.matches() && client.matches()) {
-            StringTokenizer libTokens = new StringTokenizer(libVersion, ".");
-            StringTokenizer clientTokens = new StringTokenizer(clientVersion, ".");
-            int libTokenCount = libTokens.countTokens();
-            int clientTokenCount = clientTokens.countTokens();
-            if (libTokenCount == clientTokenCount) {
-                while (libTokens.hasMoreTokens()) {
-                    int libValue = 0;
-                    int clientValue = 0;
-                    try {
-                        libValue = Integer.parseInt(libTokens.nextToken());
-                        clientValue = Integer.parseInt(clientTokens.nextToken());
-                    } catch (NumberFormatException e) {
-                        return false;
-                    }
-                    if (libValue == clientValue) continue;
-                    return libValue > clientValue;
-                }
-                return true;
-            } else {
-                return libTokenCount > clientTokenCount;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void handleException(Exception e) {
-        // Here is for handling runtime library not found,
-        // Should never happen if runtime is embedded.
-        if (libraryIsEmbedded()) throw new RuntimeException(e);
-
-        // XWalkView will handle UnsatisfiedLinkError which indicates mismatch of CPU architecture.
-        // So exception here should be either library not installed for shared mode or invoke error.
-        Exception toHandle = e;
-        if (mRuntimeLoaded) {
-            toHandle = new XWalkRuntimeLibraryException(
-                    XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_INVOKE_FAILED, e);
-        } else {
-            if (!(e instanceof XWalkRuntimeLibraryException)) {
-                toHandle = new XWalkRuntimeLibraryException(
-                        XWalkRuntimeLibraryException.XWALK_RUNTIME_LIBRARY_NOT_INSTALLED, e);
-            }
-        }
-        super.handleException(toHandle);
-    }
-
-    public FrameLayout get() {
-        return (FrameLayout) mInstance;
-    }
-
-    /**
-     * Get the version information of current runtime client.
-     *
-     * @return the string containing the version information.
-     */
-    public static String getVersion() {
-        return XWalkRuntimeClientVersion.XWALK_RUNTIME_CLIENT_VERSION;
-    }
-
-    /**
-     * Load a web application through the entry url. It may be
-     * a file from assets or a url from network.
-     *
-     * @param url the url of loaded html resource.
-     */
-    public void loadAppFromUrl(String url) {
-        invokeMethod(mLoadAppFromUrl, mInstance, url);
-    }
-
-    /**
-     * Load a web application through the url of the manifest file.
-     * The manifest file typically is placed in android assets. Now it is
-     * compliant to W3C SysApps spec.
-     *
-     * @param manifestUrl the url of the manifest file
-     */
-    public void loadAppFromManifest(String manifestUrl) {
-        invokeMethod(mLoadAppFromManifest, mInstance, manifestUrl);
-    }
-
-    /**
-     * Tell runtime that the application is on creating. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onCreate() {
-        invokeMethod(mOnCreate, mInstance);
-    }
-
-    /**
-     * Tell runtime that the application is on starting. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onStart() {
-        invokeMethod(mOnStart, mInstance);
-    }
-
-    /**
-     * Tell runtime that the application is on resuming. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onResume() {
-        invokeMethod(mOnResume, mInstance);
-    }
-
-    /**
-     * Tell runtime that the application is on pausing. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onPause() {
-        invokeMethod(mOnPause, mInstance);
-    }
-
-    /**
-     * Tell runtime that the application is on stopping. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onStop() {
-        invokeMethod(mOnStop, mInstance);
-    }
-
-    /**
-     * Tell runtime that the application is on destroying. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onDestroy() {
-        invokeMethod(mOnDestroy, mInstance);
-    }
-
-    /**
-     * Tell runtime that one activity exists so that it can know the result code
-     * of the exit code.
-     *
-     * @param requestCode the request code to identify where the result is from
-     * @param resultCode the result code of the activity
-     * @param data the data to contain the result data
-     */
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        invokeMethod(mOnActivityResult, mInstance, requestCode, resultCode, data);
-    }
-
-    /**
-     * Tell runtime that the activity receive a new Intent. The Intent may contain
-     * data that runtime wants to deal with.
-     * @param intent the new coming Intent.
-     * @return boolean whether runtime consumed it. 
-     */
-    public boolean onNewIntent(Intent intent) {
-        Boolean handled = (Boolean) invokeMethod(mOnNewIntent, mInstance, intent);
-        if (handled != null) return handled;
-        return false;
-    }
-
-    /**
-     * Enable remote debugging for the loaded web application. The caller
-     * can set the url of debugging url. Besides, the socket name for remote
-     * debugging has to be unique so typically the string can be appended
-     * with the package name of the application.
-     *
-     * @param frontEndUrl the url of debugging url. If it's empty, then a
-     *                    default url will be used.
-     * @param socketName the unique socket name for setting up socket for
-     *                   remote debugging.
-     * @return the url of web socket for remote debugging.
-     */
-    public void enableRemoteDebugging(String frontEndUrl, String socketName) {
-        invokeMethod(mEnableRemoteDebugging, mInstance, frontEndUrl, socketName);
-    }
-
-    /**
-     * Disable remote debugging so runtime can close related stuff for
-     * this feature.
-     */
-    public void disableRemoteDebugging() {
-        invokeMethod(mDisableRemoteDebugging, mInstance);
-    }
-
-    // The following functions just for instrumentation test.
-    public View getViewForTest() {
-        return (View)mInstance;
-    }
-
-    public String getTitleForTest() {
-        if (mGetTitleForTest == null) {
-            mGetTitleForTest = lookupMethod("getTitleForTest");
-        }
-
-        return (String) invokeMethod(mGetTitleForTest, mInstance);
-    }
-
-    public void setCallbackForTest(Object callback) {
-        if (mSetCallbackForTest == null) {
-            mSetCallbackForTest = lookupMethod("setCallbackForTest", Object.class);
-        }
-
-        invokeMethod(mSetCallbackForTest, mInstance, callback);
-    }
-
-    public void loadDataForTest(String data, String mimeType, boolean isBase64Encoded) {
-        if (mLoadDataForTest == null) {
-            mLoadDataForTest = lookupMethod("loadDataForTest", String.class, String.class, boolean.class);
-        }
-
-        invokeMethod(mLoadDataForTest, mInstance, data, mimeType, isBase64Encoded);
-    }
-}
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.runtime;
+package org.xwalk.app.runtime;
 
 import android.content.Context;
 import android.graphics.Bitmap;
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.runtime;
+package org.xwalk.app.runtime;
 
 import android.app.Activity;
 import android.content.Context;
@@ -33,12 +33,12 @@ public class XWalkRuntimeView extends FrameLayout {
      * @param context a context when creating this package
      * @param attrs the attributes of the XML tag that is inflating the view
      */
-    public XWalkRuntimeView(Activity activity, Context libContext, AttributeSet attrs) {
-        super(libContext, attrs);
+    public XWalkRuntimeView(Activity activity, Context context, AttributeSet attrs) {
+        super(context, attrs);
 
         // MixedContext is needed for cross package because the application
         // context is different.
-        init(new MixedContext(libContext, activity), activity);
+        init(context, activity);
     }
 
     /**
@@ -99,14 +99,6 @@ public class XWalkRuntimeView extends FrameLayout {
     }
 
     /**
-     * Tell runtime that the application is on starting. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onStart() {
-        mProvider.onStart();
-    }
-
-    /**
      * Tell runtime that the application is on resuming. This can make runtime
      * be aware of application life cycle.
      */
@@ -123,14 +115,6 @@ public class XWalkRuntimeView extends FrameLayout {
     }
 
     /**
-     * Tell runtime that the application is on stoping. This can make runtime
-     * be aware of application life cycle.
-     */
-    public void onStop() {
-        mProvider.onStop();
-    }
-
-    /**
      * Tell runtime that the application is on destroying. This can make runtime
      * be aware of application life cycle.
      */
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.runtime;
+package org.xwalk.app.runtime;
 
 import android.app.Activity;
 import android.content.Context;
@@ -17,10 +17,8 @@ import android.view.View;
 interface XWalkRuntimeViewProvider {
     // For handling life cycle and activity result.
     public void onCreate();
-    public void onStart();
     public void onResume();
     public void onPause();
-    public void onStop();
     public void onDestroy();
     public void onActivityResult(int requestCode, int resultCode, Intent data);
     public boolean onNewIntent(Intent intent);
@@ -2,24 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.core.internal.extension;
+package org.xwalk.app.runtime.extension;
 
 import android.content.Context;
 import android.content.Intent;
 
-import org.chromium.base.CalledByNative;
-
-import org.xwalk.core.internal.extensions.XWalkExtensionAndroid;
-import org.xwalk.core.internal.extension.XWalkExtension;
+import org.xwalk.core.XWalkExtension;
 
 /**
  * The extension bridge for the implementation based on xwalk core.
  */
-class XWalkCoreExtensionBridge extends XWalkExtensionAndroid implements XWalkExtensionBridge {
-    private XWalkExtension mExtension;
+class XWalkCoreExtensionBridge extends XWalkExtension implements XWalkRuntimeExtensionBridge {
+    private XWalkExtensionClient mExtension;
 
-    public XWalkCoreExtensionBridge(XWalkExtension extension) {
-        super(extension.getExtensionName(), extension.getJsApi(), extension.getEntryPoints());
+    public XWalkCoreExtensionBridge(XWalkExtensionClient extension) {
+        super(extension.getExtensionName(), extension.getJsApi(), null);
         mExtension = extension;
     }
 
@@ -36,7 +33,6 @@ class XWalkCoreExtensionBridge extends XWalkExtensionAndroid implements XWalkExt
 
     public void onDestroy() {
         mExtension.onDestroy();
-        destroyExtension();
     }
 
     public void onResume() {
index 3db50e3..81fc95e 100644 (file)
@@ -4,17 +4,8 @@
 
 package org.xwalk.app.runtime.extension;
 
-import android.app.Activity;
-import android.content.Context;
 import android.content.Intent;
 
-import java.lang.reflect.Method;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.xwalk.app.runtime.CrossPackageWrapper;
-
 /**
  * This class is to encapsulate the reflection detail of
  * invoking XWalkExtension class in the shared library APK.
@@ -23,41 +14,45 @@ import org.xwalk.app.runtime.CrossPackageWrapper;
  * below methods. It's created and registered by runtime side via the
  * configuration information in extensions-config.json.
  */
-public class XWalkExtensionClient extends CrossPackageWrapper {
+public class XWalkExtensionClient {
+    // The unique name for this extension.
+    protected String mName;
 
-    private final static String EXTENSION_CLASS_NAME = "org.xwalk.core.internal.extension.XWalkExtensionClientImpl";
-    private Object mInstance;
-    private Method mGetExtensionName;
-    private Method mGetJsApi;
-    private Method mPostMessage;
-    private Method mBroadcastMessage;
+    // The JavaScript code stub. Will be injected to JS engine.
+    protected String mJsApi;
 
-    protected XWalkExtensionContextClient mContext;
+    // The context used by extensions.
+    protected XWalkExtensionContextClient mExtensionContext;
 
+    /**
+     * Constructor with the information of an extension.
+     * @param name the extension name.
+     * @param apiVersion the version of API.
+     * @param jsApi the code stub of JavaScript for this extension.
+     * @param context the extension context.
+     */
     public XWalkExtensionClient(String name, String jsApi, XWalkExtensionContextClient context) {
-        super(context.getActivity(), EXTENSION_CLASS_NAME, null /* ExceptionHalder */, String.class, String.class,
-                context.getInstance().getClass(), Object.class);
-        mContext = context;
-        mInstance = this.createInstance(name, jsApi, context.getInstance(), this);
-
-        mGetExtensionName = lookupMethod("getExtensionName");
-        mGetJsApi = lookupMethod("getJsApi");
-        mPostMessage = lookupMethod("postMessage", int.class, String.class);
-        mBroadcastMessage = lookupMethod("broadcastMessage", String.class);
+        assert (context != null);
+        mName = name;
+        mJsApi = jsApi;
+        mExtensionContext = context;
+        mExtensionContext.registerExtension(this);
     }
 
     /**
-     * Get the extension name which is set when it's created.
+     * Get the unique name of extension.
+     * @return the name of extension set from constructor.
      */
     public final String getExtensionName() {
-        return (String)invokeMethod(mGetExtensionName, mInstance);
+        return mName;
     }
 
     /**
-     * Get the JavaScript stub code which is set when it's created.
+     * Get the JavaScript code stub.
+     * @return the JavaScript code stub.
      */
     public final String getJsApi() {
-        return (String)invokeMethod(mGetJsApi, mInstance);
+        return mJsApi;
     }
 
     /**
@@ -118,15 +113,16 @@ public class XWalkExtensionClient extends CrossPackageWrapper {
         return "";
     }
 
+
     /**
      * Post messages to JavaScript via extension's context.
      * It's used by child classes to post message from Java side
      * to JavaScript side.
-     * @param extensionInstanceID the ID of extension instance where the message came from.
+     * @param instanceID the ID of target extension instance.
      * @param message the message to be passed to Javascript.
      */
-    public final void postMessage(int extensionInstanceID, String message) {
-        invokeMethod(mPostMessage, mInstance, extensionInstanceID, message);
+    public final void postMessage(int instanceID, String message) {
+        mExtensionContext.postMessage(this, instanceID, message);
     }
 
     /**
@@ -136,6 +132,6 @@ public class XWalkExtensionClient extends CrossPackageWrapper {
      * @param message the message to be passed to Javascript.
      */
     public final void broadcastMessage(String message) {
-        invokeMethod(mBroadcastMessage, mInstance, message);
+        mExtensionContext.broadcastMessage(this, message);
     }
 }
index 720398c..13ba291 100644 (file)
@@ -6,61 +6,51 @@ package org.xwalk.app.runtime.extension;
 
 import android.app.Activity;
 import android.content.Context;
-import android.content.Intent;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import java.lang.reflect.Method;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.xwalk.app.runtime.CrossPackageWrapper;
 
 /**
- * This is the extension context used by external extensions. It'll be created
- * by runtime side.
+ * Interface for extension context
+ *
+ * It is responsible for maintaining all xwalk extensions and providing a way to
+ * post message to JavaScript side for each xwalk extension.
  */
-public final class XWalkExtensionContextClient extends CrossPackageWrapper {
-    private final static String EXTENSION_CLASS_NAME =
-            "org.xwalk.core.internal.extension.XWalkExtensionContextWrapper";
-    private Object mInstance;
-    private Method mGetContext;
-    private Method mGetActivity;
+public interface XWalkExtensionContextClient {
+    /**
+     * Register an xwalk extension into context.
+     */
+    public void registerExtension(XWalkExtensionClient extension);
 
     /**
-     * It's called by runtime side.
+     * Unregister an xwalk extension with the given unique name from context.
      */
-    public XWalkExtensionContextClient(Activity activity, Object instance) {
-        super(activity, EXTENSION_CLASS_NAME, null, String.class, String.class,
-                instance.getClass());
+    public void unregisterExtension(String name);
 
-        mInstance = instance;
-        mGetActivity = lookupMethod("getActivity");
-        mGetContext = lookupMethod("getContext");
-    }
+    /**
+     * Post a message to the given extension instance.
+     *
+     * @param extension The xwalk extension
+     * @param instanceId The unique id to identify the extension instance as the
+     *                   message destination.
+     * @param message The message content to be posted.
+     */
+    public void postMessage(XWalkExtensionClient extension, int instanceId, String message);
 
     /**
-     * Get the current Android Activity. Used by XWalkExtensionClient.
-     * @return the current Android Activity.
+     * Broadcast a message to all extension instances.
+     *
+     * @param extension The xwalk extension
+     * @param message The message content to be broadcasted.
      */
-    public Activity getActivity() {
-        return (Activity) invokeMethod(mGetActivity, mInstance);
-    }
+    public void broadcastMessage(XWalkExtensionClient extension, String message);
 
     /**
-     * Get the current Android Context. Used by XWalkExtensionClient.
+     * Get current Android Context.
      * @return the current Android Context.
      */
-    public Context getContext() {
-        return (Context) invokeMethod(mGetContext, mInstance);
-    }
+    public Context getContext();
 
     /**
-     * Get the object of the runtime side.
-     * @return the object of the runtime side.
+     * Get the current Android Activity.
+     * @return the current Android Activity.
      */
-    public Object getInstance() {
-        return mInstance;
-    }
+    public Activity getActivity();
 }
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.core.internal.extension;
+package org.xwalk.app.runtime.extension;
 
 import android.content.Intent;
 
 /**
  * Interface for bridging XWalkExtension functionalities to its backend implementation.
  */
-interface XWalkExtensionBridge {
+interface XWalkRuntimeExtensionBridge {
     /**
      * Post a message from native to a specific receiver on JavaScript side.
      *
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.core.internal.extension;
+package org.xwalk.app.runtime.extension;
 
 /**
  * A factory used to create the extension bridge.
  */
-final class XWalkExtensionBridgeFactory {
+final class XWalkRuntimeExtensionBridgeFactory {
     /**
      * Return a XWalkExtensionBridge instance for the given extension.
      */
-    public static XWalkExtensionBridge createInstance(XWalkExtension extension) {
+    public static XWalkRuntimeExtensionBridge createInstance(XWalkExtensionClient extension) {
         return new XWalkCoreExtensionBridge(extension);
     }
 }
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.core.internal.extension;
+package org.xwalk.app.runtime.extension;
 
 import android.app.Activity;
 import android.content.Context;
@@ -23,49 +23,41 @@ import java.util.HashMap;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.xwalk.core.internal.extension.api.contacts.Contacts;
-import org.xwalk.core.internal.extension.api.device_capabilities.DeviceCapabilities;
-import org.xwalk.core.internal.extension.api.launchscreen.LaunchScreenExtension;
-import org.xwalk.core.internal.extension.api.messaging.Messaging;
-import org.xwalk.core.internal.extension.api.presentation.PresentationExtension;
 
 /**
  * This internal class acts a manager to manage extensions.
  */
-public class XWalkExtensionManager implements XWalkExtensionContext {
+public class XWalkRuntimeExtensionManager implements XWalkExtensionContextClient {
     private final static String TAG = "XWalkExtensionManager";
     private final static String EXTENSION_CONFIG_FILE = "extensions-config.json";
-    // This class name is from runtime client. Need to keep consistency with it.
-    private final static String EXTENSION_CONTEXT_CLIENT_CLASS_NAME =
-            "org.xwalk.app.runtime.extension.XWalkExtensionContextClient";
 
     private final Context mContext;
     private final Activity mActivity;
 
-    private final HashMap<String, XWalkExtensionBridge> mExtensions = new HashMap<String, XWalkExtensionBridge>();
+    private final HashMap<String, XWalkRuntimeExtensionBridge> mExtensions = new HashMap<String, XWalkRuntimeExtensionBridge>();
     // This variable is to set whether to load external extensions. The default is true.
     private boolean mLoadExternalExtensions;
 
-    public XWalkExtensionManager(Context context, Activity activity) {
+    public XWalkRuntimeExtensionManager(Context context, Activity activity) {
         mContext = context;
         mActivity = activity;
         mLoadExternalExtensions = true;
     }
 
     @Override
-    public void registerExtension(XWalkExtension extension) {
+    public void registerExtension(XWalkExtensionClient extension) {
         if (mExtensions.get(extension.getExtensionName()) != null) {
             Log.e(TAG, extension.getExtensionName() + "is already registered!");
             return;
         }
 
-        XWalkExtensionBridge bridge = XWalkExtensionBridgeFactory.createInstance(extension);
+        XWalkRuntimeExtensionBridge bridge = XWalkRuntimeExtensionBridgeFactory.createInstance(extension);
         mExtensions.put(extension.getExtensionName(), bridge);
     }
 
     @Override
     public void unregisterExtension(String name) {
-        XWalkExtensionBridge bridge = mExtensions.get(name);
+        XWalkRuntimeExtensionBridge bridge = mExtensions.get(name);
         if (bridge != null) {
             mExtensions.remove(name);
             bridge.onDestroy();
@@ -83,55 +75,54 @@ public class XWalkExtensionManager implements XWalkExtensionContext {
     }
 
     @Override
-    public void postMessage(XWalkExtension extension, int instanceID, String message) {
-        XWalkExtensionBridge bridge = mExtensions.get(extension.getExtensionName());
+    public void postMessage(XWalkExtensionClient extension, int instanceID, String message) {
+        XWalkRuntimeExtensionBridge bridge = mExtensions.get(extension.getExtensionName());
         if (bridge != null) bridge.postMessage(instanceID, message);
     }
 
-    public void broadcastMessage(XWalkExtension extension, String message) {
-        XWalkExtensionBridge bridge = mExtensions.get(extension.getExtensionName());
+    public void broadcastMessage(XWalkExtensionClient extension, String message) {
+        XWalkRuntimeExtensionBridge bridge = mExtensions.get(extension.getExtensionName());
         if (bridge != null) bridge.broadcastMessage(message);
     }
 
     public void onStart() {
-        for(XWalkExtensionBridge extension: mExtensions.values()) {
+        for(XWalkRuntimeExtensionBridge extension: mExtensions.values()) {
             extension.onStart();
         }
     }
 
     public void onResume() {
-        for(XWalkExtensionBridge extension: mExtensions.values()) {
+        for(XWalkRuntimeExtensionBridge extension: mExtensions.values()) {
             extension.onResume();
         }
     }
 
     public void onPause() {
-        for(XWalkExtensionBridge extension: mExtensions.values()) {
+        for(XWalkRuntimeExtensionBridge extension: mExtensions.values()) {
             extension.onPause();
         }
     }
 
     public void onStop() {
-        for(XWalkExtensionBridge extension: mExtensions.values()) {
+        for(XWalkRuntimeExtensionBridge extension: mExtensions.values()) {
             extension.onStop();
         }
     }
 
     public void onDestroy() {
-        for(XWalkExtensionBridge extension: mExtensions.values()) {
+        for(XWalkRuntimeExtensionBridge extension: mExtensions.values()) {
             extension.onDestroy();
         }
         mExtensions.clear();
     }
 
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        for(XWalkExtensionBridge extension: mExtensions.values()) {
+        for(XWalkRuntimeExtensionBridge extension: mExtensions.values()) {
             extension.onActivityResult(requestCode, resultCode, data);
         }
     }
 
     public void loadExtensions() {
-        loadInternalExtensions();
         loadExternalExtensions();
     }
 
@@ -139,73 +130,6 @@ public class XWalkExtensionManager implements XWalkExtensionContext {
         mLoadExternalExtensions = load;
     }
 
-    private void loadInternalExtensions() {
-        // Create all extension instances directly here. The internal extension will register
-        // itself and add itself to XWalkExtensionManager.mExtensions automatically.
-        // The following sample shows how to create an extension that named Device:
-        //    String jsApiContent = "";
-        //    try {
-        //        jsApiContent = getExtensionJSFileContent(mContext, Device.JS_API_PATH, true);
-        //        new Device(jsApiContent, mExtensionContextImpl);
-        //    } catch(IOException e) {
-        //        Log.w(TAG, "Failed to read js API file of internal extension: Device");
-        //    }
-        {
-            String jsApiContent = "";
-            try {
-                jsApiContent = getExtensionJSFileContent(
-                        mContext, PresentationExtension.JS_API_PATH, true);
-                new PresentationExtension(jsApiContent, this);
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to read JS API file: " + PresentationExtension.JS_API_PATH);
-            }
-        }
-
-        {
-            String jsApiContent = "";
-            try {
-                jsApiContent = getExtensionJSFileContent(
-                        mContext, LaunchScreenExtension.JS_API_PATH, true);
-                new LaunchScreenExtension(jsApiContent, this);
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to read JS API file: " + LaunchScreenExtension.JS_API_PATH);
-            }
-        }
-
-        {
-            String jsApiContent = "";
-            try {
-                jsApiContent = getExtensionJSFileContent(
-                        mContext, Contacts.JS_API_PATH, true);
-                new Contacts(jsApiContent, this);
-            } catch(IOException e) {
-                Log.w(TAG, "Failed to read JS API file: " + Contacts.JS_API_PATH);
-            }
-        }
-
-        {
-            String jsApiContent = "";
-            try {
-                jsApiContent = getExtensionJSFileContent(
-                        mContext, DeviceCapabilities.JS_API_PATH, true);
-                new DeviceCapabilities(jsApiContent, this);
-            } catch(IOException e) {
-                Log.w(TAG, "Failed to read JS API file: " + DeviceCapabilities.JS_API_PATH);
-            }
-        }
-
-        {
-            String jsApiContent = "";
-            try {
-                jsApiContent = getExtensionJSFileContent(
-                        mContext, Messaging.JS_API_PATH, true);
-                new Messaging(jsApiContent, this);
-            } catch(IOException e) {
-                Log.w(TAG, "Failed to read JS API file: " + Messaging.JS_API_PATH);
-            }
-        }
-    }
-
     private void loadExternalExtensions() {
         if (!mLoadExternalExtensions) return;
 
@@ -218,11 +142,6 @@ public class XWalkExtensionManager implements XWalkExtensionContext {
             return;
         }
 
-        // Initialize the context for external extensions.
-        XWalkExtensionContextWrapper contextWrapper =
-                new XWalkExtensionContextWrapper(this);
-        Object contextClient = createExtensionContextClient(contextWrapper);
-
         try {
             JSONArray jsonFeatures = new JSONArray(configFileContent);
             int extensionCount = jsonFeatures.length();
@@ -242,7 +161,7 @@ public class XWalkExtensionManager implements XWalkExtensionContext {
                 }
 
                 if (name != null && className != null && jsApi != null) {
-                    createExternalExtension(name, className, jsApi, contextClient, contextWrapper);
+                    createExternalExtension(name, className, jsApi, this);
                 }
             }
         } catch (JSONException e) {
@@ -286,34 +205,14 @@ public class XWalkExtensionManager implements XWalkExtensionContext {
         return result;
     }
 
-    private Object createExtensionContextClient(XWalkExtensionContextWrapper contextWrapper) {
-        Activity activity = contextWrapper.getActivity();
-        try {
-            Class<?> clazz = activity.getClassLoader().loadClass(EXTENSION_CONTEXT_CLIENT_CLASS_NAME);
-            Constructor<?> constructor = clazz.getConstructor(Activity.class, Object.class);
-            return constructor.newInstance(activity, contextWrapper);
-        } catch (ClassNotFoundException e) {
-            handleException(e);
-        } catch (IllegalAccessException e) {
-            handleException(e);
-        } catch (InstantiationException e) {
-            handleException(e);
-        } catch (InvocationTargetException e) {
-            handleException(e);
-        } catch (NoSuchMethodException e) {
-            handleException(e);
-        }
-        return null;
-    }
-
     private void createExternalExtension(String name, String className, String jsApi,
-            Object contextClient, XWalkExtensionContextWrapper contextWrapper) {
-        Activity activity = contextWrapper.getActivity();
+            XWalkExtensionContextClient extensionContext) {
+        Activity activity = extensionContext.getActivity();
         try {
             Class<?> clazz = activity.getClassLoader().loadClass(className);
             Constructor<?> constructor = clazz.getConstructor(String.class,
-                    String.class, contextClient.getClass());
-            constructor.newInstance(name, jsApi, contextClient);
+                    String.class, XWalkExtensionContextClient.class);
+            constructor.newInstance(name, jsApi, this);
         } catch (ClassNotFoundException e) {
             handleException(e);
         } catch (IllegalAccessException e) {
index 43f4dd7..2bf677a 100644 (file)
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.xwalk.runtime.client.embedded.shell">
 
-    <application android:name="android.app.Application"
+    <application android:name="org.xwalk.core.XWalkApplication"
         android:label="XWalkRuntimeClientEmbeddedShell" android:hardwareAccelerated="true">
         <activity android:name="org.xwalk.runtime.client.embedded.shell.XWalkRuntimeClientEmbeddedShellActivity"
             android:theme="@android:style/Theme.Holo.Light.NoActionBar"
index 75a8cc0..c0a7c03 100644 (file)
@@ -124,10 +124,10 @@ public class XWalkRuntimeClientEmbeddedShellActivity extends XWalkRuntimeActivit
 
     @Override
     protected void didTryLoadRuntimeView(View runtimeView) {
-        if (getRuntimeView().get() != null) {
+        if (runtimeView != null) {
             setContentView(R.layout.testshell_activity);
             LinearLayout container = (LinearLayout) findViewById(R.id.content_container);
-            container.addView(getRuntimeView().get(),
+            container.addView(runtimeView,
                               LayoutParams.MATCH_PARENT,
                               LayoutParams.MATCH_PARENT);
             initializeUrlField();
index ad4acff..0a8f874 100644 (file)
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.xwalk.runtime.client.shell">
 
-    <application android:name="org.xwalk.app.runtime.XWalkRuntimeApplication"
+    <application android:name="org.xwalk.core.XWalkApplication"
         android:label="XWalkRuntimeClientShell" android:hardwareAccelerated="true">
         <activity android:name="org.xwalk.runtime.client.shell.XWalkRuntimeClientShellActivity"
             android:theme="@android:style/Theme.Holo.Light.NoActionBar"
index cd9d45d..6e33e54 100644 (file)
@@ -77,10 +77,10 @@ public class XWalkRuntimeClientShellActivity extends XWalkRuntimeActivityBase {
 
     @Override
     protected void didTryLoadRuntimeView(View runtimeView) {
-        if (getRuntimeView().get() != null) {
+        if (runtimeView != null) {
             setContentView(R.layout.testshell_activity);
             LinearLayout container = (LinearLayout) findViewById(R.id.content_container);
-            container.addView(getRuntimeView().get(),
+            container.addView(runtimeView,
                               LayoutParams.MATCH_PARENT,
                               LayoutParams.MATCH_PARENT);
             initializeUrlField();
index ca02af9..84b5fe6 100755 (executable)
@@ -14,6 +14,10 @@ import shutil
 import stat
 import sys
 
+# get xwalk absolute path so we can run this script from any location
+xwalk_dir = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(xwalk_dir)
+
 from app_info import AppInfo
 from customize_launch_screen import CustomizeLaunchScreen
 from handle_xml import AddElementAttribute
@@ -23,6 +27,7 @@ from handle_xml import EditElementValueByNodeName
 from handle_permissions import HandlePermissions
 from xml.dom import minidom
 
+TEMPLATE_DIR_NAME = 'template'
 
 def VerifyPackageName(value):
   regex = r'^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$'
@@ -107,31 +112,50 @@ def CompressSourceFiles(app_root, compressor):
 
 
 def Prepare(app_info, compressor):
-  name = app_info.android_name
-  package = app_info.package
+  """Copy the Android template project to a new app project
+     named app_info.app_name
+  """
+  # create new app_dir in xwalk_dir
+  app_name = app_info.android_name
+  app_dir = os.path.join(xwalk_dir, app_name)
+  app_package = app_info.package
   app_root = app_info.app_root
-  if os.path.exists(name):
-    shutil.rmtree(name)
-  shutil.copytree('template', name)
-  shutil.rmtree(os.path.join(name, 'src'))
-  src_root = os.path.join('template', 'src', 'org', 'xwalk', 'app', 'template')
-  src_activity = os.path.join(src_root, 'AppTemplateActivity.java')
-  if not os.path.isfile(src_activity):
-    print ('Please make sure that the java file'
-           ' of activity does exist.')
+  template_app_dir = os.path.join(xwalk_dir, TEMPLATE_DIR_NAME)
+
+  # 1) copy template project to app_dir
+  if os.path.exists(app_dir):
+    shutil.rmtree(app_dir)
+  shutil.copytree(template_app_dir, app_dir)
+
+  # 2) replace app_dir 'src' dir with template 'src' dir
+  shutil.rmtree(os.path.join(app_dir, 'src'))
+  template_src_root = os.path.join(template_app_dir, 'src', 'org', 'xwalk',
+                                   'app', 'template')
+
+  # 3) Create directory tree from app package (org.xyz.foo -> src/org/xyz/foo)
+  #    and copy AppTemplateActivity.java to <app_name>Activity.java 
+  template_activity_file = os.path.join(template_src_root,
+                                        'AppTemplateActivity.java')
+  if not os.path.isfile(template_activity_file):
+    print ('Error: The template file %s was not found. '
+           'Please make sure this file exists.' % template_activity_file)
     sys.exit(7)
-  root_path = os.path.join(name, 'src', package.replace('.', os.path.sep))
-  if not os.path.exists(root_path):
-    os.makedirs(root_path)
-  dest_activity = name + 'Activity.java'
-  shutil.copyfile(src_activity, os.path.join(root_path, dest_activity))
+  app_pkg_dir = os.path.join(app_dir, 'src',
+                             app_package.replace('.', os.path.sep))
+  if not os.path.exists(app_pkg_dir):
+    os.makedirs(app_pkg_dir)
+  app_activity_file = app_name + 'Activity.java'
+  shutil.copyfile(template_activity_file,
+                  os.path.join(app_pkg_dir, app_activity_file))
+
+  # 4) Copy all HTML source from app_root to app_dir
   if app_root:
-    assets_path = os.path.join(name, 'assets', 'www')
-    if os.path.isdir(assets_path):
-      shutil.rmtree(assets_path)
-    shutil.copytree(app_root, assets_path)
+    app_assets_dir = os.path.join(app_dir, 'assets', 'www')
+    if os.path.isdir(app_assets_dir):
+      shutil.rmtree(app_assets_dir)
+    shutil.copytree(app_root, app_assets_dir)
     if compressor:
-      CompressSourceFiles(assets_path, compressor)
+      CompressSourceFiles(app_assets_dir, compressor)
 
 
 def EncodingUnicodeValue(value):
@@ -144,7 +168,7 @@ def EncodingUnicodeValue(value):
 
 
 def CustomizeStringXML(name, description):
-  strings_path = os.path.join(name, 'res', 'values', 'strings.xml')
+  strings_path = os.path.join(xwalk_dir, name, 'res', 'values', 'strings.xml')
   if not os.path.isfile(strings_path):
     print ('Please make sure strings_xml'
            ' exists under template folder.')
@@ -161,7 +185,7 @@ def CustomizeStringXML(name, description):
 
 
 def CustomizeThemeXML(name, fullscreen, manifest):
-  theme_path = os.path.join(name, 'res', 'values-v14', 'theme.xml')
+  theme_path = os.path.join(xwalk_dir, name, 'res', 'values-v14', 'theme.xml')
   if not os.path.isfile(theme_path):
     print('Error: theme.xml is missing in the build tool.')
     sys.exit(6)
@@ -195,7 +219,7 @@ def CustomizeXML(app_info, description, icon_dict, manifest, permissions):
   # append a space before '@' or '?' to fix that.
   if app_name.startswith('@') or app_name.startswith('?'):
     app_name = ' ' + app_name
-  manifest_path = os.path.join(name, 'AndroidManifest.xml')
+  manifest_path = os.path.join(xwalk_dir, name, 'AndroidManifest.xml')
   if not os.path.isfile(manifest_path):
     print ('Please make sure AndroidManifest.xml'
            ' exists under template folder.')
@@ -227,7 +251,7 @@ def CustomizeXML(app_info, description, icon_dict, manifest, permissions):
     EditElementAttribute(xmldoc, 'application', 'android:icon',
                          '@drawable/%s' % icon_name)
 
-  file_handle = open(os.path.join(name, 'AndroidManifest.xml'), 'w')
+  file_handle = open(os.path.join(xwalk_dir, name, 'AndroidManifest.xml'), 'w')
   xmldoc.writexml(file_handle, encoding='utf-8')
   file_handle.close()
 
@@ -258,11 +282,12 @@ def SetVariable(file_path, string_line, variable, value):
 def CustomizeJava(app_info, app_url, app_local_path, keep_screen_on):
   name = app_info.android_name
   package = app_info.package
-  root_path = os.path.join(name, 'src', package.replace('.', os.path.sep))
-  dest_activity = os.path.join(root_path, name + 'Activity.java')
+  app_pkg_dir = os.path.join(xwalk_dir, name, 'src',
+                             package.replace('.', os.path.sep))
+  dest_activity = os.path.join(app_pkg_dir, name + 'Activity.java')
   ReplaceString(dest_activity, 'org.xwalk.app.template', package)
   ReplaceString(dest_activity, 'AppTemplate', name)
-  manifest_file = os.path.join(name, 'assets/www', 'manifest.json')
+  manifest_file = os.path.join(xwalk_dir, name, 'assets/www', 'manifest.json')
   if os.path.isfile(manifest_file):
     ReplaceString(
         dest_activity,
@@ -274,7 +299,8 @@ def CustomizeJava(app_info, app_url, app_local_path, keep_screen_on):
         ReplaceString(dest_activity, 'file:///android_asset/www/index.html',
                       app_url)
     elif app_local_path:
-      if os.path.isfile(os.path.join(name, 'assets/www', app_local_path)):
+      if os.path.isfile(os.path.join(xwalk_dir, name, 'assets/www',
+                                     app_local_path)):
         ReplaceString(dest_activity, 'file:///android_asset/www/index.html',
                       'app://' + package + '/' + app_local_path)
       else:
@@ -338,7 +364,7 @@ def CustomizeExtensions(app_info, extensions):
   if not extensions:
     return
   name = app_info.android_name
-  apk_path = name
+  apk_path = os.path.join(xwalk_dir, name)
   apk_assets_path = os.path.join(apk_path, 'assets')
   extensions_string = 'xwalk-extensions'
 
@@ -390,7 +416,7 @@ def CustomizeExtensions(app_info, extensions):
       json_output['jsapi'] = js_path_prefix + json_output['jsapi']
       extension_json_list.append(json_output)
       # Merge the permissions of extensions into AndroidManifest.xml.
-      manifest_path = os.path.join(name, 'AndroidManifest.xml')
+      manifest_path = os.path.join(xwalk_dir, name, 'AndroidManifest.xml')
       xmldoc = minidom.parse(manifest_path)
       if ('permissions' in json_output):
         # Get used permission list to avoid repetition as "--permissions"
@@ -423,7 +449,7 @@ def CustomizeExtensions(app_info, extensions):
 def GenerateCommandLineFile(app_info, xwalk_command_line):
   if xwalk_command_line == '':
     return
-  assets_path = os.path.join(app_info.android_name, 'assets')
+  assets_path = os.path.join(xwalk_dir, app_info.android_name, 'assets')
   file_path = os.path.join(assets_path, 'xwalk-command-line')
   command_line_file = open(file_path, 'w')
   command_line_file.write('xwalk ' + xwalk_command_line)
@@ -447,7 +473,7 @@ def CustomizeIconByDict(name, app_root, icon_dict):
     for kd, vd in drawable_dict.items():
       for item in icon_list:
         if item[0] >= vd[0] and item[0] < vd[1]:
-          drawable_path = os.path.join(name, 'res', 'drawable-' + kd)
+          drawable_path = os.path.join(xwalk_dir, name, 'res', 'drawable-' + kd)
           if not os.path.exists(drawable_path):
             os.makedirs(drawable_path)
           icon = os.path.join(app_root, item[1])
@@ -466,7 +492,7 @@ def CustomizeIconByDict(name, app_root, icon_dict):
 
 def CustomizeIconByOption(name, icon):
   if os.path.isfile(icon):
-    drawable_path = os.path.join(name, 'res', 'drawable')
+    drawable_path = os.path.join(xwalk_dir, name, 'res', 'drawable')
     if not os.path.exists(drawable_path):
       os.makedirs(drawable_path)
     icon_file = os.path.basename(icon)
@@ -573,7 +599,7 @@ def main():
     if options.name is not None:
       app_info.android_name = options.name
     if options.app_root is None:
-      app_info.app_root = os.path.join('test_data', 'manifest')
+      app_info.app_root = os.path.join(xwalk_dir, 'test_data', 'manifest')
     else:
       app_info.app_root = options.app_root
     if options.package is not None:
index a2415db..719d02f 100755 (executable)
@@ -8,6 +8,7 @@ import os
 import shutil
 import sys
 
+xwalk_dir = os.path.dirname(os.path.abspath(__file__))
 
 def CopyToPathWithName(root, name, final_path, rename):
   if name == '':
@@ -29,7 +30,7 @@ def CopyToPathWithName(root, name, final_path, rename):
 
 
 def CopyDrawables(image_dict, orientation, sanitized_name, name, app_root):
-  drawable = os.path.join(sanitized_name, 'res', 'drawable')
+  drawable = os.path.join(xwalk_dir, sanitized_name, 'res', 'drawable')
   if orientation == 'landscape':
     drawable = drawable + '-land'
   elif orientation == 'portrait':
@@ -113,7 +114,7 @@ def CustomizeBackground(background_color,
                         orientation,
                         sanitized_name,
                         app_root):
-  background_path = os.path.join(sanitized_name, 'res',
+  background_path = os.path.join(xwalk_dir, sanitized_name, 'res',
                                  'drawable', 'launchscreen_bg.xml')
   if not os.path.isfile(background_path):
     print('Error: launchscreen_bg.xml is missing in the build tool.')
diff --git a/src/xwalk/app/tools/android/extension_manager.py b/src/xwalk/app/tools/android/extension_manager.py
new file mode 100755 (executable)
index 0000000..efa54e1
--- /dev/null
@@ -0,0 +1,222 @@
+#!/usr/bin/env python
+
+# 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.
+# pylint: disable=F0401
+
+import fnmatch
+import json
+import optparse
+import os
+import sys
+
+from util import CleanDir, RunCommand, GetVersion
+
+
+"""
+* Fodler structure for extension.
+1. 1 extension of 1 repo.
+.
+|-- all.gyp     #optional. If your extension is built from source.
+|                          You have to provide this file.
+|-- build.json  #required. Tell make_apk.json where to find extension.
+|-- <other files and dirs>
+
+2. multiple extesnions of 1 repo
+.
+|-- all.gyp
+|-- <extension>
+    |-- build.json
+    |-- <other files and dirs>
+
+* Format of build.json
+Example:
+{
+  "binary_path":"../out/Default/gen/iap"
+}
+The base dir of "binary_path" is the path of extension.
+"""
+
+
+def GetExtensionList(extensions_path):
+  if not os.path.isdir(extensions_path):
+    return []
+
+  extension_list = []
+  for item in os.listdir(extensions_path):
+    sub_path = os.path.join(extensions_path, item)
+    if not os.path.isdir(sub_path):
+      continue
+    if os.path.isfile(os.path.join(sub_path, "build.json")):
+      extension_list.append(item)
+    else:
+      for sub_item in os.listdir(sub_path):
+        if os.path.isfile(
+            os.path.join(sub_path, sub_item, "build.json")):
+          extension_list.append(os.path.join(item, sub_item))
+
+  return extension_list
+
+
+def EnableExtension(extension_name, extensions_path, is_enable):
+  extension_list = GetExtensionList(extensions_path)
+  filtered_extensions = fnmatch.filter(extension_list, extension_name)
+  for item in filtered_extensions:
+    build_json_path = os.path.join(extensions_path, item, "build.json")
+    with open(build_json_path, "r") as fd:
+      data = json.load(fd)
+      data["enable"] = is_enable
+    with open(build_json_path, "w") as fd:
+      fd.write(
+          json.dumps(data, sort_keys=True, indent=4, separators=(',', ': ')))
+
+
+def GetExtensionStatus(extension_name, extensions_path):
+  build_json_path = os.path.join(extensions_path, extension_name, "build.json")
+  with open(build_json_path, "r") as fd:
+    data = json.load(fd)
+  return data.get('enable', True)
+
+
+def BuildExtension(repo_path):
+  old_cwd = os.getcwd()
+  os.chdir(repo_path)
+  os.environ["GYP_GENERATORS"] = "ninja"
+  gyp_cmd = ["gyp", "--depth=.", "all.gyp"]
+  RunCommand(gyp_cmd, True)
+  #Currently, the output path is set to out/Default.
+  ninja_cmd = ["ninja", "-C", os.path.join("out", "Default")]
+  RunCommand(ninja_cmd, True)
+  os.chdir(old_cwd)
+
+
+def HandleAdd(git_url, extensions_path, name=None):
+  if name is None:
+    name = git_url.split('/')[-1].split('.')[0]
+  if not os.path.isdir(extensions_path):
+    if os.path.isfile(extensions_path):
+      print "WARNING: Please remove file %s" % (extensions_path)
+      sys.exit(1)
+    else:
+      os.mkdir(extensions_path)
+  local_extension_path = os.path.join(extensions_path, name)
+  if os.path.exists(local_extension_path):
+    print "ERROR: You already have a repo named \"%s\"." % name
+    return 
+  os.mkdir(local_extension_path)
+  #Only support git.
+  git_cmd = ["git", "clone", git_url, local_extension_path]
+  RunCommand(git_cmd, True)
+  if os.path.isfile(os.path.join(local_extension_path, "all.gyp")):
+    BuildExtension(local_extension_path)
+
+
+def HandleRemove(remove_name, extensions_path):
+  extension_path = os.path.join(extensions_path, remove_name)
+  if os.path.exists(extension_path):
+    CleanDir(extension_path)
+  else:
+    print "ERROR: Don't have extension \"%s\"" % (remove_name)
+
+
+def PrintExtensionInfo(extension_name, extensions_path):
+  print "{0} {1}".format(
+      "+" if GetExtensionStatus(extension_name, extensions_path) else "-",
+      extension_name)
+
+
+def HandleList(extensions_path):
+  extension_list = GetExtensionList(extensions_path)
+  print
+  for extension_name in extension_list:
+    PrintExtensionInfo(extension_name, extensions_path)
+  print
+
+
+def HandleSearch(key, extensions_path):
+  extension_list = GetExtensionList(extensions_path)
+  filtered_extensions = fnmatch.filter(extension_list, key)
+  print
+  for extension_name in filtered_extensions:
+    PrintExtensionInfo(extension_name, extensions_path)
+  print
+
+
+def HandleEnable(extension_name, extension_path):
+  EnableExtension(extension_name, extension_path, True)
+
+
+def HandleDisable(extension_name, extension_path):
+  EnableExtension(extension_name, extension_path, False)
+
+
+def HandleVersion():
+  version_path = \
+      os.path.join(os.path.dirname(os.path.realpath(__file__)), "VERSION")
+  if os.path.isfile(version_path):
+    print(GetVersion("VERSION"))
+  else:
+    print ("ERROR: VERSION was not found, so Crosswalk\'s version could not"
+           "be determined.")
+
+
+def main(argv):
+  parser = optparse.OptionParser()
+  parser.add_option("--add", action="store",
+                    type="string", dest="git_url",
+                    metavar="URL",
+                    help="Add an extension")
+  parser.add_option("--enable", action="store",
+                    type="string", dest="enable",
+                    metavar="NAME",
+                    help="Enabled extension list")
+  parser.add_option("--disable", action="store",
+                    type="string", dest="disable",
+                    metavar="NAME",
+                    help="Disabled extension list")
+  parser.add_option("--name", action="store",
+                    type="string", dest="name",
+                    metavar="NAME",
+                    help="Extension name in local path. "
+                         "Work with --add option.")
+  parser.add_option("--remove", action="store",
+                    type="string", dest="remove_name",
+                    metavar="NAME",
+                    help="Remove an extension")
+  parser.add_option("-l", "--list", action="store_true",
+                    dest="list_extensions", default=False,
+                    help="List all extensions")
+  parser.add_option("--search", action="store",
+                    type="string", dest="search_key",
+                    metavar="KEYWORD",
+                    help="List all extensions")
+  parser.add_option("-v", "--version", action="store_true",
+                    dest="version", default=False,
+                    help="The version of this python tool.")
+
+  options, _ = parser.parse_args()
+  if len(argv) == 1:
+    parser.print_help()
+    return 0
+  
+  extensions_path = os.path.join(os.getcwd(), "extensions")
+
+  if options.git_url:
+    HandleAdd(options.git_url, extensions_path, options.name)
+  elif options.enable:
+    HandleEnable(options.enable, extensions_path)
+  elif options.disable:
+    HandleDisable(options.disable, extensions_path)
+  elif options.remove_name:
+    HandleRemove(options.remove_name, extensions_path)
+  elif options.list_extensions:
+    HandleList(extensions_path)
+  elif options.search_key:
+    HandleSearch(options.search_key, extensions_path)
+  elif options.version:
+    HandleVersion()
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
index 371f8e8..975c502 100755 (executable)
@@ -5,6 +5,7 @@
 # found in the LICENSE file.
 # pylint: disable=F0401
 
+import json
 import optparse
 import os
 import re
@@ -12,10 +13,16 @@ import shutil
 import subprocess
 import sys
 
+# get xwalk absolute path so we can run this script from any location
+xwalk_dir = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(xwalk_dir)
+
 from app_info import AppInfo
 from customize import VerifyPackageName, CustomizeAll, \
                       ParseParameterForCompressor
+from extension_manager import GetExtensionList, GetExtensionStatus
 from handle_permissions import permission_mapping_table
+from util import AllArchitectures, CleanDir, GetVersion, RunCommand
 from manifest_json_parser import HandlePermissionList
 from manifest_json_parser import ManifestJsonParser
 
@@ -23,15 +30,6 @@ from manifest_json_parser import ManifestJsonParser
 NATIVE_LIBRARY = 'libxwalkcore.so'
 
 
-def CleanDir(path):
-  if os.path.exists(path):
-    shutil.rmtree(path)
-
-
-def AllArchitectures():
-  return ("x86", "arm")
-
-
 def ConvertArchNameToArchFolder(arch):
   arch_dict = {
       'x86': 'x86',
@@ -50,22 +48,6 @@ def AddExeExtensions(name):
   return result
 
 
-def RunCommand(command, verbose=False, shell=False):
-  """Runs the command list, print the output, and propagate its result."""
-  proc = subprocess.Popen(command, stdout=subprocess.PIPE,
-                          stderr=subprocess.STDOUT, shell=shell)
-  if not shell:
-    output = proc.communicate()[0]
-    result = proc.returncode
-    if verbose:
-      print(output.decode("utf-8").strip())
-    if result != 0:
-      print ('Command "%s" exited with non-zero exit code %d'
-             % (' '.join(command), result))
-      sys.exit(result)
-    return output.decode("utf-8")
-
-
 def Which(name):
   """Searches PATH for executable files with the given name, also taking
   PATHEXT into account. Returns the first existing match, or None if no matches
@@ -89,17 +71,6 @@ def GetAndroidApiLevel():
   return max(targets)
 
 
-def GetVersion(path):
-  """Get the version of this python tool."""
-  version_str = 'Crosswalk app packaging tool version is '
-  file_handle = open(path, 'r')
-  src_content = file_handle.read()
-  version_nums = re.findall(r'\d+', src_content)
-  version_str += ('.').join(version_nums)
-  file_handle.close()
-  return version_str
-
-
 def ContainsNativeLibrary(path):
   return os.path.isfile(os.path.join(path, NATIVE_LIBRARY))
 
@@ -136,7 +107,7 @@ def ParseManifest(options):
 
 
 def ParseXPK(options, out_dir):
-  cmd = ['python', 'parse_xpk.py',
+  cmd = ['python', os.path.join (xwalk_dir, 'parse_xpk.py'),
          '--file=%s' % os.path.expanduser(options.xpk),
          '--out=%s' % out_dir]
   RunCommand(cmd)
@@ -194,6 +165,33 @@ def MakeVersionCode(options):
   return '%s%s' % (abi, b.zfill(7))
 
 
+def GetExtensionBinaryPathList():
+  local_extension_list = []
+  extensions_path = os.path.join(os.getcwd(), "extensions")
+  exist_extension_list = GetExtensionList(extensions_path)
+  for item in exist_extension_list:
+    build_json_path = os.path.join(extensions_path, item, "build.json")
+    with open(build_json_path) as fd:
+      data = json.load(fd)
+    if not GetExtensionStatus(item, extensions_path):
+      continue
+    else:
+      if data.get("binary_path", False):
+        extension_binary_path = os.path.join(extensions_path,
+                                             item,
+                                             data["binary_path"])
+      else:
+        print "The extension \"%s\" doesn't exists." % item
+        sys.exit(1)
+    if os.path.isdir(extension_binary_path):
+      local_extension_list.append(extension_binary_path)
+    else:
+      print "The extension \"%s\" doesn't exists." % item
+      sys.exit(1)
+
+  return local_extension_list
+
+
 def Customize(options, app_info, manifest):
   app_info.package = options.package
   app_info.app_name = options.name
@@ -213,6 +211,21 @@ def Customize(options, app_info, manifest):
     app_info.orientation = options.orientation
   if options.icon:
     app_info.icon = '%s' % os.path.expanduser(options.icon)
+
+  #Add local extensions to extension list.
+  extension_binary_path_list = GetExtensionBinaryPathList()
+  if len(extension_binary_path_list) > 0:
+    if options.extensions is None:
+      options.extensions = "" 
+    else:
+      options.extensions += os.pathsep
+
+    for item in extension_binary_path_list:
+      options.extensions += item
+      options.extensions += os.pathsep
+    #trim final path separator
+    options.extensions = options.extensions[0:-1]
+
   CustomizeAll(app_info, options.description, options.icon_dict,
                options.permissions, options.app_url, options.app_local_path,
                options.keep_screen_on, options.extensions, manifest,
@@ -250,7 +263,7 @@ def Execution(options, name):
   else:
     print ('Use xwalk\'s keystore by default for debugging. '
            'Please switch to your keystore when distributing it to app market.')
-    key_store = 'xwalk-debug.keystore'
+    key_store = os.path.join(xwalk_dir, 'xwalk-debug.keystore')
     key_alias = 'xwalkdebugkey'
     key_code = 'xwalkdebug'
     key_alias_code = 'xwalkdebug'
@@ -265,26 +278,27 @@ def Execution(options, name):
 
   # Update android project for app and xwalk_core_library.
   update_project_cmd = ['android', 'update', 'project',
-                        '--path', name, '--target', target_string,
+                        '--path', os.path.join (xwalk_dir, name),
+                        '--target', target_string,
                         '--name', name]
   if options.mode == 'embedded':
     RunCommand(['android', 'update', 'lib-project',
-                '--path', os.path.join(name, 'xwalk_core_library'),
+                '--path', os.path.join(xwalk_dir, name, 'xwalk_core_library'),
                 '--target', target_string])
     update_project_cmd.extend(['-l', 'xwalk_core_library'])
   else:
     # Shared mode doesn't need xwalk_runtime_java.jar.
-    os.remove(os.path.join(name, 'libs', 'xwalk_runtime_java.jar'))
+    os.remove(os.path.join(xwalk_dir, name, 'libs', 'xwalk_runtime_java.jar'))
 
   RunCommand(update_project_cmd)
 
   # Check whether external extensions are included.
   extensions_string = 'xwalk-extensions'
-  extensions_dir = os.path.join(os.getcwd(), name, extensions_string)
+  extensions_dir = os.path.join(xwalk_dir, name, extensions_string)
   external_extension_jars = FindExtensionJars(extensions_dir)
   for external_extension_jar in external_extension_jars:
     shutil.copyfile(external_extension_jar,
-                    os.path.join(name, 'libs',
+                    os.path.join(xwalk_dir, name, 'libs',
                                  os.path.basename(external_extension_jar)))
 
   if options.mode == 'embedded':
@@ -296,12 +310,13 @@ def Execution(options, name):
     if not arch:
       print ('Invalid CPU arch: %s.' % arch)
       sys.exit(10)
-    library_lib_path = os.path.join(name, 'xwalk_core_library', 'libs')
+    library_lib_path = os.path.join(xwalk_dir, name, 'xwalk_core_library',
+                                    'libs')
     for dir_name in os.listdir(library_lib_path):
       lib_dir = os.path.join(library_lib_path, dir_name)
       if ContainsNativeLibrary(lib_dir):
         shutil.rmtree(lib_dir)
-    native_lib_path = os.path.join(name, 'native_libs', arch)
+    native_lib_path = os.path.join(xwalk_dir, name, 'native_libs', arch)
     if ContainsNativeLibrary(native_lib_path):
       shutil.copytree(native_lib_path, os.path.join(library_lib_path, arch))
     else:
@@ -309,7 +324,7 @@ def Execution(options, name):
             'embedded APK.' % arch)
       sys.exit(10)
 
-  ant_cmd = ['ant', 'release', '-f', os.path.join(name, 'build.xml')]
+  ant_cmd = ['ant', 'release', '-f', os.path.join(xwalk_dir, name, 'build.xml')]
   if not options.verbose:
     ant_cmd.extend(['-quiet'])
   ant_cmd.extend(['-Dkey.store="%s"' % os.path.abspath(key_store)])
@@ -324,7 +339,7 @@ def Execution(options, name):
           % (' '.join(ant_cmd), ant_result))
     sys.exit(ant_result)
 
-  src_file = os.path.join(name, 'bin', '%s-release.apk' % name)
+  src_file = os.path.join(xwalk_dir, name, 'bin', '%s-release.apk' % name)
   package_name = name
   if options.app_version:
     package_name += ('_' + options.app_version)
@@ -384,10 +399,11 @@ def MakeApk(options, app_info, manifest):
     # out.
     # When making apk for specified CPU arch, will only include the
     # corresponding native library by copying it back into xwalk_core_library.
-    target_library_path = os.path.join(name, 'xwalk_core_library')
-    shutil.copytree('xwalk_core_library', target_library_path)
+    target_library_path = os.path.join(xwalk_dir, name, 'xwalk_core_library')
+    shutil.copytree(os.path.join(xwalk_dir, 'xwalk_core_library'),
+                    target_library_path)
     library_lib_path = os.path.join(target_library_path, 'libs')
-    native_lib_path = os.path.join(name, 'native_libs')
+    native_lib_path = os.path.join(xwalk_dir, name, 'native_libs')
     os.makedirs(native_lib_path)
     available_archs = []
     for dir_name in os.listdir(library_lib_path):
@@ -558,7 +574,7 @@ def main(argv):
   xpk_temp_dir = ''
   if options.xpk:
     xpk_name = os.path.splitext(os.path.basename(options.xpk))[0]
-    xpk_temp_dir = xpk_name + '_xpk'
+    xpk_temp_dir = os.path.join(xwalk_dir, xpk_name + '_xpk')
     ParseXPK(options, xpk_temp_dir)
 
   if options.app_root and not options.manifest:
diff --git a/src/xwalk/app/tools/android/util.py b/src/xwalk/app/tools/android/util.py
new file mode 100644 (file)
index 0000000..ed90122
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+# 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.
+# pylint: disable=F0401
+
+
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+
+def CleanDir(path):
+  if os.path.exists(path):
+    shutil.rmtree(path)
+
+
+def AllArchitectures():
+  return ("x86", "arm")
+
+
+def RunCommand(command, verbose=False, shell=False):
+  """Runs the command list, print the output, and propagate its result."""
+  proc = subprocess.Popen(command, stdout=subprocess.PIPE,
+                          stderr=subprocess.STDOUT, shell=shell)
+  if not shell:
+    output = proc.communicate()[0]
+    result = proc.returncode
+    if verbose:
+      print(output.decode("utf-8").strip())
+    if result != 0:
+      print ('Command "%s" exited with non-zero exit code %d'
+             % (' '.join(command), result))
+      sys.exit(result)
+    return output.decode("utf-8")
+  else:
+    return None
+
+
+def GetVersion(path):
+  """Get the version of this python tool."""
+  version_str = 'Crosswalk app packaging tool version is '
+  file_handle = open(path, 'r')
+  src_content = file_handle.read()
+  version_nums = re.findall(r'\d+', src_content)
+  version_str += ('.').join(version_nums)
+  file_handle.close()
+  return version_str
index 29ea3ad..22eb39a 100644 (file)
 #include "xwalk/runtime/browser/runtime_context.h"
 #include "xwalk/runtime/browser/xwalk_runner.h"
 
+#if defined(OS_TIZEN)
+#include "xwalk/application/browser/application_tizen.h"
+#endif
+
 using content::RenderProcessHost;
 
 namespace xwalk {
@@ -70,22 +74,29 @@ GURL GetDefaultWidgetEntryPage(
 
 namespace application {
 
+scoped_ptr<Application> Application::Create(
+    scoped_refptr<ApplicationData> data,
+    RuntimeContext* context) {
+#if defined(OS_TIZEN)
+  return make_scoped_ptr<Application>(new ApplicationTizen(data, context));
+#else
+  return make_scoped_ptr(new Application(data, context));
+#endif
+}
+
 Application::Application(
     scoped_refptr<ApplicationData> data,
-    RuntimeContext* runtime_context,
-    Observer* observer)
+    RuntimeContext* runtime_context)
     : data_(data),
       render_process_host_(NULL),
       web_contents_(NULL),
       security_mode_enabled_(false),
       runtime_context_(runtime_context),
-      observer_(observer),
-      entry_point_used_(Default),
+      observer_(NULL),
       remote_debugging_enabled_(false),
       weak_factory_(this) {
   DCHECK(runtime_context_);
-  DCHECK(data_.get());
-  DCHECK(observer_);
+  DCHECK(data_);
 }
 
 Application::~Application() {
@@ -94,90 +105,55 @@ Application::~Application() {
     render_process_host_->RemoveObserver(this);
 }
 
-bool Application::Launch(const LaunchParams& launch_params) {
-  if (!runtimes_.empty()) {
-    LOG(ERROR) << "Attempt to launch app: " << id()
-               << " that was already launched.";
-    return false;
+template<>
+GURL Application::GetStartURL<Package::WGT>() {
+  GURL url = GetAbsoluteURLFromKey(widget_keys::kLaunchLocalPathKey);
+  if (!url.is_valid()) {
+    LOG(WARNING) << "Failed to find start URL from the 'config.xml'"
+                 << "trying to find default entry page.";
+    url = GetDefaultWidgetEntryPage(data_);
   }
 
-  CHECK(!render_process_host_);
-
-  GURL url = GetStartURL(launch_params, &entry_point_used_);
-  if (!url.is_valid())
-    return false;
-
-  remote_debugging_enabled_ = launch_params.remote_debugging;
-
-  Runtime* runtime = Runtime::Create(
-      runtime_context_,
-      this, content::SiteInstance::CreateForURL(runtime_context_, url));
-  render_process_host_ = runtime->GetRenderProcessHost();
-  render_process_host_->AddObserver(this);
-  web_contents_ = runtime->web_contents();
-  InitSecurityPolicy();
-  runtime->LoadURL(url);
-
-  NativeAppWindow::CreateParams params;
-  params.net_wm_pid = launch_params.launcher_pid;
-  if (data_->GetPackageType() == Package::WGT)
-    params.state = GetWindowShowStateWGT(launch_params);
-  else
-    params.state = GetWindowShowStateXPK(launch_params);
-
-  params.splash_screen_path = GetSplashScreenPath();
-
-  runtime->AttachWindow(params);
-
-  return true;
-}
-
-GURL Application::GetStartURL(const LaunchParams& params,
-    LaunchEntryPoint* used) {
-  if (params.entry_points & StartURLKey) {
-    GURL url = GetAbsoluteURLFromKey(keys::kStartURLKey);
-    if (url.is_valid()) {
-      *used = StartURLKey;
-      return url;
+  if (url.is_valid()) {
+#if defined(OS_TIZEN)
+    if (data_->IsHostedApp() && !url.SchemeIsHTTPOrHTTPS()) {
+      LOG(ERROR) << "Hosted apps are only supported with"
+                    "http:// or https:// scheme.";
+      return GURL();
     }
+#endif
+    return url;
   }
 
-  if (params.entry_points & LaunchLocalPathKey) {
-    GURL url = GetAbsoluteURLFromKey(
-        GetLaunchLocalPathKey(data_->GetPackageType()));
+  LOG(WARNING) << "Failed to find a valid start URL in the manifest.";
+  return GURL();
+}
 
-    if (!url.is_valid() && data_->GetPackageType() == Package::WGT)
-      url = GetDefaultWidgetEntryPage(data_);
+template<>
+GURL Application::GetStartURL<Package::XPK>() {
+  GURL url = GetAbsoluteURLFromKey(keys::kStartURLKey);
+  if (url.is_valid())
+    return url;
 
-    if (url.is_valid()) {
-#if defined(OS_TIZEN)
-      if (data_->IsHostedApp() && !url.SchemeIsHTTPOrHTTPS()) {
-        LOG(ERROR) << "Hosted application should use the url start with"
-                      "http or https as its entry page.";
-        return GURL();
-      }
-#endif
-      *used = LaunchLocalPathKey;
-      return url;
-    }
-  }
+  url = GetAbsoluteURLFromKey(keys::kLaunchLocalPathKey);
+  if (url.is_valid())
+    return url;
 
-  if (params.entry_points & URLKey) {
+  url = GetAbsoluteURLFromKey(keys::kDeprecatedURLKey);
+  if (url.is_valid()) {
     LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedURLKey
         << "' found. Please migrate to using '" << keys::kStartURLKey
         << "' instead.";
-    GURL url = GetAbsoluteURLFromKey(keys::kDeprecatedURLKey);
-    if (url.is_valid()) {
-      *used = URLKey;
-      return url;
-    }
+    return url;
   }
 
   LOG(WARNING) << "Failed to find a valid start URL in the manifest.";
   return GURL();
 }
 
-ui::WindowShowState Application::GetWindowShowStateWGT(
+
+template<>
+ui::WindowShowState Application::GetWindowShowState<Package::WGT>(
     const LaunchParams& params) {
   if (params.force_fullscreen)
     return ui::SHOW_STATE_FULLSCREEN;
@@ -197,7 +173,8 @@ ui::WindowShowState Application::GetWindowShowStateWGT(
   return ui::SHOW_STATE_DEFAULT;
 }
 
-ui::WindowShowState Application::GetWindowShowStateXPK(
+template<>
+ui::WindowShowState Application::GetWindowShowState<Package::XPK>(
     const LaunchParams& params) {
   if (params.force_fullscreen)
     return ui::SHOW_STATE_FULLSCREEN;
@@ -214,6 +191,44 @@ ui::WindowShowState Application::GetWindowShowStateXPK(
   return ui::SHOW_STATE_DEFAULT;
 }
 
+bool Application::Launch(const LaunchParams& launch_params) {
+  if (!runtimes_.empty()) {
+    LOG(ERROR) << "Attempt to launch app with id " << id()
+               << ", but it is already running.";
+    return false;
+  }
+
+  CHECK(!render_process_host_);
+  bool is_wgt = data_->GetPackageType() == Package::WGT;
+
+  GURL url = is_wgt ? GetStartURL<Package::WGT>():
+                      GetStartURL<Package::XPK>();
+  if (!url.is_valid())
+    return false;
+
+  remote_debugging_enabled_ = launch_params.remote_debugging;
+
+  Runtime* runtime = Runtime::Create(
+      runtime_context_,
+      this, content::SiteInstance::CreateForURL(runtime_context_, url));
+  render_process_host_ = runtime->GetRenderProcessHost();
+  render_process_host_->AddObserver(this);
+  web_contents_ = runtime->web_contents();
+  InitSecurityPolicy();
+  runtime->LoadURL(url);
+
+  NativeAppWindow::CreateParams params;
+  params.net_wm_pid = launch_params.launcher_pid;
+  params.state = is_wgt ? GetWindowShowState<Package::WGT>(launch_params):
+                          GetWindowShowState<Package::XPK>(launch_params);
+
+  params.splash_screen_path = GetSplashScreenPath();
+
+  runtime->AttachWindow(params);
+
+  return true;
+}
+
 GURL Application::GetAbsoluteURLFromKey(const std::string& key) {
   const Manifest* manifest = data_->GetManifest();
   std::string source;
@@ -221,7 +236,7 @@ GURL Application::GetAbsoluteURLFromKey(const std::string& key) {
   if (!manifest->GetString(key, &source) || source.empty())
     return GURL();
 
-  std::size_t found = source.find_first_of("://");
+  std::size_t found = source.find("://");
   if (found == std::string::npos)
     return data_->GetResourceURL(source);
   return GURL(source);
@@ -255,7 +270,6 @@ void Application::OnRuntimeRemoved(Runtime* runtime) {
     base::MessageLoop::current()->PostTask(FROM_HERE,
         base::Bind(&Application::NotifyTermination,
                    weak_factory_.GetWeakPtr()));
-    return;
   }
 }
 
@@ -276,7 +290,8 @@ void Application::RenderProcessHostDestroyed(RenderProcessHost* host) {
 
 void Application::NotifyTermination() {
   CHECK(!render_process_host_);
-  observer_->OnApplicationTerminated(this);
+  if (observer_)
+    observer_->OnApplicationTerminated(this);
 }
 
 bool Application::UseExtension(const std::string& extension_name) const {
index 6ee21ee..4a6840c 100644 (file)
@@ -58,24 +58,7 @@ class Application : public Runtime::Observer,
     virtual ~Observer() {}
   };
 
-  // Manifest keys that can be used as application entry points.
-  enum LaunchEntryPoint {
-    StartURLKey = 1 << 0,  // start_url
-    LaunchLocalPathKey = 1 << 1,  // app.launch.local_path
-    URLKey = 1 << 2,  // url
-    Default = StartURLKey | LaunchLocalPathKey
-  };
-  typedef unsigned LaunchEntryPoints;
-
   struct LaunchParams {
-    LaunchParams() :
-        entry_points(Default),
-        launcher_pid(0),
-        force_fullscreen(false),
-        remote_debugging(false) {}
-
-    LaunchEntryPoints entry_points;
-
     // Used only when running as service. Specifies the PID of the launcher
     // process.
     int32 launcher_pid;
@@ -126,12 +109,10 @@ class Application : public Runtime::Observer,
                      StoredPermission perm);
   bool CanRequestURL(const GURL& url) const;
 
+  void set_observer(Observer* observer) { observer_ = observer; }
+
  protected:
-  // We enforce ApplicationService ownership.
-  friend class ApplicationService;
-  Application(scoped_refptr<ApplicationData> data,
-              RuntimeContext* context,
-              Observer* observer);
+  Application(scoped_refptr<ApplicationData> data, RuntimeContext* context);
   virtual bool Launch(const LaunchParams& launch_params);
   virtual void InitSecurityPolicy();
 
@@ -151,6 +132,10 @@ class Application : public Runtime::Observer,
   }
 
  private:
+  // We enforce ApplicationService ownership.
+  friend class ApplicationService;
+  static scoped_ptr<Application> Create(scoped_refptr<ApplicationData> data,
+      RuntimeContext* context);
   // Runtime::Observer implementation.
   virtual void OnRuntimeAdded(Runtime* runtime) OVERRIDE;
   virtual void OnRuntimeRemoved(Runtime* runtime) OVERRIDE;
@@ -165,9 +150,10 @@ class Application : public Runtime::Observer,
 
   // Try to extract the URL from different possible keys for entry points in the
   // manifest, returns it and the entry point used.
-  GURL GetStartURL(const LaunchParams& params, LaunchEntryPoint* used);
-  ui::WindowShowState GetWindowShowStateWGT(const LaunchParams& params);
-  ui::WindowShowState GetWindowShowStateXPK(const LaunchParams& params);
+  template <Package::Type> GURL GetStartURL();
+
+  template <Package::Type>
+  ui::WindowShowState GetWindowShowState(const LaunchParams& params);
 
   GURL GetAbsoluteURLFromKey(const std::string& key);
 
@@ -175,8 +161,7 @@ class Application : public Runtime::Observer,
 
   RuntimeContext* runtime_context_;
   Observer* observer_;
-  // The entry point used as part of Launch().
-  LaunchEntryPoint entry_point_used_;
+
   std::map<std::string, std::string> name_perm_map_;
   // Application's session permissions.
   StoredPermissionMap permission_map_;
index e4c6005..6a68e4e 100644 (file)
@@ -4,79 +4,45 @@
 
 #include "xwalk/application/browser/application_service.h"
 
+#include <hash_set>
 #include <set>
 #include <string>
 #include <vector>
 
-#include "base/containers/hash_tables.h"
-#include "base/files/file_enumerator.h"
 #include "base/file_util.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "xwalk/application/browser/application.h"
-#include "xwalk/application/browser/application_system.h"
-#include "xwalk/application/common/application_storage.h"
-#include "xwalk/application/common/installer/package.h"
-#include "xwalk/application/common/installer/package_installer.h"
+#include "xwalk/application/common/application_manifest_constants.h"
 #include "xwalk/application/common/application_file_util.h"
+#include "xwalk/application/common/id_util.h"
 #include "xwalk/runtime/browser/runtime_context.h"
 #include "xwalk/runtime/browser/runtime.h"
-#include "xwalk/runtime/browser/xwalk_runner.h"
 #include "xwalk/runtime/common/xwalk_paths.h"
 
 #if defined(OS_TIZEN)
-#include "xwalk/application/browser/application_tizen.h"
+#include "xwalk/application/browser/application_service_tizen.h"
 #endif
 
 namespace xwalk {
 
 namespace application {
 
-namespace {
-
-const base::FilePath::CharType kApplicationDataDirName[] =
-    FILE_PATH_LITERAL("Storage/ext");
+ApplicationService::ApplicationService(RuntimeContext* runtime_context)
+  : runtime_context_(runtime_context) {
+}
 
-base::FilePath GetStoragePartitionPath(
-    const base::FilePath& base_path, const std::string& app_id) {
-#if defined(OS_WIN)
-  std::wstring application_id(app_id.begin(), app_id.end());
-  return base_path.Append(kApplicationDataDirName).Append(application_id);
+scoped_ptr<ApplicationService> ApplicationService::Create(
+    RuntimeContext* runtime_context) {
+#if defined(OS_TIZEN)
+  return make_scoped_ptr<ApplicationService>(
+    new ApplicationServiceTizen(runtime_context));
 #else
-  return base_path.Append(kApplicationDataDirName).Append(app_id);
+  return make_scoped_ptr(new ApplicationService(runtime_context));
 #endif
 }
 
-void CollectUnusedStoragePartitions(RuntimeContext* context,
-                                    ApplicationStorage* storage) {
-  std::vector<std::string> app_ids;
-  if (!storage->GetInstalledApplicationIDs(app_ids))
-    return;
-
-  scoped_ptr<base::hash_set<base::FilePath> > active_paths(
-      new base::hash_set<base::FilePath>()); // NOLINT
-
-  for (unsigned i = 0; i < app_ids.size(); ++i) {
-    active_paths->insert(
-        GetStoragePartitionPath(context->GetPath(), app_ids.at(i)));
-  }
-
-  content::BrowserContext::GarbageCollectStoragePartitions(
-      context, active_paths.Pass(), base::Bind(&base::DoNothing));
-}
-
-}  // namespace
-
-ApplicationService::ApplicationService(RuntimeContext* runtime_context,
-                                       ApplicationStorage* app_storage)
-    : runtime_context_(runtime_context),
-      application_storage_(app_storage) {
-  CollectUnusedStoragePartitions(runtime_context, app_storage);
-}
-
 ApplicationService::~ApplicationService() {
 }
 
@@ -91,14 +57,8 @@ Application* ApplicationService::Launch(
     return NULL;
   }
 
-#if defined(OS_TIZEN)
-  Application* application(new ApplicationTizen(application_data,
-    runtime_context_, this));
-#else
-  Application* application(new Application(application_data,
-    runtime_context_, this));
-#endif
-
+  Application* application = Application::Create(application_data,
+    runtime_context_).release();
   ScopedVector<Application>::iterator app_iter =
       applications_.insert(applications_.end(), application);
 
@@ -107,35 +67,63 @@ Application* ApplicationService::Launch(
     return NULL;
   }
 
+  application->set_observer(this);
+
   FOR_EACH_OBSERVER(Observer, observers_,
                     DidLaunchApplication(application));
 
   return application;
 }
 
-Application* ApplicationService::Launch(
-    const std::string& id, const Application::LaunchParams& params) {
-  scoped_refptr<ApplicationData> application_data =
-    application_storage_->GetApplicationData(id);
+Application* ApplicationService::LaunchFromUnpackedPath(
+    const base::FilePath& path, const Application::LaunchParams& params) {
+  std::string error;
+  scoped_refptr<ApplicationData> application_data;
+  if (!base::DirectoryExists(path)) {
+    LOG(ERROR) << "Invalid input parameter: " << path.AsUTF8Unsafe();
+    return NULL;
+  }
+
+  application_data =
+      LoadApplication(path, ApplicationData::LOCAL_DIRECTORY, &error);
+
   if (!application_data) {
-    LOG(ERROR) << "Application with id " << id << " is not installed.";
+    LOG(ERROR) << "Error occurred while trying to load application: "
+               << error;
     return NULL;
   }
 
   return Launch(application_data, params);
 }
 
-Application* ApplicationService::Launch(
+Application* ApplicationService::LaunchFromPackagePath(
     const base::FilePath& path, const Application::LaunchParams& params) {
-  if (!base::DirectoryExists(path))
+  scoped_ptr<Package> package = Package::Create(path);
+  if (!package || !package->IsValid()) {
+    LOG(ERROR) << "Failed to obtain valid package from "
+               << path.AsUTF8Unsafe();
     return NULL;
+  }
+
+  base::FilePath tmp_dir, target_dir;
+  if (!GetTempDir(&tmp_dir)) {
+    LOG(ERROR) << "Failed to obtain system temp directory.";
+    return NULL;
+  }
 
   std::string error;
-  scoped_refptr<ApplicationData> application_data =
-      LoadApplication(path, Manifest::COMMAND_LINE, &error);
+  scoped_refptr<ApplicationData> application_data;
+
+  base::CreateTemporaryDirInDir(tmp_dir, package->name(), &target_dir);
+  if (package->ExtractTo(target_dir)) {
+    std::string id = tmp_dir.BaseName().AsUTF8Unsafe();
+    application_data =
+        LoadApplication(
+            target_dir, id, ApplicationData::TEMP_DIRECTORY, &error);
+  }
 
   if (!application_data) {
-    LOG(ERROR) << "Error occurred while trying to launch application: "
+    LOG(ERROR) << "Error occurred while trying to load application: "
                << error;
     return NULL;
   }
@@ -143,6 +131,35 @@ Application* ApplicationService::Launch(
   return Launch(application_data, params);
 }
 
+// Launch an application created from arbitrary url.
+// FIXME: This application should have the same strict permissions
+// as common browser apps.
+Application* ApplicationService::LaunchHostedURL(
+    const GURL& url, const Application::LaunchParams& params) {
+  const std::string& url_spec = url.spec();
+  if (url_spec.empty()) {
+      LOG(ERROR) << "Failed to launch application from the URL: " << url;
+      return NULL;
+  }
+
+  const std::string& app_id = GenerateId(url_spec);
+
+  base::DictionaryValue manifest;
+  // FIXME: define permissions!
+  manifest.SetString(application_manifest_keys::kStartURLKey, url_spec);
+  // FIXME: Why use URL as name?
+  manifest.SetString(application_manifest_keys::kNameKey, url_spec);
+  manifest.SetString(application_manifest_keys::kXWalkVersionKey, "0");
+
+  std::string error;
+  scoped_refptr<ApplicationData> app_data =
+        ApplicationData::Create(base::FilePath(),
+            ApplicationData::EXTERNAL_URL, manifest, app_id, &error);
+  DCHECK(app_data);
+
+  return Launch(app_data, params);
+}
+
 namespace {
 
 struct ApplicationRenderHostIDComparator {
@@ -198,7 +215,23 @@ void ApplicationService::OnApplicationTerminated(
   CHECK(found != applications_.end());
   FOR_EACH_OBSERVER(Observer, observers_,
                     WillDestroyApplication(application));
+  scoped_refptr<ApplicationData> app_data = application->data();
   applications_.erase(found);
+
+  if (app_data->source_type() == ApplicationData::TEMP_DIRECTORY) {
+      LOG(INFO) << "Deleting the app temporary directory "
+                << app_data->Path().AsUTF8Unsafe();
+      content::BrowserThread::PostTask(content::BrowserThread::FILE,
+          FROM_HERE, base::Bind(base::IgnoreResult(&base::DeleteFile),
+                                app_data->Path(), true /*recursive*/));
+      // FIXME: So far we simply clean up all the app persistent data,
+      // further we need to add an appropriate logic to handle it.
+      content::BrowserContext::GarbageCollectStoragePartitions(
+          runtime_context_,
+          make_scoped_ptr(new base::hash_set<base::FilePath>()),
+          base::Bind(&base::DoNothing));
+  }
+
 #if !defined(SHARED_PROCESS_MODE)
   if (applications_.empty()) {
     base::MessageLoop::current()->PostTask(
index 81da985..92dc801 100644 (file)
@@ -6,13 +6,13 @@
 #define XWALK_APPLICATION_BROWSER_APPLICATION_SERVICE_H_
 
 #include <string>
+
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "base/observer_list.h"
 #include "xwalk/application/browser/application.h"
 #include "xwalk/application/common/permission_policy_manager.h"
-#include "xwalk/runtime/browser/runtime_context.h"
 #include "xwalk/application/common/application_data.h"
 
 namespace xwalk {
@@ -21,15 +21,11 @@ class RuntimeContext;
 
 namespace application {
 
-class ApplicationStorage;
-class PackageInstaller;
-
-// The application service manages install, uninstall and updates of
-// applications.
+// The application service manages launch and termination of the applications.
 class ApplicationService : public Application::Observer {
  public:
   // Client code may use this class (and register with AddObserver below) to
-  // keep track of [un]installation of applications.
+  // keep track of applications life cycle.
   class Observer {
    public:
     virtual void DidLaunchApplication(Application* app) {}
@@ -38,22 +34,30 @@ class ApplicationService : public Application::Observer {
     virtual ~Observer() {}
   };
 
-  ApplicationService(RuntimeContext* runtime_context,
-                     ApplicationStorage* app_storage);
   virtual ~ApplicationService();
 
-  Application* Launch(scoped_refptr<ApplicationData> application_data,
-                      const Application::LaunchParams& launch_params);
-  // Launch an installed application using application id.
-  Application* Launch(
-      const std::string& id,
+  static scoped_ptr<ApplicationService> Create(
+    RuntimeContext* runtime_context);
+
+  // Launch an application using path to a local directory which
+  // contains manifest file of an unpacked application.
+  Application* LaunchFromUnpackedPath(
+      const base::FilePath& path,
       const Application::LaunchParams& params = Application::LaunchParams());
-  // Launch an unpacked application using path to a local directory which
-  // contains manifest file.
-  Application* Launch(
+
+  // Launch an application using path to its package file.
+  // Note: the given package is unpacked to a temporary folder,
+  // which is deleted after the application terminates.
+  Application* LaunchFromPackagePath(
       const base::FilePath& path,
       const Application::LaunchParams& params = Application::LaunchParams());
 
+  // Launch an application from an arbitrary URL.
+  // Creates a "dummy" application.
+  Application* LaunchHostedURL(
+      const GURL& url,
+      const Application::LaunchParams& params = Application::LaunchParams());
+
   Application* GetApplicationByRenderHostID(int id) const;
   Application* GetApplicationByID(const std::string& app_id) const;
 
@@ -76,12 +80,17 @@ class ApplicationService : public Application::Observer {
       const std::string& extension_name,
       const std::string& perm_table);
 
+ protected:
+  explicit ApplicationService(RuntimeContext* runtime_context);
+
+  Application* Launch(scoped_refptr<ApplicationData> application_data,
+                      const Application::LaunchParams& launch_params);
+
  private:
   // Implementation of Application::Observer.
   virtual void OnApplicationTerminated(Application* app) OVERRIDE;
 
-  xwalk::RuntimeContext* runtime_context_;
-  ApplicationStorage* application_storage_;
+  RuntimeContext* runtime_context_;
   ScopedVector<Application> applications_;
   ObserverList<Observer> observers_;
 
diff --git a/src/xwalk/application/browser/application_service_tizen.cc b/src/xwalk/application/browser/application_service_tizen.cc
new file mode 100644 (file)
index 0000000..d8bf715
--- /dev/null
@@ -0,0 +1,77 @@
+// 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/application/browser/application_service_tizen.h"
+
+#include <string>
+#include <vector>
+
+#include "xwalk/application/browser/application.h"
+#include "xwalk/application/common/application_storage.h"
+#include "xwalk/application/common/id_util.h"
+#include "xwalk/runtime/browser/runtime_context.h"
+
+namespace xwalk {
+
+namespace application {
+
+namespace {
+
+const base::FilePath::CharType kApplicationDataDirName[] =
+    FILE_PATH_LITERAL("Storage/ext");
+
+base::FilePath GetStoragePartitionPath(
+    const base::FilePath& base_path, const std::string& app_id) {
+  return base_path.Append(kApplicationDataDirName).Append(app_id);
+}
+
+void CollectUnusedStoragePartitions(RuntimeContext* context,
+                                    ApplicationStorage* storage) {
+  std::vector<std::string> app_ids;
+  if (!storage->GetInstalledApplicationIDs(app_ids))
+    return;
+
+  scoped_ptr<base::hash_set<base::FilePath> > active_paths(
+      new base::hash_set<base::FilePath>()); // NOLINT
+
+  for (unsigned i = 0; i < app_ids.size(); ++i) {
+    active_paths->insert(
+        GetStoragePartitionPath(context->GetPath(), app_ids.at(i)));
+  }
+
+  content::BrowserContext::GarbageCollectStoragePartitions(
+      context, active_paths.Pass(), base::Bind(&base::DoNothing));
+}
+
+}  // namespace
+
+ApplicationServiceTizen::ApplicationServiceTizen(
+    RuntimeContext* runtime_context)
+  : ApplicationService(runtime_context),
+    application_storage_(new ApplicationStorage(runtime_context->GetPath())) {
+  CollectUnusedStoragePartitions(runtime_context, application_storage_.get());
+}
+
+ApplicationServiceTizen::~ApplicationServiceTizen() {
+}
+
+Application* ApplicationServiceTizen::LaunchFromAppID(
+    const std::string& id, const Application::LaunchParams& params) {
+  if (!IsValidApplicationID(id)) {
+     LOG(ERROR) << "The input parameter is not a valid app id: " << id;
+     return NULL;
+  }
+
+  scoped_refptr<ApplicationData> app_data =
+    application_storage_->GetApplicationData(id);
+  if (!app_data) {
+    LOG(ERROR) << "Application with id " << id << " is not installed.";
+    return NULL;
+  }
+
+  return Launch(app_data, params);
+}
+
+}  // namespace application
+}  // namespace xwalk
diff --git a/src/xwalk/application/browser/application_service_tizen.h b/src/xwalk/application/browser/application_service_tizen.h
new file mode 100644 (file)
index 0000000..16f0424
--- /dev/null
@@ -0,0 +1,43 @@
+// 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_APPLICATION_BROWSER_APPLICATION_SERVICE_TIZEN_H_
+#define XWALK_APPLICATION_BROWSER_APPLICATION_SERVICE_TIZEN_H_
+
+#include <string>
+
+#include "xwalk/application/browser/application_service.h"
+
+namespace xwalk {
+
+namespace application {
+
+class ApplicationStorage;
+
+// The application service manages launch and termination of the applications.
+class ApplicationServiceTizen : public ApplicationService {
+ public:
+  virtual ~ApplicationServiceTizen();
+  // Launch an installed application using application id.
+  Application* LaunchFromAppID(
+      const std::string& id,
+      const Application::LaunchParams& params = Application::LaunchParams());
+
+ private:
+  friend class ApplicationService;
+  explicit ApplicationServiceTizen(RuntimeContext* runtime_context);
+  // Note : do not export app storage from this class! We need consider
+  // making ApplicationSystemTizen (owning the storage) instead.
+  scoped_ptr<ApplicationStorage> application_storage_;
+};
+
+inline ApplicationServiceTizen* ToApplicationServiceTizen(
+    ApplicationService* service) {
+  return static_cast<ApplicationServiceTizen*>(service);
+}
+
+}  // namespace application
+}  // namespace xwalk
+
+#endif  // XWALK_APPLICATION_BROWSER_APPLICATION_SERVICE_TIZEN_H_
index 603f938..ce1544c 100644 (file)
@@ -12,7 +12,6 @@
 #include "net/base/filename_util.h"
 #include "xwalk/application/browser/application.h"
 #include "xwalk/application/browser/application_service.h"
-#include "xwalk/application/common/application_storage.h"
 #include "xwalk/application/common/application_manifest_constants.h"
 #include "xwalk/application/common/id_util.h"
 #include "xwalk/application/extension/application_runtime_extension.h"
 #include "xwalk/application/browser/application_system_linux.h"
 #endif
 
+#if defined(OS_TIZEN)
+#include "xwalk/application/browser/application_service_tizen.h"
+#endif
+
 namespace xwalk {
 namespace application {
 
 ApplicationSystem::ApplicationSystem(RuntimeContext* runtime_context)
   : runtime_context_(runtime_context),
-    application_storage_(new ApplicationStorage(runtime_context->GetPath())),
-    application_service_(new ApplicationService(
-        runtime_context,
-        application_storage_.get())) {}
+    application_service_(ApplicationService::Create(
+        runtime_context)) {}
 
 ApplicationSystem::~ApplicationSystem() {
 }
@@ -49,68 +50,62 @@ scoped_ptr<ApplicationSystem> ApplicationSystem::Create(
   return app_system.Pass();
 }
 
-template <typename T>
-bool ApplicationSystem::LaunchWithCommandLineParam(
-    const T& param, const base::CommandLine& cmd_line) {
-  Application::LaunchParams launch_params;
-  launch_params.force_fullscreen = cmd_line.HasSwitch(switches::kFullscreen);
-  launch_params.remote_debugging =
-      cmd_line.HasSwitch(switches::kRemoteDebuggingPort);
-
-  return application_service_->Launch(param, launch_params);
-}
-
-// Launch an application created from arbitrary url.
-// FIXME: This application should have the same strict permissions
-// as common browser apps.
-template <>
-bool ApplicationSystem::LaunchWithCommandLineParam<GURL>(
-    const GURL& url, const base::CommandLine& cmd_line) {
-  std::string error;
-  scoped_refptr<ApplicationData> application_data =
-      ApplicationData::Create(url, &error);
-  if (!application_data) {
-    LOG(ERROR) << "Error occurred while trying to launch application: "
-               << error;
-    return false;
-  }
+namespace {
 
-  Application::LaunchParams launch_params;
-  launch_params.force_fullscreen = cmd_line.HasSwitch(switches::kFullscreen);
-  launch_params.entry_points = Application::StartURLKey;
-  launch_params.remote_debugging =
+Application::LaunchParams launch_params(
+    const base::CommandLine& cmd_line) {
+  Application::LaunchParams params;
+  params.force_fullscreen = cmd_line.HasSwitch(switches::kFullscreen);
+  params.remote_debugging =
       cmd_line.HasSwitch(switches::kRemoteDebuggingPort);
-
-  return !!application_service_->Launch(application_data, launch_params);
+  return params;
 }
 
+}  // namespace
+
 bool ApplicationSystem::LaunchFromCommandLine(
     const base::CommandLine& cmd_line, const GURL& url,
     bool& run_default_message_loop) { // NOLINT
 
+#if defined(OS_TIZEN)
   // Handles raw app_id passed as first non-switch argument.
   const base::CommandLine::StringVector& args = cmd_line.GetArgs();
   if (!args.empty()) {
     std::string app_id = std::string(args[0].begin(), args[0].end());
     if (IsValidApplicationID(app_id)) {
-      run_default_message_loop = LaunchWithCommandLineParam(app_id, cmd_line);
+      ApplicationServiceTizen* app_service_tizen =
+          ToApplicationServiceTizen(application_service_.get());
+      run_default_message_loop = app_service_tizen->LaunchFromAppID(
+          app_id, launch_params(cmd_line));
       return true;
     }
   }
-
+#endif
   if (!url.is_valid())
     return false;
 
   base::FilePath path;
-  if (url.SchemeIsFile() &&
-      net::FileURLToFilePath(url, &path) &&
-      base::DirectoryExists(path)) {  // Handles local directory.
-    run_default_message_loop = LaunchWithCommandLineParam(path, cmd_line);
-  } else {  // Handles external URL.
-    run_default_message_loop = LaunchWithCommandLineParam(url, cmd_line);
+  bool is_local = url.SchemeIsFile() && net::FileURLToFilePath(url, &path);
+  if (!is_local) {  // Handles external URL.
+    run_default_message_loop = application_service_->LaunchHostedURL(
+        url, launch_params(cmd_line));
+    return true;
+  }
+
+  if (base::DirectoryExists(path)) {  // Handles unpacked application.
+    run_default_message_loop = application_service_->LaunchFromUnpackedPath(
+        path, launch_params(cmd_line));
+    return true;
+  }
+
+  if (path.MatchesExtension(FILE_PATH_LITERAL(".xpk")) ||
+      path.MatchesExtension(FILE_PATH_LITERAL(".wgt"))) {
+    run_default_message_loop = application_service_->LaunchFromPackagePath(
+        path, launch_params(cmd_line));
+    return true;
   }
 
-  return true;
+  return false;
 }
 
 void ApplicationSystem::CreateExtensions(
index a6f0d41..4d88035 100644 (file)
@@ -29,8 +29,6 @@ namespace xwalk {
 namespace application {
 
 class ApplicationService;
-class ApplicationServiceProvider;
-class ApplicationStorage;
 
 // The ApplicationSystem manages the creation and destruction of services which
 // related to applications' runtime model.
@@ -47,16 +45,13 @@ class ApplicationSystem {
     return application_service_.get();
   }
 
-  ApplicationStorage* application_storage() {
-    return application_storage_.get();
-  }
-
   // Launches an application based on the given command line, there are
   // different ways to inform which application should be launched
   //
   // (1) app_id from the binary name (used in Tizen);
-  // (2) app_id passed in the command line;
+  // (2) app_id passed in the command line (used in Tizen);
   // (3) launching a directory that contains an extracted package.
+  // (4) launching from the path to the packaged application file.
   //
   // The parameter `url` contains the current URL Crosswalk is considering to
   // load, and the output parameter `run_default_message_loop` controls whether
@@ -66,7 +61,7 @@ class ApplicationSystem {
   // line, so the caller shouldn't try to load the url by itself.
   bool LaunchFromCommandLine(const base::CommandLine& cmd_line,
                              const GURL& url,
-                             bool& run_default_message_loop_);
+                             bool& run_default_message_loop_);  // NOLINT
 
   void CreateExtensions(content::RenderProcessHost* host,
                         extensions::XWalkExtensionVector* extensions);
@@ -75,12 +70,8 @@ class ApplicationSystem {
   explicit ApplicationSystem(RuntimeContext* runtime_context);
 
  private:
-  template <typename T>
-  bool LaunchWithCommandLineParam(const T& param,
-                                  const base::CommandLine& cmd_line);
   // Note: initialization order matters.
-  xwalk::RuntimeContext* runtime_context_;
-  scoped_ptr<ApplicationStorage> application_storage_;
+  RuntimeContext* runtime_context_;
   scoped_ptr<ApplicationService> application_service_;
 
   DISALLOW_COPY_AND_ASSIGN(ApplicationSystem);
index e39f231..fd41d65 100644 (file)
@@ -76,9 +76,8 @@ class ScreenOrientationProviderTizen :
 
 ApplicationTizen::ApplicationTizen(
     scoped_refptr<ApplicationData> data,
-    RuntimeContext* runtime_context,
-    Application::Observer* observer)
-    : Application(data, runtime_context, observer),
+    RuntimeContext* runtime_context)
+    : Application(data, runtime_context),
       is_suspended_(false) {
 #if defined(USE_OZONE)
   ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
index 5cace02..755b674 100644 (file)
@@ -27,11 +27,9 @@ class ApplicationTizen :  // NOLINT
   void Resume();
 
  private:
-  // We enforce ApplicationService ownership.
-  friend class ApplicationService;
+  friend class Application;
   ApplicationTizen(scoped_refptr<ApplicationData> data,
-                   RuntimeContext* context,
-                   Application::Observer* observer);
+                   RuntimeContext* context);
   virtual bool Launch(const LaunchParams& launch_params) OVERRIDE;
 
   virtual base::FilePath GetSplashScreenPath() OVERRIDE;
index b020e31..1181f03 100644 (file)
 #include "xwalk/application/common/application_data.h"
 #include "xwalk/runtime/browser/xwalk_runner.h"
 
+#if defined(OS_TIZEN)
+#include "xwalk/application/browser/application_service_tizen.h"
+#endif
+
 namespace {
 
 // D-Bus Interface implemented by the manager object of running applications.
@@ -157,22 +161,16 @@ void RunningApplicationsManager::OnLaunch(
   params.force_fullscreen = fullscreen;
   params.remote_debugging = remote_debugging;
 
-  Application* application;
-  if (GURL(app_id_or_url).spec().empty()) {
-    application = application_service_->Launch(app_id_or_url, params);
-  } else {
-    params.entry_points = Application::StartURLKey;
-    std::string error;
-    scoped_refptr<ApplicationData> application_data =
-        ApplicationData::Create(GURL(app_id_or_url), &error);
-    if (!application_data) {
-      scoped_ptr<dbus::Response> response = CreateError(method_call, error);
-      response_sender.Run(response.Pass());
-      return;
-    }
-
-    application = application_service_->Launch(application_data, params);
-  }
+  Application* application = NULL;
+  GURL url(app_id_or_url);
+  if (!url.spec().empty())
+    application = application_service_->LaunchHostedURL(url, params);
+
+#if defined(OS_TIZEN)
+  if (!application)
+    application = ToApplicationServiceTizen(
+        application_service_)->LaunchFromAppID(app_id_or_url, params);
+#endif
 
   if (!application) {
     scoped_ptr<dbus::Response> response =
index d6d371c..8048c4c 100644 (file)
@@ -44,48 +44,26 @@ namespace application {
 // static
 scoped_refptr<ApplicationData> ApplicationData::Create(
     const base::FilePath& path,
-    Manifest::SourceType source_type,
+    SourceType source_type,
     const base::DictionaryValue& manifest_data,
     const std::string& explicit_id,
     std::string* error_message) {
   DCHECK(error_message);
   base::string16 error;
-  scoped_ptr<xwalk::application::Manifest> manifest(
-      new xwalk::application::Manifest(source_type,
-                 scoped_ptr<base::DictionaryValue>(manifest_data.DeepCopy())));
+  scoped_ptr<Manifest> manifest(new Manifest(
+      scoped_ptr<base::DictionaryValue>(manifest_data.DeepCopy())));
 
   if (!manifest->ValidateManifest(error_message))
     return NULL;
 
-  scoped_refptr<ApplicationData> application = new ApplicationData(path,
-                                                           manifest.Pass());
-  if (!application->Init(explicit_id, &error)) {
+  scoped_refptr<ApplicationData> app_data =
+      new ApplicationData(path, source_type, manifest.Pass());
+  if (!app_data->Init(explicit_id, &error)) {
     *error_message = base::UTF16ToUTF8(error);
     return NULL;
   }
 
-  return application;
-}
-
-// static
-scoped_refptr<ApplicationData> ApplicationData::Create(
-    const GURL& url,
-    std::string* error_message) {
-  const std::string& url_spec = url.spec();
-  DCHECK(!url_spec.empty());
-  const std::string& app_id = GenerateId(url_spec);
-
-  base::DictionaryValue manifest;
-  // FIXME: define permissions!
-  manifest.SetString(application_manifest_keys::kStartURLKey, url_spec);
-  // FIXME: Why use URL as name?
-  manifest.SetString(application_manifest_keys::kNameKey, url_spec);
-  manifest.SetString(application_manifest_keys::kXWalkVersionKey, "0");
-  scoped_refptr<ApplicationData> application_data =
-      ApplicationData::Create(base::FilePath(), Manifest::COMMAND_LINE,
-                              manifest, app_id, error_message);
-
-  return application_data;
+  return app_data;
 }
 
 // static
@@ -110,10 +88,6 @@ void ApplicationData::SetManifestData(const std::string& key,
   manifest_data_[key] = linked_ptr<ManifestData>(data);
 }
 
-Manifest::SourceType ApplicationData::GetSourceType() const {
-  return manifest_->GetSourceType();
-}
-
 const std::string& ApplicationData::ID() const {
   return manifest_->GetApplicationID();
 }
@@ -131,19 +105,16 @@ const std::string ApplicationData::VersionString() const {
   return "";
 }
 
-bool ApplicationData::IsPlatformApp() const {
-  return manifest_->IsPackaged();
-}
-
 bool ApplicationData::IsHostedApp() const {
   return GetManifest()->IsHosted();
 }
 
 ApplicationData::ApplicationData(const base::FilePath& path,
-                     scoped_ptr<xwalk::application::Manifest> manifest)
+    SourceType source_type, scoped_ptr<Manifest> manifest)
     : manifest_version_(0),
       manifest_(manifest.release()),
-      finished_parsing_manifest_(false) {
+      finished_parsing_manifest_(false),
+      source_type_(source_type) {
   DCHECK(path.empty() || path.IsAbsolute());
   path_ = path;
   if (manifest_->HasPath(widget_keys::kWidgetKey))
@@ -158,7 +129,7 @@ ApplicationData::~ApplicationData() {
 // static
 GURL ApplicationData::GetResourceURL(const GURL& application_url,
                                const std::string& relative_path) {
-  DCHECK(application_url.SchemeIs(xwalk::application::kApplicationScheme));
+  DCHECK(application_url.SchemeIs(kApplicationScheme));
   DCHECK_EQ("/", application_url.path());
 
   std::string path = relative_path;
index 1a3563c..deb61ec 100644 (file)
@@ -24,6 +24,7 @@
 #include "url/gurl.h"
 #include "xwalk/application/common/manifest.h"
 #include "xwalk/application/common/permission_types.h"
+#include "xwalk/application/common/package/package.h"
 
 namespace base {
 class DictionaryValue;
@@ -36,6 +37,14 @@ namespace application {
 
 class ApplicationData : public base::RefCountedThreadSafe<ApplicationData> {
  public:
+  // Where an application was loaded from.
+  enum SourceType {
+    INTERNAL,         // From internal application registry.
+    LOCAL_DIRECTORY,  // From a persistently stored unpacked application
+    TEMP_DIRECTORY,   // From a temporary folder
+    EXTERNAL_URL      // From an arbitrary URL
+  };
+
   struct ManifestData;
 
   struct ApplicationIdCompare {
@@ -59,14 +68,11 @@ class ApplicationData : public base::RefCountedThreadSafe<ApplicationData> {
   };
 
   static scoped_refptr<ApplicationData> Create(const base::FilePath& path,
-      Manifest::SourceType source_type,
+      SourceType source_type,
       const base::DictionaryValue& manifest_data,
       const std::string& explicit_id,
       std::string* error_message);
 
-  static scoped_refptr<ApplicationData> Create(const GURL& url,
-                                               std::string* error_message);
-
   Manifest::Type GetType() const;
 
   // Returns an absolute url to a resource inside of an application. The
@@ -97,7 +103,7 @@ class ApplicationData : public base::RefCountedThreadSafe<ApplicationData> {
   const base::FilePath& Path() const { return path_; }
   void SetPath(const base::FilePath& path) { path_ = path; }
   const GURL& URL() const { return application_url_; }
-  Manifest::SourceType GetSourceType() const;
+  SourceType source_type() const { return source_type_; }
   const std::string& ID() const;
 #if defined(OS_TIZEN)
   std::string GetPackageID() const;
@@ -115,7 +121,6 @@ class ApplicationData : public base::RefCountedThreadSafe<ApplicationData> {
   const base::Time& install_time() const { return install_time_; }
 
   // App-related.
-  bool IsPlatformApp() const;
   bool IsHostedApp() const;
 
   // Permission related.
@@ -136,8 +141,8 @@ class ApplicationData : public base::RefCountedThreadSafe<ApplicationData> {
   friend class base::RefCountedThreadSafe<ApplicationData>;
   friend class ApplicationStorageImpl;
 
-  ApplicationData(const base::FilePath& path,
-            scoped_ptr<Manifest> manifest);
+  ApplicationData(const base::FilePath& path, SourceType source_type,
+                  scoped_ptr<Manifest> manifest);
   virtual ~ApplicationData();
 
   // Initialize the application from a parsed manifest.
@@ -211,6 +216,9 @@ class ApplicationData : public base::RefCountedThreadSafe<ApplicationData> {
   // The package type, wgt or xpk.
   Package::Type package_type_;
 
+  // The source the application was loaded from.
+  SourceType source_type_;
+
   DISALLOW_COPY_AND_ASSIGN(ApplicationData);
 };
 
index 33dffda..fb9a302 100644 (file)
@@ -25,7 +25,6 @@
 #include "net/base/file_stream.h"
 #include "third_party/libxml/src/include/libxml/tree.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "xwalk/application/common/installer/package.h"
 #include "xwalk/application/common/application_data.h"
 #include "xwalk/application/common/application_manifest_constants.h"
 #include "xwalk/application/common/constants.h"
@@ -362,7 +361,7 @@ base::DictionaryValue* LoadXMLNode(
 
 scoped_refptr<ApplicationData> LoadApplication(
     const base::FilePath& application_path,
-    Manifest::SourceType source_type,
+    ApplicationData::SourceType source_type,
     std::string* error) {
   Package::Type package_type;
   if (!GetPackageType(application_path, &package_type, error))
@@ -375,7 +374,7 @@ scoped_refptr<ApplicationData> LoadApplication(
 scoped_refptr<ApplicationData> LoadApplication(
     const base::FilePath& application_path,
     const std::string& application_id,
-    Manifest::SourceType source_type,
+    ApplicationData::SourceType source_type,
     std::string* error) {
   Package::Type package_type;
 #if defined(OS_TIZEN)
@@ -392,7 +391,7 @@ scoped_refptr<ApplicationData> LoadApplication(
 scoped_refptr<ApplicationData> LoadApplication(
     const base::FilePath& application_path,
     const std::string& application_id,
-    Manifest::SourceType source_type,
+    ApplicationData::SourceType source_type,
     Package::Type package_type,
     std::string* error) {
   scoped_ptr<base::DictionaryValue> manifest(
index c413ee8..30e07f4 100644 (file)
@@ -9,9 +9,7 @@
 #include <map>
 
 #include "base/memory/ref_counted.h"
-#include "xwalk/application/common/installer/package.h"
-#include "xwalk/application/common/manifest.h"
-
+#include "xwalk/application/common/application_data.h"
 
 class GURL;
 
@@ -43,20 +41,20 @@ class FileDeleter {
 // on failure, with a description of the error in |error|.
 scoped_refptr<ApplicationData> LoadApplication(
     const base::FilePath& application_root,
-    Manifest::SourceType source_type,
+    ApplicationData::SourceType source_type,
     std::string* error);
 
 // The same as LoadApplication except use the provided |application_id|.
 scoped_refptr<ApplicationData> LoadApplication(
     const base::FilePath& application_root,
     const std::string& application_id,
-    Manifest::SourceType source_type,
+    ApplicationData::SourceType source_type,
     std::string* error);
 
 scoped_refptr<ApplicationData> LoadApplication(
     const base::FilePath& application_root,
     const std::string& application_id,
-    Manifest::SourceType source_type,
+    ApplicationData::SourceType source_type,
     Package::Type package_type,
     std::string* error);
 
index c2542d6..163a844 100644 (file)
@@ -41,7 +41,7 @@ TEST_F(ApplicationFileUtilTest, LoadApplicationWithValidPath) {
 
   std::string error;
   scoped_refptr<ApplicationData> application(LoadApplication(
-          install_dir, Manifest::COMMAND_LINE, &error));
+          install_dir, ApplicationData::LOCAL_DIRECTORY, &error));
   ASSERT_TRUE(application != NULL);
   EXPECT_EQ("The first application that I made.", application->Description());
 }
@@ -60,7 +60,7 @@ TEST_F(ApplicationFileUtilTest,
 
   std::string error;
   scoped_refptr<ApplicationData> application(LoadApplication(
-          install_dir, Manifest::COMMAND_LINE, &error));
+          install_dir, ApplicationData::LOCAL_DIRECTORY, &error));
   ASSERT_TRUE(application == NULL);
   ASSERT_FALSE(error.empty());
   ASSERT_STREQ("Manifest file is missing or unreadable.", error.c_str());
@@ -80,7 +80,7 @@ TEST_F(ApplicationFileUtilTest,
 
   std::string error;
   scoped_refptr<ApplicationData> application(LoadApplication(
-          install_dir, Manifest::COMMAND_LINE, &error));
+          install_dir, ApplicationData::LOCAL_DIRECTORY, &error));
   ASSERT_TRUE(application == NULL);
   ASSERT_FALSE(error.empty());
   ASSERT_STREQ("Manifest is not valid JSON."
@@ -91,7 +91,7 @@ TEST_F(ApplicationFileUtilTest,
 static scoped_refptr<ApplicationData> LoadApplicationManifest(
     base::DictionaryValue* manifest,
     const base::FilePath& manifest_dir,
-    Manifest::SourceType location,
+    ApplicationData::SourceType location,
     int extra_flags,
     std::string* error) {
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
@@ -102,7 +102,7 @@ static scoped_refptr<ApplicationData> LoadApplicationManifest(
 static scoped_refptr<ApplicationData> LoadApplicationManifest(
     const std::string& manifest_value,
     const base::FilePath& manifest_dir,
-    Manifest::SourceType location,
+    ApplicationData::SourceType location,
     int extra_flags,
     std::string* error) {
   JSONStringValueSerializer serializer(manifest_value);
@@ -135,7 +135,7 @@ TEST_F(ApplicationFileUtilTest, ValidateThemeUTF8) {
           "}", non_ascii_file.c_str());
   std::string error;
   scoped_refptr<ApplicationData> application = LoadApplicationManifest(
-      kManifest, temp.path(), Manifest::COMMAND_LINE, 0, &error);
+      kManifest, temp.path(), ApplicationData::LOCAL_DIRECTORY, 0, &error);
   ASSERT_TRUE(application.get()) << error;
 }
 
index a6cff56..4ed0b96 100644 (file)
@@ -161,13 +161,6 @@ const char* GetVersionKey(Package::Type package_type) {
   return application_manifest_keys::kXWalkVersionKey;
 }
 
-const char* GetLaunchLocalPathKey(Package::Type package_type) {
-  if (package_type == Package::WGT)
-    return application_widget_keys::kLaunchLocalPathKey;
-
-  return application_manifest_keys::kLaunchLocalPathKey;
-}
-
 const char* GetCSPKey(Package::Type package_type) {
   if (package_type == Package::WGT)
     return application_widget_keys::kCSPKey;
index 0a8ebe9..85ebc2d 100644 (file)
@@ -6,6 +6,7 @@
 #define XWALK_APPLICATION_COMMON_APPLICATION_MANIFEST_CONSTANTS_H_
 
 #include "xwalk/application/common/manifest.h"
+#include "xwalk/application/common/package/package.h"
 // Keys used in JSON representation of applications.
 namespace xwalk {
 namespace application_manifest_keys {
@@ -118,10 +119,7 @@ namespace application_manifest_errors {
 }  // namespace application_manifest_errors
 
 namespace application {
-
-typedef application::Manifest Manifest;
 const char* GetNameKey(Package::Type type);
-const char* GetLaunchLocalPathKey(Package::Type type);
 const char* GetCSPKey(Package::Type type);
 #if defined(OS_TIZEN)
 const char* GetTizenAppIdKey(Package::Type type);
index dde11b7..7119a57 100644 (file)
@@ -5,7 +5,6 @@
 #ifndef XWALK_APPLICATION_COMMON_APPLICATION_STORAGE_H_
 #define XWALK_APPLICATION_COMMON_APPLICATION_STORAGE_H_
 
-#include <map>
 #include <string>
 #include <vector>
 
index 4359f6c..5d9caa6 100644 (file)
@@ -148,7 +148,7 @@ bool ApplicationStorageImpl::UpgradeToVersion1(const base::FilePath& v0_file) {
     std::string error;
     scoped_refptr<ApplicationData> application =
         ApplicationData::Create(base::FilePath::FromUTF8Unsafe(path),
-                                Manifest::INTERNAL,
+                                ApplicationData::INTERNAL,
                                 *manifest,
                                 it.key(),
                                 &error);
@@ -250,7 +250,7 @@ scoped_refptr<ApplicationData> ApplicationStorageImpl::ExtractApplicationData(
   scoped_refptr<ApplicationData> app_data =
       ApplicationData::Create(
           base::FilePath::FromUTF8Unsafe(path),
-          Manifest::INTERNAL,
+          ApplicationData::INTERNAL,
           *manifest,
           id,
           &error);
index e195498..3fc541f 100644 (file)
@@ -53,7 +53,8 @@ scoped_refptr<ApplicationData> ApplicationStorageImpl::GetApplicationData(
   base::FilePath app_path = GetApplicationPath(app_id);
 
   std::string error_str;
-  return LoadApplication(app_path, app_id, Manifest::INTERNAL, &error_str);
+  return LoadApplication(
+      app_path, app_id, ApplicationData::INTERNAL, &error_str);
 }
 
 bool ApplicationStorageImpl::GetInstalledApplicationIDs(
index fd24522..563a582 100644 (file)
@@ -49,7 +49,7 @@ TEST_F(ApplicationStorageImplTest, DBInsert) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest,
       "",
       &error);
@@ -72,7 +72,7 @@ TEST_F(ApplicationStorageImplTest, DBDelete) {
   std::string error;
   scoped_refptr<ApplicationData> application =
       ApplicationData::Create(base::FilePath(),
-                              Manifest::INTERNAL,
+                              ApplicationData::INTERNAL,
                               manifest,
                               "",
                               &error);
@@ -127,7 +127,7 @@ TEST_F(ApplicationStorageImplTest, DBUpdate) {
   std::string error;
   scoped_refptr<ApplicationData> application =
       ApplicationData::Create(base::FilePath(),
-                              Manifest::INTERNAL,
+                              ApplicationData::INTERNAL,
                               manifest,
                               "",
                               &error);
@@ -139,7 +139,7 @@ TEST_F(ApplicationStorageImplTest, DBUpdate) {
   manifest.SetString("a", "c");
   scoped_refptr<ApplicationData> new_application =
       ApplicationData::Create(base::FilePath(),
-                              Manifest::INTERNAL,
+                              ApplicationData::INTERNAL,
                               manifest,
                               "",
                               &error);
@@ -167,7 +167,7 @@ TEST_F(ApplicationStorageImplTest, SetPermission) {
   std::string error;
   scoped_refptr<ApplicationData> application =
       ApplicationData::Create(base::FilePath(),
-                              Manifest::INTERNAL,
+                              ApplicationData::INTERNAL,
                               manifest,
                               "",
                               &error);
index 74ae842..c3fef0b 100644 (file)
@@ -17,9 +17,10 @@ namespace application {
 // We persist location values in the preferences, so this is a sanity test that
 // someone doesn't accidentally change them.
 TEST(ApplicationTest, LocationValuesTest) {
-  ASSERT_EQ(0, Manifest::INVALID_TYPE);
-  ASSERT_EQ(1, Manifest::INTERNAL);
-  ASSERT_EQ(2, Manifest::COMMAND_LINE);
+  ASSERT_EQ(0, ApplicationData::INTERNAL);
+  ASSERT_EQ(1, ApplicationData::LOCAL_DIRECTORY);
+  ASSERT_EQ(2, ApplicationData::TEMP_DIRECTORY);
+  ASSERT_EQ(3, ApplicationData::EXTERNAL_URL);
 }
 
 }  // namespace application
diff --git a/src/xwalk/application/common/installer/package_installer.h b/src/xwalk/application/common/installer/package_installer.h
deleted file mode 100644 (file)
index b32887d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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_APPLICATION_COMMON_INSTALLER_PACKAGE_INSTALLER_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_INSTALLER_H_
-
-#include <string>
-#include "base/files/file_path.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace xwalk {
-namespace application {
-
-class ApplicationData;
-class ApplicationStorage;
-
-class PackageInstaller {
- public:
-  static scoped_ptr<PackageInstaller> Create(ApplicationStorage* storage);
-
-  virtual ~PackageInstaller();
-
-  bool Install(const base::FilePath& path, std::string* id);
-  bool Uninstall(const std::string& id);
-  bool Update(const std::string& id, const base::FilePath& path);
-  void ContinueUnfinishedTasks();
-
-  virtual void SetQuiet(bool quiet);
-  virtual void SetInstallationKey(const std::string& key);
-
- protected:
-  explicit PackageInstaller(ApplicationStorage* storage);
-
-  virtual std::string PrepareUninstallationID(const std::string& id);
-
-  // Those to be overriden to implement platform specific logic.
-  virtual bool PlatformInstall(ApplicationData* data);
-  virtual bool PlatformUninstall(ApplicationData* data);
-  virtual bool PlatformUpdate(ApplicationData* updated_data);
-
-  ApplicationStorage* storage_;
-};
-
-}  // namespace application
-}  // namespace xwalk
-
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_INSTALLER_H_
diff --git a/src/xwalk/application/common/installer/package_installer_tizen.cc b/src/xwalk/application/common/installer/package_installer_tizen.cc
deleted file mode 100644 (file)
index 876074c..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-// 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/application/common/installer/package_installer_tizen.h"
-
-#include <sys/types.h>
-#include <pwd.h>
-#include <unistd.h>
-#include <pkgmgr/pkgmgr_parser.h>
-#include <algorithm>
-#include <map>
-#include <string>
-
-#include "base/file_util.h"
-#include "base/files/file_enumerator.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/path_service.h"
-#include "base/command_line.h"
-#include "base/process/launch.h"
-#include "third_party/libxml/chromium/libxml_utils.h"
-#include "xwalk/application/common/application_data.h"
-#include "xwalk/application/common/application_file_util.h"
-#include "xwalk/application/common/application_manifest_constants.h"
-#include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
-#include "xwalk/application/common/manifest_handlers/tizen_metadata_handler.h"
-#include "xwalk/application/common/application_storage.h"
-#include "xwalk/application/common/installer/tizen/packageinfo_constants.h"
-#include "xwalk/application/common/id_util.h"
-#include "xwalk/runtime/common/xwalk_paths.h"
-
-namespace info = xwalk::application_packageinfo_constants;
-
-namespace {
-
-namespace widget_keys = xwalk::application_widget_keys;
-
-const base::FilePath kPkgHelper("/usr/bin/xwalk-pkg-helper");
-
-const base::FilePath kXWalkLauncherBinary("/usr/bin/xwalk-launcher");
-
-const base::FilePath kDefaultIcon(
-    "/usr/share/icons/default/small/crosswalk.png");
-
-const std::string kServicePrefix("xwalk-service.");
-const std::string kAppIdPrefix("xwalk.");
-
-void WriteMetaDataElement(
-    XmlWriter& writer, // NOLINT
-    xwalk::application::TizenMetaDataInfo* info) {
-  if (!info)
-    return;
-
-  const std::map<std::string, std::string>& metadata = info->metadata();
-  std::map<std::string, std::string>::const_iterator it;
-  for (it = metadata.begin(); it != metadata.end(); ++it) {
-    writer.StartElement("metadata");
-    writer.AddAttribute("key", it->first);
-    writer.AddAttribute("value", it->second);
-    writer.EndElement();
-  }
-}
-
-bool GeneratePkgInfoXml(xwalk::application::ApplicationData* application,
-                        const std::string& icon_name,
-                        const base::FilePath& app_dir,
-                        const base::FilePath& xml_path) {
-  if (!base::PathExists(app_dir) &&
-      !base::CreateDirectory(app_dir))
-    return false;
-
-  std::string package_id =
-      xwalk::application::AppIdToPkgId(application->ID());
-
-  base::FilePath execute_path =
-      app_dir.AppendASCII("bin/").AppendASCII(application->ID());
-  std::string stripped_name = application->Name();
-
-  FILE* file = base::OpenFile(xml_path, "w");
-
-  XmlWriter xml_writer;
-  xml_writer.StartWriting();
-  xml_writer.StartElement("manifest");
-  xml_writer.AddAttribute("xmlns", "http://tizen.org/ns/packages");
-  xml_writer.AddAttribute("package", package_id);
-  xml_writer.AddAttribute("type", "wgt");
-  xml_writer.AddAttribute("version", application->VersionString());
-  xml_writer.WriteElement("label", application->Name());
-  xml_writer.WriteElement("description", application->Description());
-
-  xml_writer.StartElement("ui-application");
-  xml_writer.AddAttribute("appid", application->ID());
-  xml_writer.AddAttribute("exec", execute_path.MaybeAsASCII());
-  xml_writer.AddAttribute("type", "webapp");
-  xml_writer.AddAttribute("taskmanage", "true");
-  xml_writer.WriteElement("label", application->Name());
-
-  xwalk::application::TizenMetaDataInfo* info =
-      static_cast<xwalk::application::TizenMetaDataInfo*>(
-      application->GetManifestData(widget_keys::kTizenMetaDataKey));
-  WriteMetaDataElement(xml_writer, info);
-
-  if (icon_name.empty())
-    xml_writer.WriteElement("icon", info::kDefaultIconName);
-  else
-    xml_writer.WriteElement("icon",
-                            kServicePrefix + application->ID() + ".png");
-  xml_writer.EndElement();  // Ends "ui-application"
-
-  xml_writer.EndElement();  // Ends "manifest" element.
-  xml_writer.StopWriting();
-
-  base::WriteFile(xml_path,
-                  xml_writer.GetWrittenString().c_str(),
-                  xml_writer.GetWrittenString().size());
-
-  base::CloseFile(file);
-  LOG(INFO) << "Converting manifest.json into "
-            << xml_path.BaseName().MaybeAsASCII()
-            << " for installation. [DONE]";
-  return true;
-}
-
-bool CreateAppSymbolicLink(const base::FilePath& app_dir,
-                           const std::string& app_id) {
-  base::FilePath execute_path =
-      app_dir.AppendASCII("bin/").AppendASCII(app_id);
-
-  if (!base::CreateDirectory(execute_path.DirName())) {
-    LOG(ERROR) << "Could not create directory '"
-               << execute_path.DirName().value() << "'.";
-    return false;
-  }
-
-  if (!base::CreateSymbolicLink(kXWalkLauncherBinary, execute_path)) {
-    LOG(ERROR) << "Could not create symbolic link to launcher from '"
-               << execute_path.value() << "'.";
-    return false;
-  }
-  return true;
-}
-
-}  // namespace
-
-namespace xwalk {
-namespace application {
-
-PackageInstallerTizen::PackageInstallerTizen(ApplicationStorage* storage)
-    : PackageInstaller(storage) {
-}
-
-void PackageInstallerTizen::SetQuiet(bool quiet) {
-  quiet_ = quiet;
-}
-
-void PackageInstallerTizen::SetInstallationKey(const std::string& key) {
-  key_ = key;
-}
-
-std::string PackageInstallerTizen::PrepareUninstallationID(
-    const std::string& id) {
-  // this function fix pkg_id to app_id
-  // if installer was launched with pkg_id
-  if (IsValidPkgID(id)) {
-    LOG(INFO) << "The package id is given " << id << " Will find app_id...";
-    std::string appid = PkgIdToAppId(id);
-    if (!appid.empty())
-      return appid;
-  }
-  return id;
-}
-
-bool PackageInstallerTizen::PlatformInstall(ApplicationData* app_data) {
-  std::string app_id(app_data->ID());
-  base::FilePath data_dir;
-  CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &data_dir));
-
-  base::FilePath app_dir =
-      data_dir.AppendASCII(info::kAppDir).AppendASCII(app_id);
-  base::FilePath xml_path = data_dir.AppendASCII(info::kAppDir).AppendASCII(
-      app_id + std::string(info::kXmlExtension));
-
-  std::string icon_name;
-  if (!app_data->GetManifest()->GetString(
-      GetIcon128Key(app_data->GetPackageType()), &icon_name))
-    LOG(WARNING) << "'icon' not included in manifest";
-
-  // This will clean everything inside '<data dir>/<app id>'.
-  FileDeleter app_dir_cleaner(app_dir, true);
-
-  if (!GeneratePkgInfoXml(app_data, icon_name, app_dir, xml_path)) {
-    LOG(ERROR) << "Failed to create XML metadata file '"
-               << xml_path.value() << "'.";
-    return false;
-  }
-
-  if (!CreateAppSymbolicLink(app_dir, app_id)) {
-    LOG(ERROR) << "Failed to create symbolic link for " << app_id;
-    return false;
-  }
-
-  base::FilePath icon =
-      icon_name.empty() ? kDefaultIcon : app_dir.AppendASCII(icon_name);
-
-  CommandLine cmdline(kPkgHelper);
-  cmdline.AppendSwitchASCII("--install", app_id);
-  cmdline.AppendSwitchPath("--xml", xml_path);
-  cmdline.AppendSwitchPath("--icon", icon);
-  if (quiet_)
-    cmdline.AppendSwitch("-q");
-  if (!key_.empty()) {
-    cmdline.AppendSwitchASCII("--key", key_);
-  }
-
-  int exit_code;
-  std::string output;
-
-  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
-    LOG(ERROR) << "Could not launch the installation helper process.";
-    return false;
-  }
-
-  if (exit_code != 0) {
-    LOG(ERROR) << "Could not install application: "
-               << output << " (" << exit_code << ")";
-    return false;
-  }
-
-  app_dir_cleaner.Dismiss();
-
-  return true;
-}
-
-bool PackageInstallerTizen::PlatformUninstall(ApplicationData* app_data) {
-  bool result = true;
-  std::string app_id(app_data->ID());
-  base::FilePath data_dir;
-  CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &data_dir));
-
-  CommandLine cmdline(kPkgHelper);
-  cmdline.AppendSwitchASCII("--uninstall", app_id);
-  if (quiet_)
-    cmdline.AppendSwitch("-q");
-  if (!key_.empty()) {
-    cmdline.AppendSwitchASCII("--key", key_);
-  }
-
-  int exit_code;
-  std::string output;
-
-  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
-    LOG(ERROR) << "Could not launch installer helper";
-    result = false;
-  }
-
-  if (exit_code != 0) {
-    LOG(ERROR) << "Could not uninstall application: "
-               << output << " (" << exit_code << ")";
-    result = false;
-  }
-
-  base::FilePath app_dir =
-      data_dir.AppendASCII(info::kAppDir).AppendASCII(app_id);
-  if (!base::DeleteFile(app_dir, true)) {
-    LOG(ERROR) << "Could not remove directory '" << app_dir.value() << "'";
-    result = false;
-  }
-
-  base::FilePath xml_path = data_dir.AppendASCII(
-      app_id + std::string(info::kXmlExtension));
-  if (!base::DeleteFile(xml_path, false)) {
-    LOG(ERROR) << "Could not remove file '" << xml_path.value() << "'";
-    result = false;
-  }
-
-  return result;
-}
-
-bool PackageInstallerTizen::PlatformUpdate(ApplicationData* app_data) {
-  std::string app_id(app_data->ID());
-  base::FilePath data_dir;
-  CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &data_dir));
-
-  base::FilePath app_dir =
-      data_dir.AppendASCII(info::kAppDir).AppendASCII(app_id);
-  base::FilePath new_xml_path = data_dir.AppendASCII(info::kAppDir).AppendASCII(
-      app_id + ".new" + std::string(info::kXmlExtension));
-
-  std::string icon_name;
-  if (!app_data->GetManifest()->GetString(
-      GetIcon128Key(app_data->GetPackageType()), &icon_name))
-    LOG(WARNING) << "'icon' not included in manifest";
-
-  // This will clean everything inside '<data dir>/<app id>' and the new XML.
-  FileDeleter app_dir_cleaner(app_dir, true);
-  FileDeleter new_xml_cleaner(new_xml_path, true);
-
-  if (!GeneratePkgInfoXml(app_data, icon_name, app_dir, new_xml_path)) {
-    LOG(ERROR) << "Could not create new XML metadata file '"
-               << new_xml_path.value() << "'.";
-    return false;
-  }
-
-  if (!CreateAppSymbolicLink(app_dir, app_id))
-    return false;
-
-  base::FilePath icon =
-      icon_name.empty() ? kDefaultIcon : app_dir.AppendASCII(icon_name);
-
-  CommandLine cmdline(kPkgHelper);
-  cmdline.AppendSwitchASCII("--update", app_id);
-  cmdline.AppendSwitchPath("--xml", new_xml_path);
-  cmdline.AppendSwitchPath("--icon", icon);
-  if (quiet_)
-    cmdline.AppendSwitch("-q");
-  if (!key_.empty()) {
-    cmdline.AppendSwitchASCII("--key", key_);
-  }
-
-  int exit_code;
-  std::string output;
-
-  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
-    LOG(ERROR) << "Could not launch installer helper";
-    return false;
-  }
-
-  if (exit_code != 0) {
-    LOG(ERROR) << "Could not update application: "
-               << output << " (" << exit_code << ")";
-    return false;
-  }
-
-  base::FilePath old_xml_path = data_dir.AppendASCII(info::kAppDir).AppendASCII(
-      app_id + std::string(info::kXmlExtension));
-  base::Move(new_xml_path, old_xml_path);
-  app_dir_cleaner.Dismiss();
-  return true;
-}
-
-}  // namespace application
-}  // namespace xwalk
diff --git a/src/xwalk/application/common/installer/package_installer_tizen.h b/src/xwalk/application/common/installer/package_installer_tizen.h
deleted file mode 100644 (file)
index 356d97b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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_APPLICATION_COMMON_INSTALLER_PACKAGE_INSTALLER_TIZEN_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_INSTALLER_TIZEN_H_
-
-#include <string>
-
-#include "xwalk/application/common/installer/package_installer.h"
-
-namespace xwalk {
-namespace application {
-
-class PackageInstallerTizen : public PackageInstaller {
- public:
-  explicit PackageInstallerTizen(ApplicationStorage* storage);
-
-  void SetQuiet(bool quiet) OVERRIDE;
-  void SetInstallationKey(const std::string& key) OVERRIDE;
-
- protected:
-  std::string PrepareUninstallationID(const std::string& id) OVERRIDE;
-
-  virtual bool PlatformInstall(ApplicationData* data) OVERRIDE;
-  virtual bool PlatformUninstall(ApplicationData* data) OVERRIDE;
-  virtual bool PlatformUpdate(ApplicationData* data) OVERRIDE;
-
- private:
-  bool quiet_;
-  std::string key_;
-};
-
-}  // namespace application
-}  // namespace xwalk
-
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_INSTALLER_TIZEN_H_
index 5feaeaf..7efe82e 100644 (file)
@@ -63,10 +63,8 @@ scoped_ptr<List> ExpandUserAgentLocalesList(const scoped_ptr<List>& list) {
 
 }  // namespace
 
-Manifest::Manifest(SourceType source_type,
-        scoped_ptr<base::DictionaryValue> value)
-    : source_type_(source_type),
-      data_(value.Pass()),
+Manifest::Manifest(scoped_ptr<base::DictionaryValue> value)
+    : data_(value.Pass()),
       i18n_data_(new base::DictionaryValue),
       type_(TYPE_UNKNOWN) {
   // FIXME: Hosted apps can contain start_url. Below is wrong.
@@ -183,7 +181,7 @@ bool Manifest::GetList(
 
 Manifest* Manifest::DeepCopy() const {
   Manifest* manifest = new Manifest(
-      source_type_, scoped_ptr<base::DictionaryValue>(data_->DeepCopy()));
+      scoped_ptr<base::DictionaryValue>(data_->DeepCopy()));
   manifest->SetApplicationID(application_id_);
   return manifest;
 }
index c129f8c..3485ef0 100644 (file)
@@ -14,7 +14,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "base/values.h"
-#include "xwalk/application/common/installer/package.h"
 
 namespace xwalk {
 namespace application {
@@ -23,28 +22,18 @@ namespace application {
 // properties of the manifest using ManifestFeatureProvider.
 class Manifest {
  public:
-  // Where an application was loaded from.
-  enum SourceType {
-    INVALID_TYPE,
-    INTERNAL,           // Load from internal application registry.
-    COMMAND_LINE,       // Load from an unpacked application from command line.
-    NUM_TYPES
-  };
-
   enum Type {
     TYPE_UNKNOWN = 0,
     TYPE_HOSTED_APP,
     TYPE_PACKAGED_APP
   };
 
-  Manifest(SourceType source_type, scoped_ptr<base::DictionaryValue> value);
+  explicit Manifest(scoped_ptr<base::DictionaryValue> value);
   ~Manifest();
 
   const std::string& GetApplicationID() const { return application_id_; }
   void SetApplicationID(const std::string& id) { application_id_ = id; }
 
-  SourceType GetSourceType() const { return source_type_; }
-
   // Returns false and |error| will be non-empty if the manifest is malformed.
   // |warnings| will be populated if there are keys in the manifest that cannot
   // be specified by the application type.
@@ -111,8 +100,7 @@ class Manifest {
 
   // A persistent, globally unique ID. An application's ID is used in things
   // like directory structures and URLs, and is expected to not change across
-  // versions. It is generated as a SHA-256 hash of the application's public
-  // key, or as a hash of the path in the case of unpacked applications.
+  // versions.
   std::string application_id_;
 
 #if defined(OS_TIZEN)
@@ -120,9 +108,6 @@ class Manifest {
   std::string package_id_;
 #endif
 
-  // The source the application was loaded from.
-  SourceType source_type_;
-
   // The underlying dictionary representation of the manifest.
   scoped_ptr<base::DictionaryValue> data_;
   scoped_ptr<base::DictionaryValue> i18n_data_;
index 405fb01..f232b84 100644 (file)
@@ -220,7 +220,7 @@ TEST_F(ManifestHandlerTest, DependentHandlers) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest,
       "",
       &error);
@@ -248,7 +248,7 @@ TEST_F(ManifestHandlerTest, FailingHandlers) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest_a,
       "",
       &error);
@@ -265,7 +265,7 @@ TEST_F(ManifestHandlerTest, FailingHandlers) {
 
   application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest_a,
       "",
       &error);
@@ -286,7 +286,7 @@ TEST_F(ManifestHandlerTest, Validate) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::COMMAND_LINE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest,
       "",
       &error);
index 19dac08..e6e21e1 100644 (file)
@@ -19,7 +19,8 @@ class CSPHandlerTest: public testing::Test {
   scoped_refptr<ApplicationData> CreateApplication() {
     std::string error;
     scoped_refptr<ApplicationData> application = ApplicationData::Create(
-        base::FilePath(), Manifest::INVALID_TYPE, manifest, "", &error);
+        base::FilePath(), ApplicationData::LOCAL_DIRECTORY,
+        manifest, "", &error);
     return application;
   }
 
index a4d4b4d..2b68ee2 100644 (file)
@@ -25,7 +25,8 @@ class NavigationHandlerTest: public testing::Test {
   scoped_refptr<ApplicationData> CreateApplication() {
     std::string error;
     scoped_refptr<ApplicationData> application = ApplicationData::Create(
-        base::FilePath(), Manifest::INVALID_TYPE, manifest, "", &error);
+        base::FilePath(), ApplicationData::LOCAL_DIRECTORY,
+        manifest, "", &error);
     return application;
   }
 
index d942635..8773131 100644 (file)
@@ -35,7 +35,7 @@ TEST_F(PermissionsHandlerTest, NonePermission) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest,
       "",
       &error);
@@ -52,7 +52,7 @@ TEST_F(PermissionsHandlerTest, EmptyPermission) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest,
       "",
       &error);
@@ -70,7 +70,7 @@ TEST_F(PermissionsHandlerTest, DeviceAPIPermission) {
   std::string error;
   scoped_refptr<ApplicationData> application = ApplicationData::Create(
       base::FilePath(),
-      Manifest::INVALID_TYPE,
+      ApplicationData::LOCAL_DIRECTORY,
       manifest,
       "",
       &error);
index cc6c2dd..83ae8bd 100644 (file)
@@ -23,7 +23,8 @@ class WARPHandlerTest: public testing::Test {
   scoped_refptr<ApplicationData> CreateApplication() {
     std::string error;
     scoped_refptr<ApplicationData> application = ApplicationData::Create(
-        base::FilePath(), Manifest::INVALID_TYPE, manifest, "", &error);
+        base::FilePath(), ApplicationData::LOCAL_DIRECTORY,
+        manifest, "", &error);
     return application;
   }
 
index 17ab4aa..0025074 100644 (file)
@@ -52,10 +52,11 @@ const char* preferencesReadonly[] = {"true", "false", "false"};
 class WidgetHandlerTest: public testing::Test {
  public:
   scoped_refptr<ApplicationData> CreateApplication(
-    base::DictionaryValue &manifest) {
+    const base::DictionaryValue& manifest) {
     std::string error;
     scoped_refptr<ApplicationData> application = ApplicationData::Create(
-        base::FilePath(), Manifest::INVALID_TYPE, manifest, "", &error);
+        base::FilePath(), ApplicationData::LOCAL_DIRECTORY,
+        manifest, "", &error);
     return application;
   }
 
index 95781b7..5973f78 100644 (file)
@@ -45,8 +45,7 @@ class ManifestTest : public testing::Test {
       manifest_value->Set(key, value);
     else
       manifest_value->Remove(key, NULL);
-    manifest->reset(new Manifest(Manifest::COMMAND_LINE,
-            manifest_value.Pass()));
+    manifest->reset(new Manifest(manifest_value.Pass()));
   }
 
   std::string default_value_;
@@ -60,7 +59,7 @@ TEST_F(ManifestTest, ApplicationData) {
   manifest_value->SetString("unknown_key", "foo");
 
   scoped_ptr<Manifest> manifest(
-      new Manifest(Manifest::COMMAND_LINE, manifest_value.Pass()));
+      new Manifest(manifest_value.Pass()));
   std::string error;
   EXPECT_TRUE(manifest->ValidateManifest(&error));
   EXPECT_TRUE(error.empty());
@@ -88,7 +87,7 @@ TEST_F(ManifestTest, ApplicationTypes) {
   value->SetString(keys::kXWalkVersionKey, "1");
 
   scoped_ptr<Manifest> manifest(
-      new Manifest(Manifest::COMMAND_LINE, value.Pass()));
+      new Manifest(value.Pass()));
   std::string error;
   EXPECT_TRUE(manifest->ValidateManifest(&error));
   EXPECT_TRUE(error.empty());
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/package.h"
+#include "xwalk/application/common/package/package.h"
 
 #include "base/file_util.h"
 #include "base/files/file_path.h"
@@ -10,8 +10,8 @@
 #include "base/path_service.h"
 #include "third_party/zlib/google/zip.h"
 #include "xwalk/application/common/id_util.h"
-#include "xwalk/application/common/installer/wgt_package.h"
-#include "xwalk/application/common/installer/xpk_package.h"
+#include "xwalk/application/common/package/wgt_package.h"
+#include "xwalk/application/common/package/xpk_package.h"
 
 namespace xwalk {
 namespace application {
@@ -19,7 +19,8 @@ namespace application {
 Package::Package(const base::FilePath& source_path)
     : source_path_(source_path),
       is_extracted_(false),
-      is_valid_(false) {
+      is_valid_(false),
+      name_(source_path_.BaseName().AsUTF8Unsafe()) {
 }
 
 Package::~Package() {
@@ -28,20 +29,19 @@ Package::~Package() {
 // static
 scoped_ptr<Package> Package::Create(const base::FilePath& source_path) {
   if (source_path.MatchesExtension(FILE_PATH_LITERAL(".xpk"))) {
-      scoped_ptr<Package> package(new XPKPackage(source_path));
-      if (!package->IsValid())
-        LOG(ERROR) << "Package not valid";
-      return package.Pass();
-  } else if (source_path.MatchesExtension(FILE_PATH_LITERAL(".wgt"))) {
-     scoped_ptr<Package> package(new WGTPackage(source_path));
-     return package.Pass();
+    scoped_ptr<Package> package(new XPKPackage(source_path));
+    return package.Pass();
+  }
+  if (source_path.MatchesExtension(FILE_PATH_LITERAL(".wgt"))) {
+    scoped_ptr<Package> package(new WGTPackage(source_path));
+    return package.Pass();
   }
 
   LOG(ERROR) << "Invalid package type. Only .xpk/.wgt supported now";
   return scoped_ptr<Package>();
 }
 
-bool Package::Extract(base::FilePath* target_path) {
+bool Package::ExtractToTemporaryDir(base::FilePath* target_path) {
   if (is_extracted_) {
     *target_path = temp_dir_.path();
     return true;
@@ -64,6 +64,25 @@ bool Package::Extract(base::FilePath* target_path) {
   return true;
 }
 
+bool Package::ExtractTo(const base::FilePath& target_path) {
+  if (!DirectoryExists(target_path)) {
+    LOG(ERROR) << "The directory " << target_path.MaybeAsASCII()
+               << "does not exist";
+    return false;
+  }
+  if (!IsDirectoryEmpty(target_path)) {
+    LOG(ERROR) << "The directory " << target_path.MaybeAsASCII()
+               << "is not empty.";
+    return false;
+  }
+  if (!zip::Unzip(source_path_, target_path)) {
+    LOG(ERROR) << "An error occurred during package extraction";
+    return false;
+  }
+
+  return true;
+}
+
 // Create a temporary directory to decompress the zipped package file.
 // As the package information might already exists under data_path,
 // it's safer to extract the XPK/WGT file into a temporary directory first.
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_H_
+#ifndef XWALK_APPLICATION_COMMON_PACKAGE_PACKAGE_H_
+#define XWALK_APPLICATION_COMMON_PACKAGE_PACKAGE_H_
 
 #include <string>
 #include <vector>
@@ -30,21 +30,26 @@ class Package {
   virtual ~Package();
   bool IsValid() const { return is_valid_; }
   const std::string& Id() const { return id_; }
+  const std::string& name() const { return name_; }
   Type type() const { return type_; }
   // Factory method for creating a package
   static scoped_ptr<Package> Create(const base::FilePath& path);
   // The function will unzip the XPK/WGT file and return the target path where
   // to decompress by the parameter |target_path|.
-  virtual bool Extract(base::FilePath* target_path);
+  virtual bool ExtractToTemporaryDir(base::FilePath* result_path);
+  // The function will unzip the XPK/WGT file to the given folder.
+  virtual bool ExtractTo(const base::FilePath& target_path);
 
  protected:
   explicit Package(const base::FilePath& source_path);
-  scoped_ptr<base::ScopedFILE> file_;
-  bool is_valid_;
-  std::string id_;
   // Unzipping of the zipped file happens in a temporary directory
   bool CreateTempDirectory();
+  scoped_ptr<base::ScopedFILE> file_;
+
+  bool is_valid_;
   base::FilePath source_path_;
+  std::string id_;
+  std::string name_;
   // Temporary directory for unpacking.
   base::ScopedTempDir temp_dir_;
   // Represent if the package has been extracted.
@@ -55,4 +60,4 @@ class Package {
 }  // namespace application
 }  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_PACKAGE_H_
+#endif  // XWALK_APPLICATION_COMMON_PACKAGE_PACKAGE_H_
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/package.h"
+#include "xwalk/application/common/package/package.h"
 
 #include "base/file_util.h"
 #include "base/files/scoped_temp_dir.h"
@@ -37,7 +37,7 @@ TEST_F(PackageTest, Good) {
   SetupPackage("good.xpk");
   EXPECT_FALSE(package_->Id().empty());
   base::FilePath path;
-  EXPECT_TRUE(package_->Extract(&path));
+  EXPECT_TRUE(package_->ExtractToTemporaryDir(&path));
   EXPECT_TRUE(base::DirectoryExists(path));
   EXPECT_TRUE(temp_dir_.Set(path));
 }
@@ -45,19 +45,19 @@ TEST_F(PackageTest, Good) {
 TEST_F(PackageTest, BadMagicString) {
   SetupPackage("bad_magic.xpk");
   base::FilePath path;
-  EXPECT_FALSE(package_->Extract(&path));
+  EXPECT_FALSE(package_->ExtractToTemporaryDir(&path));
 }
 
 TEST_F(PackageTest, BadSignature) {
   SetupPackage("bad_signature.xpk");
   base::FilePath path;
-  EXPECT_FALSE(package_->Extract(&path));
+  EXPECT_FALSE(package_->ExtractToTemporaryDir(&path));
 }
 
 TEST_F(PackageTest, NoMagicHeader) {
   SetupPackage("no_magic_header.xpk");
   base::FilePath path;
-  EXPECT_FALSE(package_->Extract(&path));
+  EXPECT_FALSE(package_->ExtractToTemporaryDir(&path));
 }
 
 TEST_F(PackageTest, BadXPKPackageExtension) {
@@ -69,7 +69,7 @@ TEST_F(PackageTest, BadXPKPackageExtension) {
 TEST_F(PackageTest, BadUnzipFile) {
   SetupPackage("bad_zip.xpk");
   base::FilePath path;
-  EXPECT_FALSE(package_->Extract(&path));
+  EXPECT_FALSE(package_->ExtractToTemporaryDir(&path));
 }
 
 }  // namespace application
@@ -2,13 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/wgt_package.h"
+#include "xwalk/application/common/package/wgt_package.h"
 
 #include "base/file_util.h"
 #include "base/files/scoped_file.h"
 #include "third_party/libxml/chromium/libxml_utils.h"
 #include "xwalk/application/common/id_util.h"
-#include "xwalk/application/common/installer/tizen/signature_validator.h"
+
+#if defined(OS_TIZEN)
+#include "xwalk/application/common/tizen/signature_validator.h"
+#endif
 
 namespace xwalk {
 namespace application {
@@ -29,7 +32,8 @@ WGTPackage::WGTPackage(const base::FilePath& path)
     return;
   type_ = WGT;
   base::FilePath extracted_path;
-  if (!Extract(&extracted_path))
+  // FIXME : we should not call 'extract' here!
+  if (!ExtractToTemporaryDir(&extracted_path))
     return;
 
   XmlReader xml;
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_WGT_PACKAGE_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_WGT_PACKAGE_H_
+#ifndef XWALK_APPLICATION_COMMON_PACKAGE_WGT_PACKAGE_H_
+#define XWALK_APPLICATION_COMMON_PACKAGE_WGT_PACKAGE_H_
 
 #include <string>
 #include <vector>
 
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
-#include "xwalk/application/common/installer/package.h"
+#include "xwalk/application/common/package/package.h"
 
 namespace xwalk {
 namespace application {
@@ -24,4 +24,4 @@ class WGTPackage : public Package {
 }  // namespace application
 }  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_WGT_PACKAGE_H_
+#endif  // XWALK_APPLICATION_COMMON_PACKAGE_WGT_PACKAGE_H_
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/xpk_package.h"
+#include "xwalk/application/common/package/xpk_package.h"
 
 #include "base/file_util.h"
 #include "base/files/scoped_file.h"
@@ -65,7 +65,6 @@ XPKPackage::XPKPackage(const base::FilePath& path)
             std::string(reinterpret_cast<char*>(&key_.front()), key_.size());
         id_ = GenerateId(public_key);
   }
-  return;
 }
 
 bool XPKPackage::VerifySignature() {
@@ -90,7 +89,7 @@ bool XPKPackage::VerifySignature() {
   return true;
 }
 
-bool XPKPackage::Extract(base::FilePath* target_path) {
+bool XPKPackage::ExtractToTemporaryDir(base::FilePath* target_path) {
   if (is_extracted_) {
     *target_path = temp_dir_.path();
     return true;
@@ -101,7 +100,7 @@ bool XPKPackage::Extract(base::FilePath* target_path) {
     return false;
   }
 
-  return Package::Extract(target_path);
+  return Package::ExtractToTemporaryDir(target_path);
 }
 
 }  // namespace application
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_XPK_PACKAGE_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_XPK_PACKAGE_H_
+#ifndef XWALK_APPLICATION_COMMON_PACKAGE_XPK_PACKAGE_H_
+#define XWALK_APPLICATION_COMMON_PACKAGE_XPK_PACKAGE_H_
 
 #include <string>
 #include <vector>
 
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
-#include "xwalk/application/common/installer/package.h"
+#include "xwalk/application/common/package/package.h"
 
 namespace xwalk {
 namespace application {
@@ -29,7 +29,7 @@ class XPKPackage : public Package {
   };
   virtual ~XPKPackage();
   explicit XPKPackage(const base::FilePath& path);
-  virtual bool Extract(base::FilePath* target_path) OVERRIDE;
+  virtual bool ExtractToTemporaryDir(base::FilePath* target_path) OVERRIDE;
 
  private:
   // verify the signature in the xpk package
@@ -45,4 +45,4 @@ class XPKPackage : public Package {
 }  // namespace application
 }  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_XPK_PACKAGE_H_
+#endif  // XWALK_APPLICATION_COMMON_PACKAGE_XPK_PACKAGE_H_
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/signature_data.h"
+#include "xwalk/application/common/tizen/signature_data.h"
 
 #include "base/strings/utf_string_conversions.h"
 
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_SIGNATURE_DATA_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_SIGNATURE_DATA_H_
+#ifndef XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_DATA_H_
+#define XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_DATA_H_
 
 #include <list>
 #include <set>
@@ -117,4 +117,4 @@ class SignatureData {
 }  // namespace application
 }  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_SIGNATURE_DATA_H_
+#endif  // XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_DATA_H_
@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/signature_parser.h"
+#include "xwalk/application/common/tizen/signature_parser.h"
 
 #include <list>
 #include <set>
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_SIGNATURE_PARSER_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_SIGNATURE_PARSER_H_
+#ifndef XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_PARSER_H_
+#define XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_PARSER_H_
 
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
-#include "xwalk/application/common/installer/signature_data.h"
+#include "xwalk/application/common/tizen/signature_data.h"
 
 namespace xwalk {
 namespace application {
@@ -24,4 +24,4 @@ class SignatureParser {
 }  // namespace application
 }  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_SIGNATURE_PARSER_H_
+#endif  // XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_PARSER_H_
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/tizen/signature_validator.h"
+#include "xwalk/application/common/tizen/signature_validator.h"
 
 #include <set>
 #include <string>
@@ -13,8 +13,8 @@
 #include "libxml/parser.h"
 #include "libxml/xmlschemas.h"
 #include "third_party/re2/re2/re2.h"
-#include "xwalk/application/common/installer/signature_data.h"
-#include "xwalk/application/common/installer/signature_parser.h"
+#include "xwalk/application/common/tizen/signature_data.h"
+#include "xwalk/application/common/tizen/signature_parser.h"
 
 namespace {
 
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_TIZEN_SIGNATURE_VALIDATOR_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_TIZEN_SIGNATURE_VALIDATOR_H_
+#ifndef XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_VALIDATOR_H_
+#define XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_VALIDATOR_H_
 
 #include "base/files/file_path.h"
 
@@ -27,4 +27,4 @@ class SignatureValidator {
 }  // namespace application
 }  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_TIZEN_SIGNATURE_VALIDATOR_H_
+#endif  // XWALK_APPLICATION_COMMON_TIZEN_SIGNATURE_VALIDATOR_H_
index 577515b..d422122 100644 (file)
         'permission_policy_manager.h',
         'permission_types.h',
         'signature_types.h',
-
-        'installer/package.h',
-        'installer/package.cc',
-        'installer/package_installer.cc',
-        'installer/package_installer.h',
-        'installer/signature_data.h',
-        'installer/signature_data.cc',
-        'installer/signature_parser.h',
-        'installer/signature_parser.cc',
-        'installer/wgt_package.h',
-        'installer/wgt_package.cc',
-        'installer/xpk_package.cc',
-        'installer/xpk_package.h',
+        'package/package.h',
+        'package/package.cc',
+        'package/wgt_package.h',
+        'package/wgt_package.cc',
+        'package/xpk_package.cc',
+        'package/xpk_package.h',
       ],
       'conditions': [
         ['tizen==1', {
             'manifest_handlers/tizen_setting_handler.h',
             'manifest_handlers/tizen_splash_screen_handler.cc',
             'manifest_handlers/tizen_splash_screen_handler.h',
-            'installer/package_installer_tizen.cc',
-            'installer/package_installer_tizen.h',
-            'installer/tizen/packageinfo_constants.cc',
-            'installer/tizen/packageinfo_constants.h',
-            'installer/tizen/signature_validator.cc',
-            'installer/tizen/signature_validator.h',
             'tizen/package_path.cc',
             'tizen/package_path.h',
+            'tizen/signature_data.h',
+            'tizen/signature_data.cc',
+            'tizen/signature_parser.h',
+            'tizen/signature_parser.cc',
+            'tizen/signature_validator.cc',
+            'tizen/signature_validator.h',
+
           ],
         }, {
         'sources': [
index a6769a7..b6dbff0 100644 (file)
@@ -59,7 +59,7 @@ void ApplicationBrowserTest::CreateExtensions(
 }
 
 IN_PROC_BROWSER_TEST_F(ApplicationBrowserTest, ApiTest) {
-  Application* app = application_sevice()->Launch(
+  Application* app = application_sevice()->LaunchFromUnpackedPath(
       test_data_dir_.Append(FILE_PATH_LITERAL("api")));
   ASSERT_TRUE(app);
   test_runner_->WaitForTestNotification();
index cbbe34e..b7aebb0 100644 (file)
@@ -22,7 +22,7 @@ IN_PROC_BROWSER_TEST_F(ApplicationMultiAppTest, TestMultiApp) {
   ApplicationService* service = application_sevice();
   const size_t currently_running_count = service->active_applications().size();
   // Launch the first app.
-  Application* app1 = service->Launch(
+  Application* app1 = service->LaunchFromUnpackedPath(
       test_data_dir_.Append(FILE_PATH_LITERAL("dummy_app1")));
   ASSERT_TRUE(app1);
   // Wait for app is fully loaded.
@@ -36,12 +36,12 @@ IN_PROC_BROWSER_TEST_F(ApplicationMultiAppTest, TestMultiApp) {
 
   // Verify that no new App instance was created, if one exists
   // with the same ID.
-  Application* failed_app1 = service->Launch(
+  Application* failed_app1 = service->LaunchFromUnpackedPath(
       test_data_dir_.Append(FILE_PATH_LITERAL("dummy_app1")));
   ASSERT_FALSE(failed_app1);
 
   // Launch the second app.
-  Application* app2 = service->Launch(
+  Application* app2 = service->LaunchFromUnpackedPath(
       test_data_dir_.Append(FILE_PATH_LITERAL("dummy_app2")));
   ASSERT_TRUE(app2);
   // Wait for app is fully loaded.
index 55ec987..dbb5db8 100644 (file)
@@ -13,7 +13,7 @@ class ApplicationTestApiTest : public ApplicationBrowserTest {
 };
 
 IN_PROC_BROWSER_TEST_F(ApplicationTestApiTest, TestApiTest) {
-  Application* app = application_sevice()->Launch(
+  Application* app = application_sevice()->LaunchFromUnpackedPath(
       test_data_dir_.Append(FILE_PATH_LITERAL("testapi")));
   ASSERT_TRUE(app);
   test_runner_->WaitForTestNotification();
index 6845ee3..3cba1aa 100644 (file)
@@ -1,40 +1,5 @@
 {
-  'targets': [
-    {
-      'target_name': 'xwalkctl',
-      'type': 'executable',
-      'product_name': 'xwalkctl',
-      'dependencies': [
-        '../../../application/common/xwalk_application_common.gypi:xwalk_application_common_lib',
-        '../../../build/system.gyp:gio',
-        '../../../../build/linux/system.gyp:dbus',
-        '../../../../dbus/dbus.gyp:dbus',
-      ],
-      'include_dirs': [
-        '../../../..',
-      ],
-      'sources': [
-        'dbus_connection.cc',
-        'dbus_connection.h',
-        'xwalkctl_main.cc',
-        # TODO(t.iwanek) fix me - this duplicates compilation of those files
-        '../../../runtime/common/xwalk_paths.cc',
-        '../../../runtime/common/xwalk_paths.h',
-        '../../../runtime/common/xwalk_system_locale.cc',
-        '../../../runtime/common/xwalk_system_locale.h',
-      ],
-      'conditions' : [
-        ['tizen==1', {
-          'dependencies': [
-            '../../../build/system.gyp:tizen',
-          ],
-          'sources': [
-            'xwalk_tizen_user.cc',
-            'xwalk_tizen_user.h',
-          ],
-        }],
-      ],
-    },
+  'targets': [  
     {
       'target_name': 'xwalk_launcher',
       'type': 'executable',
@@ -69,8 +34,8 @@
           'sources': [
             'xwalk_launcher_tizen.cc',
             'xwalk_launcher_tizen.h',
-            'xwalk_tizen_user.cc',
-            'xwalk_tizen_user.h',
+            '../tizen/xwalk_tizen_user.cc',
+            '../tizen/xwalk_tizen_user.h',
           ],
         }],
       ],
index 57816d2..1fe5674 100644 (file)
@@ -20,7 +20,7 @@
 #if defined(OS_TIZEN)
 #include "url/gurl.h"
 #include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
-#include "xwalk/application/tools/linux/xwalk_tizen_user.h"
+#include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
 #endif
 
 static const char* xwalk_service_name = "org.crosswalkproject.Runtime1";
index 794fe17..376f2af 100644 (file)
@@ -155,12 +155,12 @@ PkgmgrBackendPlugin::GetApplicationDataFromPkg(const std::string& pkg_path) {
 
   scoped_ptr<xwalk::application::Package> package =
       xwalk::application::Package::Create(base::FilePath(pkg_path));
-  package->Extract(&unpacked_dir);
+  package->ExtractToTemporaryDir(&unpacked_dir);
   std::string app_id = package->Id();
 
   std::string error;
   scoped_refptr<xwalk::application::ApplicationData> app_data = LoadApplication(
-      unpacked_dir, app_id, xwalk::application::Manifest::COMMAND_LINE,
+      unpacked_dir, app_id, xwalk::application::ApplicationData::TEMP_DIRECTORY,
       package->type(), &error);
   return app_data;
 }
index 48aa919..4c4c050 100644 (file)
@@ -22,9 +22,9 @@ do
               keyvalue="$2"
               shift
               ;;
-        "-r") echo "Reinstall not supported"
-              exit 128 # ErrorNotSupportRDSUpdate == 128
-              ;; #TODO(t.iwanek) fix me - sending signals for reinstall option
+        "-r") option="-r"
+              id="$2"
+              ;;
     esac
     shift
 done
index e07e1c5..fde8e78 100644 (file)
@@ -23,6 +23,7 @@ namespace {
 char* install_option = NULL;
 char* update_option = NULL;
 char* uninstall_option = NULL;
+char* reinstall_option = NULL;
 char* operation_key = NULL;
 char* xml_path = NULL;
 char* icon_path = NULL;
@@ -35,6 +36,8 @@ GOptionEntry entries[] = {
     "Path of the application to be updated", "APPID" },
   { "uninstall", 'd', 0, G_OPTION_ARG_STRING, &uninstall_option,
     "Uninstall the application with this appid", "APPID" },
+  { "reinstall", 'r', 0, G_OPTION_ARG_STRING, &reinstall_option,
+    "Path of the application to be reinstalled", "APPID" },
   { "key", 'k', 0, G_OPTION_ARG_STRING, &operation_key,
     "Unique operation key", "KEY" },
   { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet,
@@ -86,8 +89,10 @@ int main(int argc, char *argv[]) {
     appId = uninstall_option;
   } else if (update_option) {
     appId = update_option;
+  } else if (reinstall_option) {
+    appId = reinstall_option;
   } else {
-    fprintf(stderr, "Use: --install, --uninstall or --update\n");
+    fprintf(stderr, "Use: --install, --uninstall, --update or --reinstall\n");
     exit(1);
   }
 
@@ -127,6 +132,14 @@ int main(int argc, char *argv[]) {
     }
 
     result = helper.UpdateApplication(xml_path, icon_path);
+  } else if (reinstall_option) {
+    if (operation_key) {
+      pkgmgr_argv[0] = "-r";
+      pkgmgr_argv[1] = reinstall_option;  // this value is ignored by pkgmgr
+      helper.InitializePkgmgrSignal((quiet ? 5 : 4), pkgmgr_argv);
+    }
+
+    result = helper.ReinstallApplication();
   }
 
   // Convention is to return 0 on success.
@@ -2,9 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/package_installer.h"
+#include "xwalk/application/tools/tizen/xwalk_package_installer.h"
 
 #include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <pkgmgr/pkgmgr_parser.h>
+
 #include <algorithm>
 #include <map>
 #include <string>
 #include "base/command_line.h"
 #include "base/process/launch.h"
 #include "base/version.h"
+#include "third_party/libxml/chromium/libxml_utils.h"
 #include "xwalk/application/common/application_data.h"
 #include "xwalk/application/common/application_file_util.h"
 #include "xwalk/application/common/application_manifest_constants.h"
-#include "xwalk/application/common/permission_policy_manager.h"
 #include "xwalk/application/common/application_storage.h"
 #include "xwalk/application/common/id_util.h"
-#include "xwalk/application/common/installer/tizen/packageinfo_constants.h"
+#include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
+#include "xwalk/application/common/manifest_handlers/tizen_metadata_handler.h"
+#include "xwalk/application/common/permission_policy_manager.h"
+#include "xwalk/application/tools/tizen/xwalk_packageinfo_constants.h"
 #include "xwalk/runtime/common/xwalk_paths.h"
 
-#if defined(OS_TIZEN)
-#include "xwalk/application/common/installer/package_installer_tizen.h"
-#endif
+namespace info = application_packageinfo_constants;
 
-namespace xwalk {
-namespace application {
+using xwalk::application::ApplicationData;
+using xwalk::application::ApplicationStorage;
+using xwalk::application::FileDeleter;
+using xwalk::application::Package;
 
 namespace {
 
+const base::FilePath::CharType kApplicationsDir[] =
+    FILE_PATH_LITERAL("applications");
+
+const base::FilePath::CharType kInstallTempDir[] =
+    FILE_PATH_LITERAL("install_temp");
+
+const base::FilePath::CharType kUpdateTempDir[] =
+    FILE_PATH_LITERAL("update_temp");
+
+namespace widget_keys = xwalk::application_widget_keys;
+
+const base::FilePath kPkgHelper("/usr/bin/xwalk-pkg-helper");
+
+const base::FilePath kXWalkLauncherBinary("/usr/bin/xwalk-launcher");
+
+const base::FilePath kDefaultIcon(
+    "/usr/share/icons/default/small/crosswalk.png");
+
+const std::string kServicePrefix("xwalk-service.");
+const std::string kAppIdPrefix("xwalk.");
+
 bool CopyDirectoryContents(const base::FilePath& from,
     const base::FilePath& to) {
   base::FileEnumerator iter(from, false,
@@ -50,18 +78,106 @@ bool CopyDirectoryContents(const base::FilePath& from,
   return true;
 }
 
-const base::FilePath::CharType kApplicationsDir[] =
-    FILE_PATH_LITERAL("applications");
+void WriteMetaDataElement(
+    XmlWriter& writer, // NOLINT
+    xwalk::application::TizenMetaDataInfo* info) {
+  if (!info)
+    return;
+
+  const std::map<std::string, std::string>& metadata = info->metadata();
+  std::map<std::string, std::string>::const_iterator it;
+  for (it = metadata.begin(); it != metadata.end(); ++it) {
+    writer.StartElement("metadata");
+    writer.AddAttribute("key", it->first);
+    writer.AddAttribute("value", it->second);
+    writer.EndElement();
+  }
+}
 
-const base::FilePath::CharType kInstallTempDir[] =
-    FILE_PATH_LITERAL("install_temp");
+bool GeneratePkgInfoXml(xwalk::application::ApplicationData* application,
+                        const std::string& icon_name,
+                        const base::FilePath& app_dir,
+                        const base::FilePath& xml_path) {
+  if (!base::PathExists(app_dir) &&
+      !base::CreateDirectory(app_dir))
+    return false;
+
+  std::string package_id =
+      xwalk::application::AppIdToPkgId(application->ID());
+
+  base::FilePath execute_path =
+      app_dir.AppendASCII("bin/").AppendASCII(application->ID());
+  std::string stripped_name = application->Name();
+
+  FILE* file = base::OpenFile(xml_path, "w");
+
+  XmlWriter xml_writer;
+  xml_writer.StartWriting();
+  xml_writer.StartElement("manifest");
+  xml_writer.AddAttribute("xmlns", "http://tizen.org/ns/packages");
+  xml_writer.AddAttribute("package", package_id);
+  xml_writer.AddAttribute("type", "wgt");
+  xml_writer.AddAttribute("version", application->VersionString());
+  xml_writer.WriteElement("label", application->Name());
+  xml_writer.WriteElement("description", application->Description());
+
+  xml_writer.StartElement("ui-application");
+  xml_writer.AddAttribute("appid", application->ID());
+  xml_writer.AddAttribute("exec", execute_path.MaybeAsASCII());
+  xml_writer.AddAttribute("type", "webapp");
+  xml_writer.AddAttribute("taskmanage", "true");
+  xml_writer.WriteElement("label", application->Name());
+
+  xwalk::application::TizenMetaDataInfo* info =
+      static_cast<xwalk::application::TizenMetaDataInfo*>(
+      application->GetManifestData(widget_keys::kTizenMetaDataKey));
+  WriteMetaDataElement(xml_writer, info);
+
+  if (icon_name.empty())
+    xml_writer.WriteElement("icon", info::kDefaultIconName);
+  else
+    xml_writer.WriteElement("icon",
+                            kServicePrefix + application->ID() + ".png");
+  xml_writer.EndElement();  // Ends "ui-application"
+
+  xml_writer.EndElement();  // Ends "manifest" element.
+  xml_writer.StopWriting();
+
+  base::WriteFile(xml_path,
+                  xml_writer.GetWrittenString().c_str(),
+                  xml_writer.GetWrittenString().size());
+
+  base::CloseFile(file);
+  LOG(INFO) << "Converting manifest.json into "
+            << xml_path.BaseName().MaybeAsASCII()
+            << " for installation. [DONE]";
+  return true;
+}
+
+bool CreateAppSymbolicLink(const base::FilePath& app_dir,
+                           const std::string& app_id) {
+  base::FilePath execute_path =
+      app_dir.AppendASCII("bin/").AppendASCII(app_id);
+
+  if (!base::CreateDirectory(execute_path.DirName())) {
+    LOG(ERROR) << "Could not create directory '"
+               << execute_path.DirName().value() << "'.";
+    return false;
+  }
+
+  if (!base::CreateSymbolicLink(kXWalkLauncherBinary, execute_path)) {
+    LOG(ERROR) << "Could not create symbolic link to launcher from '"
+               << execute_path.value() << "'.";
+    return false;
+  }
+  return true;
+}
 
-const base::FilePath::CharType kUpdateTempDir[] =
-    FILE_PATH_LITERAL("update_temp");
 }  // namespace
 
 PackageInstaller::PackageInstaller(ApplicationStorage* storage)
-    : storage_(storage) {
+  : storage_(storage),
+    quiet_(false) {
 }
 
 PackageInstaller::~PackageInstaller() {
@@ -69,32 +185,221 @@ PackageInstaller::~PackageInstaller() {
 
 scoped_ptr<PackageInstaller> PackageInstaller::Create(
     ApplicationStorage* storage) {
-#if defined(OS_TIZEN)
-  return scoped_ptr<PackageInstaller>(new PackageInstallerTizen(storage));
-#else
   return scoped_ptr<PackageInstaller>(new PackageInstaller(storage));
-#endif
 }
 
 void PackageInstaller::SetQuiet(bool quiet) {
+  quiet_ = quiet;
 }
 
 void PackageInstaller::SetInstallationKey(const std::string& key) {
+  key_ = key;
 }
 
-std::string PackageInstaller::PrepareUninstallationID(const std::string& id) {
+std::string PackageInstaller::PrepareUninstallationID(
+    const std::string& id) {
+  // this function fix pkg_id to app_id
+  // if installer was launched with pkg_id
+  if (xwalk::application::IsValidPkgID(id)) {
+    LOG(INFO) << "The package id is given " << id << " Will find app_id...";
+    std::string appid = xwalk::application::PkgIdToAppId(id);
+    if (!appid.empty())
+      return appid;
+  }
   return id;
 }
 
-bool PackageInstaller::PlatformInstall(ApplicationData* data) {
+bool PackageInstaller::PlatformInstall(ApplicationData* app_data) {
+  std::string app_id(app_data->ID());
+  base::FilePath data_dir;
+  CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &data_dir));
+
+  base::FilePath app_dir =
+      data_dir.AppendASCII(info::kAppDir).AppendASCII(app_id);
+  base::FilePath xml_path = data_dir.AppendASCII(info::kAppDir).AppendASCII(
+      app_id + std::string(info::kXmlExtension));
+
+  std::string icon_name;
+  if (!app_data->GetManifest()->GetString(
+      GetIcon128Key(app_data->GetPackageType()), &icon_name))
+    LOG(WARNING) << "'icon' not included in manifest";
+
+  // This will clean everything inside '<data dir>/<app id>'.
+  FileDeleter app_dir_cleaner(app_dir, true);
+
+  if (!GeneratePkgInfoXml(app_data, icon_name, app_dir, xml_path)) {
+    LOG(ERROR) << "Failed to create XML metadata file '"
+               << xml_path.value() << "'.";
+    return false;
+  }
+
+  if (!CreateAppSymbolicLink(app_dir, app_id)) {
+    LOG(ERROR) << "Failed to create symbolic link for " << app_id;
+    return false;
+  }
+
+  base::FilePath icon =
+      icon_name.empty() ? kDefaultIcon : app_dir.AppendASCII(icon_name);
+
+  CommandLine cmdline(kPkgHelper);
+  cmdline.AppendSwitchASCII("--install", app_id);
+  cmdline.AppendSwitchPath("--xml", xml_path);
+  cmdline.AppendSwitchPath("--icon", icon);
+  if (quiet_)
+    cmdline.AppendSwitch("-q");
+  if (!key_.empty()) {
+    cmdline.AppendSwitchASCII("--key", key_);
+  }
+
+  int exit_code;
+  std::string output;
+
+  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
+    LOG(ERROR) << "Could not launch the installation helper process.";
+    return false;
+  }
+
+  if (exit_code != 0) {
+    LOG(ERROR) << "Could not install application: "
+               << output << " (" << exit_code << ")";
+    return false;
+  }
+
+  app_dir_cleaner.Dismiss();
+
   return true;
 }
 
-bool PackageInstaller::PlatformUninstall(ApplicationData* data) {
+bool PackageInstaller::PlatformUninstall(ApplicationData* app_data) {
+  bool result = true;
+  std::string app_id(app_data->ID());
+  base::FilePath data_dir;
+  CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &data_dir));
+
+  CommandLine cmdline(kPkgHelper);
+  cmdline.AppendSwitchASCII("--uninstall", app_id);
+  if (quiet_)
+    cmdline.AppendSwitch("-q");
+  if (!key_.empty()) {
+    cmdline.AppendSwitchASCII("--key", key_);
+  }
+
+  int exit_code;
+  std::string output;
+
+  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
+    LOG(ERROR) << "Could not launch installer helper";
+    result = false;
+  }
+
+  if (exit_code != 0) {
+    LOG(ERROR) << "Could not uninstall application: "
+               << output << " (" << exit_code << ")";
+    result = false;
+  }
+
+  base::FilePath app_dir =
+      data_dir.AppendASCII(info::kAppDir).AppendASCII(app_id);
+  if (!base::DeleteFile(app_dir, true)) {
+    LOG(ERROR) << "Could not remove directory '" << app_dir.value() << "'";
+    result = false;
+  }
+
+  base::FilePath xml_path = data_dir.AppendASCII(
+      app_id + std::string(info::kXmlExtension));
+  if (!base::DeleteFile(xml_path, false)) {
+    LOG(ERROR) << "Could not remove file '" << xml_path.value() << "'";
+    result = false;
+  }
+
+  return result;
+}
+
+bool PackageInstaller::PlatformUpdate(ApplicationData* app_data) {
+  std::string app_id(app_data->ID());
+  base::FilePath data_dir;
+  CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &data_dir));
+
+  base::FilePath app_dir =
+      data_dir.AppendASCII(info::kAppDir).AppendASCII(app_id);
+  base::FilePath new_xml_path = data_dir.AppendASCII(info::kAppDir).AppendASCII(
+      app_id + ".new" + std::string(info::kXmlExtension));
+
+  std::string icon_name;
+  if (!app_data->GetManifest()->GetString(
+      GetIcon128Key(app_data->GetPackageType()), &icon_name))
+    LOG(WARNING) << "'icon' not included in manifest";
+
+  // This will clean everything inside '<data dir>/<app id>' and the new XML.
+  FileDeleter app_dir_cleaner(app_dir, true);
+  FileDeleter new_xml_cleaner(new_xml_path, true);
+
+  if (!GeneratePkgInfoXml(app_data, icon_name, app_dir, new_xml_path)) {
+    LOG(ERROR) << "Could not create new XML metadata file '"
+               << new_xml_path.value() << "'.";
+    return false;
+  }
+
+  if (!CreateAppSymbolicLink(app_dir, app_id))
+    return false;
+
+  base::FilePath icon =
+      icon_name.empty() ? kDefaultIcon : app_dir.AppendASCII(icon_name);
+
+  CommandLine cmdline(kPkgHelper);
+  cmdline.AppendSwitchASCII("--update", app_id);
+  cmdline.AppendSwitchPath("--xml", new_xml_path);
+  cmdline.AppendSwitchPath("--icon", icon);
+  if (quiet_)
+    cmdline.AppendSwitch("-q");
+  if (!key_.empty()) {
+    cmdline.AppendSwitchASCII("--key", key_);
+  }
+
+  int exit_code;
+  std::string output;
+
+  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
+    LOG(ERROR) << "Could not launch installer helper";
+    return false;
+  }
+
+  if (exit_code != 0) {
+    LOG(ERROR) << "Could not update application: "
+               << output << " (" << exit_code << ")";
+    return false;
+  }
+
+  base::FilePath old_xml_path = data_dir.AppendASCII(info::kAppDir).AppendASCII(
+      app_id + std::string(info::kXmlExtension));
+  base::Move(new_xml_path, old_xml_path);
+  app_dir_cleaner.Dismiss();
   return true;
 }
 
-bool PackageInstaller::PlatformUpdate(ApplicationData* updated_data) {
+bool PackageInstaller::PlatformReinstall(const base::FilePath& path) {
+  CommandLine cmdline(kPkgHelper);
+  cmdline.AppendSwitchPath("--reinstall", path);
+  if (quiet_)
+    cmdline.AppendSwitch("-q");
+  if (!key_.empty()) {
+    cmdline.AppendSwitchASCII("--key", key_);
+  }
+
+  int exit_code;
+  std::string output;
+
+  if (!base::GetAppOutputWithExitCode(cmdline, &output, &exit_code)) {
+    LOG(ERROR) << "Could not launch installer helper";
+    return false;
+  }
+
+  if (exit_code != 0) {
+    LOG(ERROR) << "Could not reinstall application: "
+               << output << " (" << exit_code << ")";
+    return false;
+  }
+
   return true;
 }
 
@@ -131,7 +436,7 @@ bool PackageInstaller::Install(const base::FilePath& path, std::string* id) {
     package = Package::Create(tmp_path.path());
     if (!package->IsValid())
       return false;
-    package->Extract(&unpacked_dir);
+    package->ExtractToTemporaryDir(&unpacked_dir);
     app_id = package->Id();
   } else {
     unpacked_dir = path;
@@ -139,7 +444,7 @@ bool PackageInstaller::Install(const base::FilePath& path, std::string* id) {
 
   std::string error;
   scoped_refptr<ApplicationData> app_data = LoadApplication(
-      unpacked_dir, app_id, Manifest::COMMAND_LINE,
+      unpacked_dir, app_id, ApplicationData::LOCAL_DIRECTORY,
       package->type(), &error);
   if (!app_data) {
     LOG(ERROR) << "Error during application installation: " << error;
@@ -148,7 +453,7 @@ bool PackageInstaller::Install(const base::FilePath& path, std::string* id) {
 
   // FIXME: Probably should be removed, as we should not handle permissions
   // inside XWalk.
-  PermissionPolicyManager permission_policy_handler;
+  xwalk::application::PermissionPolicyManager permission_policy_handler;
   if (!permission_policy_handler.
       InitApplicationPermission(app_data)) {
     LOG(ERROR) << "Application permission data is invalid";
@@ -202,7 +507,7 @@ bool PackageInstaller::Install(const base::FilePath& path, std::string* id) {
 
 bool PackageInstaller::Update(const std::string& app_id,
                               const base::FilePath& path) {
-  if (!IsValidApplicationID(app_id)) {
+  if (!xwalk::application::IsValidApplicationID(app_id)) {
     LOG(ERROR) << "The given application id " << app_id << " is invalid.";
     return false;
   }
@@ -241,14 +546,14 @@ bool PackageInstaller::Update(const std::string& app_id,
     return false;
   }
 
-  if (!package->Extract(&unpacked_dir))
+  if (!package->ExtractToTemporaryDir(&unpacked_dir))
     return false;
 
   std::string error;
   scoped_refptr<ApplicationData> new_app_data =
       LoadApplication(unpacked_dir,
                       app_id,
-                      Manifest::COMMAND_LINE,
+                      ApplicationData::TEMP_DIRECTORY,
                       package->type(),
                       &error);
   if (!new_app_data) {
@@ -264,12 +569,10 @@ bool PackageInstaller::Update(const std::string& app_id,
   }
 
   if (
-#if defined(OS_TIZEN)
       // For Tizen WGT package, downgrade to a lower version or reinstall
       // is permitted when using Tizen WRT, Crosswalk runtime need to follow
       // this behavior on Tizen platform.
       package->type() != Package::WGT &&
-#endif
       old_app_data->Version()->CompareTo(
           *(new_app_data->Version())) >= 0) {
     LOG(INFO) << "The version number of new XPK/WGT package "
@@ -288,7 +591,7 @@ bool PackageInstaller::Update(const std::string& app_id,
 
   new_app_data = LoadApplication(app_dir,
                                     app_id,
-                                    Manifest::COMMAND_LINE,
+                                    ApplicationData::LOCAL_DIRECTORY,
                                     package->type(),
                                     &error);
   if (!new_app_data) {
@@ -327,7 +630,7 @@ bool PackageInstaller::Update(const std::string& app_id,
 bool PackageInstaller::Uninstall(const std::string& id) {
   std::string app_id = PrepareUninstallationID(id);
 
-  if (!IsValidApplicationID(app_id)) {
+  if (!xwalk::application::IsValidApplicationID(app_id)) {
     LOG(ERROR) << "The given application id " << app_id << " is invalid.";
     return false;
   }
@@ -363,6 +666,10 @@ bool PackageInstaller::Uninstall(const std::string& id) {
   return result;
 }
 
+bool PackageInstaller::Reinstall(const base::FilePath& path) {
+  return PlatformReinstall(path);
+}
+
 void PackageInstaller::ContinueUnfinishedTasks() {
   base::FilePath config_dir;
   CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &config_dir));
@@ -395,6 +702,3 @@ void PackageInstaller::ContinueUnfinishedTasks() {
     }
   }
 }
-
-}  // namespace application
-}  // namespace xwalk
diff --git a/src/xwalk/application/tools/tizen/xwalk_package_installer.h b/src/xwalk/application/tools/tizen/xwalk_package_installer.h
new file mode 100644 (file)
index 0000000..c9c9ce3
--- /dev/null
@@ -0,0 +1,55 @@
+// 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_APPLICATION_TOOLS_TIZEN_XWALK_PACKAGE_INSTALLER_H_
+#define XWALK_APPLICATION_TOOLS_TIZEN_XWALK_PACKAGE_INSTALLER_H_
+
+#include <string>
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace xwalk {
+namespace application {
+
+class ApplicationData;
+class ApplicationStorage;
+
+}  // namespace application
+}  // namespace xwalk
+
+class PackageInstaller {
+ public:
+  static scoped_ptr<PackageInstaller> Create(
+    xwalk::application::ApplicationStorage* storage);
+
+  ~PackageInstaller();
+
+  bool Install(const base::FilePath& path, std::string* id);
+  bool Uninstall(const std::string& id);
+  bool Update(const std::string& id, const base::FilePath& path);
+  bool Reinstall(const base::FilePath& path);
+
+  void ContinueUnfinishedTasks();
+
+  void SetQuiet(bool quiet);
+  void SetInstallationKey(const std::string& key);
+
+ protected:
+  explicit PackageInstaller(xwalk::application::ApplicationStorage* storage);
+
+  std::string PrepareUninstallationID(const std::string& id);
+
+  bool PlatformInstall(xwalk::application::ApplicationData* data);
+  bool PlatformUninstall(xwalk::application::ApplicationData* data);
+  bool PlatformUpdate(xwalk::application::ApplicationData* updated_data);
+  bool PlatformReinstall(const base::FilePath& path);
+
+  xwalk::application::ApplicationStorage* storage_;
+  bool quiet_;
+  std::string key_;
+};
+
+
+
+#endif  // XWALK_APPLICATION_TOOLS_TIZEN_XWALK_PACKAGE_INSTALLER_H_
index f062098..9a97d3d 100644 (file)
@@ -40,6 +40,9 @@ const char PKGMGR_START_UNINSTALL[] = "uninstall";
 // Value for update.
 const char PKGMGR_START_UPDATE[] = "update";
 
+// Value for update.
+const char PKGMGR_START_REINSTALL[] = "reinstall";
+
 // Notification about end of installation with status.
 const char PKGMGR_END_KEY[] = "end";
 
@@ -152,6 +155,13 @@ bool PackageInstallerHelper::UpdateApplication(
   return ret;
 }
 
+bool PackageInstallerHelper::ReinstallApplication() {
+  SendSignal(PKGMGR_START_KEY, PKGMGR_START_REINSTALL);
+  // FIXME not implemented, just send signal abotu failure
+  SendSignal(PKGMGR_END_KEY, ToEndStatus(false));
+  return false;
+}
+
 bool PackageInstallerHelper::InstallApplicationInternal(
     const std::string& xmlpath,
     const std::string& iconpath) {
index 6a0bc88..ba90c17 100644 (file)
@@ -20,6 +20,7 @@ class PackageInstallerHelper {
   bool UninstallApplication();
   bool UpdateApplication(const std::string& xmlpath,
                          const std::string& iconpath);
+  bool ReinstallApplication();
 
  private:
   bool InstallApplicationInternal(const std::string& xmlpath,
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/application/common/installer/tizen/packageinfo_constants.h"
+#include "xwalk/application/tools/tizen/xwalk_packageinfo_constants.h"
 
-namespace xwalk {
 namespace application_packageinfo_constants {
 
 const base::FilePath::CharType kAppDir[] =
@@ -29,4 +28,3 @@ const char kXmlExtension[] = ".xml";
 const char kSeparator[] = ".";
 
 }  // namespace application_packageinfo_constants
-}  // namespace xwalk
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_COMMON_INSTALLER_TIZEN_PACKAGEINFO_CONSTANTS_H_
-#define XWALK_APPLICATION_COMMON_INSTALLER_TIZEN_PACKAGEINFO_CONSTANTS_H_
+#ifndef XWALK_APPLICATION_TOOLS_TIZEN_XWALK_PACKAGEINFO_CONSTANTS_H_
+#define XWALK_APPLICATION_TOOLS_TIZEN_XWALK_PACKAGEINFO_CONSTANTS_H_
 
 #include "base/files/file_path.h"
 #include "base/basictypes.h"
 
-namespace xwalk {
 namespace application_packageinfo_constants {
   extern const base::FilePath::CharType kAppDir[];
   extern const base::FilePath::CharType kAppDBPath[];
@@ -24,6 +23,5 @@ namespace application_packageinfo_constants {
   extern const char kXmlExtension[];
   extern const char kSeparator[];
 }  // namespace application_packageinfo_constants
-}  // namespace xwalk
 
-#endif  // XWALK_APPLICATION_COMMON_INSTALLER_TIZEN_PACKAGEINFO_CONSTANTS_H_
+#endif  // XWALK_APPLICATION_TOOLS_TIZEN_XWALK_PACKAGEINFO_CONSTANTS_H_
index 4ac3e8a..91d992d 100644 (file)
@@ -1,6 +1,35 @@
 {
   'targets': [
     {
+      'target_name': 'xwalkctl',
+      'type': 'executable',
+      'product_name': 'xwalkctl',
+      'dependencies': [
+        '../../../application/common/xwalk_application_common.gypi:xwalk_application_common_lib',
+        '../../../build/system.gyp:gio',
+        '../../../../build/linux/system.gyp:dbus',
+        '../../../../dbus/dbus.gyp:dbus',
+        '../../../build/system.gyp:tizen',
+      ],
+      'include_dirs': [
+        '../../../..',
+      ],
+      'sources': [
+        'xwalkctl_main.cc',
+        'xwalk_package_installer.cc',
+        'xwalk_package_installer.h',
+        'xwalk_packageinfo_constants.cc',
+        'xwalk_packageinfo_constants.h',
+        'xwalk_tizen_user.cc',
+        'xwalk_tizen_user.h',
+        # TODO(t.iwanek) fix me - this duplicates compilation of those files
+        '../../../runtime/common/xwalk_paths.cc',
+        '../../../runtime/common/xwalk_paths.h',
+        '../../../runtime/common/xwalk_system_locale.cc',
+        '../../../runtime/common/xwalk_system_locale.h',
+      ],
+    },  
+    {
       'target_name': 'xwalk-pkg-helper',
       'type': 'executable',
       'product_name': 'xwalk-pkg-helper',
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_APPLICATION_TOOLS_LINUX_XWALK_TIZEN_USER_H_
-#define XWALK_APPLICATION_TOOLS_LINUX_XWALK_TIZEN_USER_H_
+#ifndef XWALK_APPLICATION_TOOLS_TIZEN_XWALK_TIZEN_USER_H_
+#define XWALK_APPLICATION_TOOLS_TIZEN_XWALK_TIZEN_USER_H_
 
 // When developing on Tizen, we log into the device using 'sdb' as the
 // 'root' user, when changing to the 'app' user (the user as all Applications
@@ -13,4 +13,4 @@
 
 int xwalk_tizen_check_user_app(void);
 
-#endif  // XWALK_APPLICATION_TOOLS_LINUX_XWALK_TIZEN_USER_H_
+#endif  // XWALK_APPLICATION_TOOLS_TIZEN_XWALK_TIZEN_USER_H_
 #include "dbus/object_proxy.h"
 
 #include "xwalk/application/common/application_storage.h"
-#include "xwalk/application/common/installer/package_installer.h"
 #include "xwalk/application/tools/linux/dbus_connection.h"
+#include "xwalk/application/tools/tizen/xwalk_package_installer.h"
 #include "xwalk/runtime/common/xwalk_paths.h"
 
-#if defined(OS_TIZEN)
 #include "xwalk/application/common/id_util.h"
-#include "xwalk/application/tools/linux/xwalk_tizen_user.h"
-#endif
+#include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
 
 using xwalk::application::ApplicationData;
 using xwalk::application::ApplicationStorage;
-using xwalk::application::PackageInstaller;
 
 namespace {
 
 char* install_path = NULL;
 char* uninstall_id = NULL;
-#if defined(OS_TIZEN)
+char* reinstall_path = NULL;
 char* operation_key = NULL;
 int quiet = 0;
-#endif
 
 gint debugging_port = -1;
 gboolean continue_tasks = FALSE;
@@ -54,12 +50,12 @@ GOptionEntry entries[] = {
     "Enable remote debugging, port number 0 means to disable", NULL },
   { "continue", 'c' , 0, G_OPTION_ARG_NONE, &continue_tasks,
     "Continue the previous unfinished tasks.", NULL},
-#if defined(OS_TIZEN)
+  { "reinstall", 'r', 0, G_OPTION_ARG_STRING, &reinstall_path,
+    "Reinstall the application with path", "PATH" },
   { "key", 'k', 0, G_OPTION_ARG_STRING, &operation_key,
     "Unique operation key", "KEY" },
   { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet,
     "Quiet mode", NULL },
-#endif
   { NULL }
 };
 
@@ -138,10 +134,8 @@ int main(int argc, char* argv[]) {
   g_type_init();
 #endif
 
-#if defined(OS_TIZEN)
   if (xwalk_tizen_check_user_app())
     exit(1);
-#endif
 
   context = g_option_context_new("- Crosswalk Application Management");
   if (!context) {
@@ -165,11 +159,9 @@ int main(int argc, char* argv[]) {
   scoped_ptr<PackageInstaller> installer =
       PackageInstaller::Create(storage.get());
 
-#if defined(OS_TIZEN)
   installer->SetQuiet(static_cast<bool>(quiet));
   if (operation_key)
     installer->SetInstallationKey(operation_key);
-#endif
 
   if (continue_tasks) {
     g_print("trying to continue previous unfinished tasks.\n");
@@ -188,6 +180,8 @@ int main(int argc, char* argv[]) {
     }
   } else if (uninstall_id) {
     success = installer->Uninstall(uninstall_id);
+  } else if (reinstall_path) {
+    success = installer->Reinstall(base::FilePath(reinstall_path));
   } else if (debugging_port >= 0) {
 #if defined(SHARED_PROCESS_MODE)
     // Deal with the case "xwalkctl -d PORT_NUMBER"
index 19a7717..d4ab10f 100644 (file)
@@ -66,6 +66,8 @@
           'sources': [
             'browser/application_tizen.cc',
             'browser/application_tizen.h',
+            'browser/application_service_tizen.cc',
+            'browser/application_service_tizen.h',
           ],
         }],
       ],
       'conditions': [
         ['OS=="linux"', {
           'dependencies': [
-            'application/tools/linux/xwalk_application_tools.gyp:xwalkctl',
             'application/tools/linux/xwalk_application_tools.gyp:xwalk_launcher',
           ],
         }],
         ['tizen == 1', {
           'dependencies': [
+            'application/tools/tizen/xwalk_tizen_tools.gyp:xwalkctl',
             'application/tools/tizen/xwalk_tizen_tools.gyp:xwalk-pkg-helper',
             'application/tools/tizen/xwalk_tizen_tools.gyp:xwalk-backendlib',
           ],
index b5b7a7f..673cc59 100755 (executable)
@@ -63,11 +63,13 @@ def PrepareFromXwalk(src_dir, target_dir):
     (os.path.join(tools_src_dir, 'compress_js_and_css.py'), target_dir),
     (os.path.join(tools_src_dir, 'customize.py'), target_dir),
     (os.path.join(tools_src_dir, 'customize_launch_screen.py'), target_dir),
+    (os.path.join(tools_src_dir, 'extension_manager.py'), target_dir),
     (os.path.join(tools_src_dir, 'handle_permissions.py'), target_dir),
     (os.path.join(tools_src_dir, 'handle_xml.py'), target_dir),
     (os.path.join(tools_src_dir, 'make_apk.py'), target_dir),
     (os.path.join(tools_src_dir, 'manifest_json_parser.py'), target_dir),
-    (os.path.join(tools_src_dir, 'parse_xpk.py'), target_dir)
+    (os.path.join(tools_src_dir, 'parse_xpk.py'), target_dir),
+    (os.path.join(tools_src_dir, 'util.py'), target_dir)
   ]
 
   for index in range(len(source_target_list)):
index bba14f8..f66f7d3 100755 (executable)
 # 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.
-# pylint: disable=F0401
 
 import optparse
 import os
-import shutil
 import sys
 import zipfile
 
-LIBRARY_PROJECT_NAME = 'xwalk_core_library'
-AAR_LIBRARY_NAME = 'xwalk_core_library_aar'
 
-def AddGeneratorOptions(option_parser):
-  option_parser.add_option('-s', dest='source',
-                           help='Source directory of project root.',
-                           type='string')
-  option_parser.add_option('-t', dest='target',
-                           help='Product out target directory.',
-                           type='string')
-
-
-def CopyProjectFiles(out_dir):
-  """cp out/Release/xwalk_core_library/AndroidManifest<file>
-        out/Release/xwalk_core_library_aar/<file>
-  """
-
-  print 'Copying library project files...'
-  files_to_copy = [
-      # AndroidManifest.xml from template.
-      'AndroidManifest.xml',
-  ]
-  for f in files_to_copy:
-    source_file = os.path.join(out_dir, LIBRARY_PROJECT_NAME, f)
-    target_file = os.path.join(out_dir, AAR_LIBRARY_NAME, f)
-    shutil.copy2(source_file, target_file)
-
-
-def CopyBinaries(out_dir):
-  """cp out/Release/xwalk_core_library/libs/*
-        out/Release/xwalk_core_library_aar/jni/
-  """
-
-  print 'Copying binaries...'
-  # Copy jar files to classes.jar.
-  libs_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'libs')
-
-  source_file = os.path.join(libs_dir, 'xwalk_core_library_java.jar')
-  target_file = os.path.join(out_dir, AAR_LIBRARY_NAME, 'classes.jar')
-  shutil.copyfile(source_file, target_file)
-
-  # Copy native libraries.
-  source_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'libs')
-  target_dir = os.path.join(out_dir, AAR_LIBRARY_NAME, 'jni')
-  if not os.path.exists(target_dir):
-    os.makedirs(target_dir)
-
-  if os.path.exists(source_dir):
-    for item in os.listdir(source_dir):
-      sub_path = os.path.join(source_dir, item)
-      target_dir = os.path.join(target_dir, item)
-      if os.path.isdir(sub_path):
-        shutil.copytree(sub_path, target_dir)
-
-  # Copy R.txt.
-  r_source_dir = os.path.join(out_dir, 'gen', 'xwalk_core_internal_java') 
-  r_source_file = os.path.join(r_source_dir, 'java_R', 'R.txt')
-  r_target_file = os.path.join(out_dir, AAR_LIBRARY_NAME, 'R.txt')
-  shutil.copyfile(r_source_file, r_target_file) 
-
-
-def CopyResources(out_dir):
-  print 'Copying resources...'
-  source_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'res')
-  target_dir = os.path.join(out_dir, AAR_LIBRARY_NAME, 'res')
-  shutil.copytree(source_dir, target_dir)
-
-
-def GenerateAAR(aar_path, aar_dir):
-  zfile = zipfile.ZipFile(aar_path, 'w')
-  abs_src = os.path.abspath(aar_dir)
-  for dirname, _, files in os.walk(aar_dir):
-    for filename in files:
-      absname = os.path.abspath(os.path.join(dirname, filename))
-      relativename = absname[len(abs_src) + 1:]
-      zfile.write(absname, relativename)
-  zfile.close()
-  #delete the AAR dir.
-  shutil.rmtree(aar_dir)
-
-
-def main(argv):
-  print 'Generating XWalkCore AAR Library...'
+def main():
   option_parser = optparse.OptionParser()
-  AddGeneratorOptions(option_parser)
-  options, _ = option_parser.parse_args(argv)
-
-  if not os.path.exists(options.source):
-    print 'Source project does not exist, please provide correct directory.'
-    sys.exit(1)
-  out_dir = options.target
-
-  # Clean the aar library.
-  aar_path = os.path.join(out_dir, 'xwalk_core_library.aar')
-  if os.path.exists(aar_path):
-    os.remove(aar_path)
-
-  aar_dir = os.path.join(out_dir, AAR_LIBRARY_NAME)
-  if os.path.exists(aar_dir):
-    shutil.rmtree(aar_dir)
-  os.mkdir(aar_dir)
-
-  # Copy Eclipse project files of library project.
-  CopyProjectFiles(out_dir)
-  # Copy binaries and resuorces.
-  CopyResources(out_dir)
-  CopyBinaries(out_dir)
-  GenerateAAR(aar_path, aar_dir)
+  option_parser.add_option('-t', dest='target',
+                           help='Product out target directory.')
+  options, _ = option_parser.parse_args()
+
+  # The first entry of each tuple is the source file/directory that will be
+  # copied (and must exist), the second entry is its relative path inside the
+  # AAR file.
+  dirs = (
+    (os.path.join(options.target, 'xwalk_core_library', 'libs'),
+     'jni'),
+    (os.path.join(options.target, 'xwalk_core_library', 'res'),
+     'res'),
+  )
+  files = (
+    (os.path.join(options.target, 'gen', 'xwalk_core_internal_java', 'java_R',
+                  'R.txt'),
+     'R.txt'),
+    (os.path.join(options.target, 'xwalk_core_library', 'AndroidManifest.xml'),
+     'AndroidManifest.xml'),
+    (os.path.join(options.target, 'xwalk_core_library', 'libs',
+                  'xwalk_core_library_java.jar'),
+     'classes.jar'),
+  )
+
+  aar_path = os.path.join(options.target, 'xwalk_core_library.aar')
+  with zipfile.ZipFile(aar_path, 'w') as aar_file:
+    for src, dest in files:
+      aar_file.write(src, dest)
+    for src, dest in dirs:
+      for root, _, files in os.walk(src):
+        for f in files:
+          real_path = os.path.join(root, f)
+          zip_path = os.path.join(dest, os.path.relpath(root, src), f)
+          aar_file.write(real_path, zip_path)
+
+  return 0
 
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv))
+  sys.exit(main())
index a8036b9..c28789e 100644 (file)
@@ -3,11 +3,13 @@
     'tizen%': 0,
     'tizen_mobile%': 0,
     'shared_process_mode%': 0,
+    'enable_murphy%': 0,
   },
   'target_defaults': {
     'variables': {
       'tizen%': '<(tizen)',
       'tizen_mobile%': '<(tizen_mobile)',
+      'enable_murphy%': '<(enable_murphy)',
     },
     'conditions': [
       ['tizen==1', {
@@ -19,6 +21,9 @@
       ['shared_process_mode==1', {
         'defines': ['SHARED_PROCESS_MODE=1'],
       }],
+      ['enable_murphy==1', {
+        'defines': ['ENABLE_MURPHY=1'],
+      }],
     ],
     'includes': [
       'xwalk_filename_rules.gypi',
index 195bc03..331b208 100644 (file)
@@ -44,10 +44,19 @@ var getDirectoryList = function() {
   extension.internal.sendSyncMessage("get");
 }
 
+var getRealPath = function(virtual_root) {
+  var _msg = {
+    cmd : "getRealPath",
+    path : virtual_root
+  }
+  return extension.internal.sendSyncMessage(_msg);
+}
+
 NativeFileSystem.prototype = new Object();
 NativeFileSystem.prototype.constructor = NativeFileSystem;
 NativeFileSystem.prototype.requestNativeFileSystem = requestNativeFileSystem;
 NativeFileSystem.prototype.getDirectoryList = getDirectoryList;
+NativeFileSystem.prototype.getRealPath = getRealPath;
 
 exports = new NativeFileSystem();
 
index 91e1344..dcc04ab 100644 (file)
@@ -92,6 +92,36 @@ void NativeFileSystemInstance::HandleMessage(scoped_ptr<base::Value> msg) {
   checker->DoTask();
 }
 
+void NativeFileSystemInstance::HandleSyncMessage(
+    scoped_ptr<base::Value> msg) {
+  base::DictionaryValue* dict;
+  std::string command;
+
+  if (!msg->GetAsDictionary(&dict) || !dict->GetString("cmd", &command)) {
+    LOG(ERROR) << "Fail to handle command sync message.";
+    SendSyncReplyToJS(scoped_ptr<base::Value>(new base::StringValue("")));
+    return;
+  }
+
+  scoped_ptr<base::Value> result(new base::StringValue(""));
+  std::string virtual_root_string = "";
+  if ("getRealPath" ==  command &&
+      dict->GetString("path", &virtual_root_string)) {
+    std::transform(virtual_root_string.begin(),
+                   virtual_root_string.end(),
+                   virtual_root_string.begin(),
+                   ::toupper);
+    std::string real_path =
+        VirtualRootProvider::GetInstance()->GetRealPath(
+            virtual_root_string);
+    result.reset(new base::StringValue(real_path));
+  } else {
+    LOG(ERROR) << command << " ASSERT NOT REACHED.";
+  }
+
+  SendSyncReplyToJS(result.Pass());
+}
+
 FileSystemChecker::FileSystemChecker(
     int process_id,
     const std::string& path,
index a7170fc..b005ccc 100644 (file)
@@ -38,6 +38,7 @@ class NativeFileSystemInstance : public XWalkExtensionInstance {
 
   // XWalkExtensionInstance implementation.
   virtual void HandleMessage(scoped_ptr<base::Value> msg) OVERRIDE;
+  virtual void HandleSyncMessage(scoped_ptr<base::Value> msg) OVERRIDE;
 
  private:
   XWalkExtensionFunctionHandler handler_;
diff --git a/src/xwalk/packaging/crosswalk-tizen-audio-session-manager.patch b/src/xwalk/packaging/crosswalk-tizen-audio-session-manager.patch
deleted file mode 100644 (file)
index 5669694..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-Author: Sudarsana Nagineni <sudarsana.nagineni@intel.com>
-
-This patch includes Chromium side changes needed for integrating
-WebMediaPlayer with the Tizen Audio Session Manager.
-
-Also, it has changes that are needed for generating audio-session-manager
-stubs and load the library dynamically in the Browser process.
-
-audio-session-manager is using an _attribute_((constructor)) to initialize
-code and setup signal handlers at startup. So, linking with this library
-is causing a sandbox violation by executing the code in Renderer Process,
-since the Renderer Process and the Browser Process are linked with the
-same libraries.
-
-To prevent the problem, we load the audio-session-manager dynamically in
-the Browser process.
-
-diff --git src/build/linux/system.gyp src/build/linux/system.gyp
-index 4a7e857..f89d256 100644
---- src/build/linux/system.gyp
-+++ src/build/linux/system.gyp
-@@ -874,5 +874,19 @@
-         }],
-       ],
-     },
-+    {
-+      'target_name': 'audio_session_manager',
-+      'type': 'none',
-+      'toolsets': ['host', 'target'],
-+      'conditions': [
-+        ['tizen_mobile == 1', {
-+          'direct_dependent_settings': {
-+            'cflags': [
-+              '<!@(<(pkg-config) --cflags audio-session-mgr)',
-+            ],
-+          },
-+        }],
-+      ],
-+    },
-   ],
- }
-diff --git src/content/browser/renderer_host/render_view_host_impl.cc src/content/browser/renderer_host/render_view_host_impl.cc
-index 0912144..adf0a1b 100644
---- src/content/browser/renderer_host/render_view_host_impl.cc
-+++ src/content/browser/renderer_host/render_view_host_impl.cc
-@@ -89,4 +89,6 @@
- #include "content/browser/media/android/browser_media_player_manager.h"
-+#elif defined(OS_TIZEN_MOBILE)
-+#include "xwalk/tizen/browser/browser_mediaplayer_manager.h"
- #elif defined(OS_WIN)
- #include "base/win/win_util.h"
- #endif
-
- using base::TimeDelta;
-@@ -223,6 +225,8 @@ RenderViewHostImpl::RenderViewHostImpl(
-
- #if defined(OS_ANDROID)
-   media_player_manager_.reset(BrowserMediaPlayerManager::Create(this));
-+#elif defined(OS_TIZEN_MOBILE)
-+  media_player_manager_.reset(tizen::BrowserMediaPlayerManager::Create(this));
- #endif
- }
-
-diff --git src/content/browser/renderer_host/render_view_host_impl.h src/content/browser/renderer_host/render_view_host_impl.h
-index d63bae3..d0602c7 100644
---- src/content/browser/renderer_host/render_view_host_impl.h
-+++ src/content/browser/renderer_host/render_view_host_impl.h
-@@ -42,6 +42,12 @@ struct ViewHostMsg_ShowPopup_Params;
- struct ViewMsg_Navigate_Params;
- struct ViewMsg_PostMessage_Params;
-
-+#if defined(OS_TIZEN_MOBILE)
-+namespace tizen {
-+class BrowserMediaPlayerManager;
-+}
-+#endif
-+
- namespace base {
- class ListValue;
- }
-@@ -704,6 +710,8 @@ class CONTENT_EXPORT RenderViewHostImpl
- #if defined(OS_ANDROID)
-   // Manages all the android mediaplayer objects and handling IPCs for video.
-   scoped_ptr<BrowserMediaPlayerManager> media_player_manager_;
-+#elif defined(OS_TIZEN_MOBILE)
-+  scoped_ptr<tizen::BrowserMediaPlayerManager> media_player_manager_;
- #endif
-
-   DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl);
-diff --git src/content/common/content_message_generator.h src/content/common/content_message_generator.h
-index 78e7c53..a3cda01 100644
---- src/content/common/content_message_generator.h
-+++ src/content/common/content_message_generator.h
-@@ -57,3 +57,6 @@
- #include "content/common/view_messages.h"
- #include "content/common/websocket_messages.h"
- #include "content/common/worker_messages.h"
-+#if defined(OS_TIZEN_MOBILE)
-+#include "xwalk/tizen/common/media_player_messages.h"
-+#endif
-diff --git src/content/content_browser.gypi src/content/content_browser.gypi
-index 6570d15..d47cee2 100644
---- src/content/content_browser.gypi
-+++ src/content/content_browser.gypi
-@@ -1641,5 +1641,69 @@
-         'browser/geolocation/wifi_data_provider_linux.cc',
-       ],
-     }],
-+    ['tizen_mobile == 1', {
-+      'sources': [
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager.cc',
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager.h',
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager_init.cc',
-+        '<(DEPTH)/xwalk/tizen/browser/audio_session_manager_init.h',
-+        '<(DEPTH)/xwalk/tizen/browser/browser_mediaplayer_manager.cc',
-+        '<(DEPTH)/xwalk/tizen/browser/browser_mediaplayer_manager.h',
-+      ],
-+      'variables': {
-+        'generate_stubs_script': '../tools/generate_stubs/generate_stubs.py',
-+        'extra_header': '../xwalk/tizen/browser/audio_session_manager_stub_headers.fragment',
-+        'sig_files': ['../xwalk/tizen/browser/audio_session_manager.sigs'],
-+        'outfile_type': 'posix_stubs',
-+        'stubs_filename_root': 'audio_session_manager_stubs',
-+        'project_path': 'xwalk/tizen/browser',
-+        'intermediate_dir': '<(INTERMEDIATE_DIR)',
-+        'output_root': '<(SHARED_INTERMEDIATE_DIR)/audio_session_manager',
-+      },
-+      'include_dirs': [
-+        '<(output_root)',
-+      ],
-+      'actions': [
-+        {
-+          'action_name': 'generate_stubs',
-+          'inputs': [
-+          '<(generate_stubs_script)',
-+          '<(extra_header)',
-+          '<@(sig_files)',
-+          ],
-+          'outputs': [
-+            '<(intermediate_dir)/<(stubs_filename_root).cc',
-+            '<(output_root)/<(project_path)/<(stubs_filename_root).h',
-+          ],
-+          'action': ['python',
-+            '<(generate_stubs_script)',
-+            '-i', '<(intermediate_dir)',
-+            '-o', '<(output_root)/<(project_path)',
-+            '-t', '<(outfile_type)',
-+            '-e', '<(extra_header)',
-+            '-s', '<(stubs_filename_root)',
-+            '-p', '<(project_path)',
-+            '<@(_inputs)',
-+          ],
-+          'process_outputs_as_sources': 1,
-+          'message': 'Generating audio session manager stubs for dynamic loading',
-+        },
-+      ],
-+      'conditions': [
-+        ['OS=="linux" or OS=="solaris"', {
-+          'link_settings': {
-+            'libraries': [
-+            '-ldl',
-+            ],
-+          },
-+        }],
-+      ],
-+      'dependencies': [
-+        '../build/linux/system.gyp:audio_session_manager',
-+      ],
-+      'export_dependent_settings': [
-+        '../build/linux/system.gyp:audio_session_manager',
-+      ],
-+    }],
-   ],
- }
-diff --git src/content/content_common.gypi src/content/content_common.gypi
-index 1bfcccd..46db168 100644
---- src/content/content_common.gypi
-+++ src/content/content_common.gypi
-@@ -656,5 +656,10 @@
-     }, {
-       'defines': ['USE_SECCOMP_BPF'],
-     }],
-+    ['tizen_mobile == 1', {
-+      'sources': [
-+        '<(DEPTH)/xwalk/tizen/common/media_player_messages.h',
-+      ],
-+    }],
-     ['OS=="win" and directxsdk_exists=="True"', {
-       'actions': [
-       {
-diff --git src/content/content_renderer.gypi src/content/content_renderer.gypi
-index 1e72a81..3bceb70 100644
---- src/content/content_renderer.gypi
-+++ src/content/content_renderer.gypi
-@@ -752,6 +752,14 @@
-         }],
-       ],
-     }],
-+    ['tizen_mobile == 1', {
-+      'sources': [
-+        '<(DEPTH)/xwalk/tizen/renderer/mediaplayer_impl.cc',
-+        '<(DEPTH)/xwalk/tizen/renderer/mediaplayer_impl.h',
-+        '<(DEPTH)/xwalk/tizen/renderer/renderer_mediaplayer_manager.cc',
-+        '<(DEPTH)/xwalk/tizen/renderer/renderer_mediaplayer_manager.h',
-+      ],
-+    }],
-   ],
-   'target_conditions': [
-     ['OS=="android"', {
-diff --git src/content/renderer/render_view_impl.cc src/content/renderer/render_view_impl.cc
-index c5a7059..cd42b4c 100644
---- src/content/renderer/render_view_impl.cc
-+++ src/content/renderer/render_view_impl.cc
-@@ -245,6 +245,11 @@
- #include "content/renderer/media/rtc_peer_connection_handler.h"
- #endif
-
-+#if defined(OS_TIZEN_MOBILE)
-+#include "xwalk/tizen/renderer/mediaplayer_impl.h"
-+#include "xwalk/tizen/renderer/renderer_mediaplayer_manager.h"
-+#endif
-+
- using blink::WebAXObject;
- using blink::WebApplicationCacheHost;
- using blink::WebApplicationCacheHostClient;
-@@ -844,6 +849,8 @@ RenderViewImpl::RenderViewImpl(RenderViewImplParams* params)
-       body_background_color_(SK_ColorWHITE),
-       expected_content_intent_id_(0),
-       media_player_manager_(NULL),
-+#elif defined(OS_TIZEN_MOBILE)
-+      media_player_manager_(NULL),
- #endif
- #if defined(OS_WIN)
-       focused_plugin_id_(-1),
-@@ -967,6 +974,8 @@ void RenderViewImpl::Initialize(RenderViewImplParams* params) {
- #if defined(OS_ANDROID)
-   media_player_manager_ = new RendererMediaPlayerManager(this);
-   new JavaBridgeDispatcher(this);
-+#elif defined(OS_TIZEN_MOBILE)
-+  media_player_manager_ = new tizen::RendererMediaPlayerManager(this);
- #endif
-
-   // The next group of objects all implement RenderViewObserver, so are deleted
-@@ -3044,6 +3053,13 @@ blink::WebMediaPlayer* RenderViewImpl::CreateMediaPlayer(
-                  base::Unretained(GetContentClient()->renderer()),
-                  static_cast<RenderFrame*>(render_frame)),
-       sink);
-+
-+#if defined(OS_TIZEN_MOBILE)
-+  tizen::MediaPlayerImpl* media_player = new tizen::MediaPlayerImpl(
-+      frame, client, AsWeakPtr(), media_player_manager_, params);
-+  return media_player;
-+#endif
-+
-   return new WebMediaPlayerImpl(frame, client, AsWeakPtr(), params);
- #endif  // defined(OS_ANDROID)
- }
-diff --git src/content/renderer/render_view_impl.h src/content/renderer/render_view_impl.h
-index ccfd1b5..8949cd0 100644
---- src/content/renderer/render_view_impl.h
-+++ src/content/renderer/render_view_impl.h
-@@ -128,6 +128,12 @@ namespace webkit_glue {
- class WebURLResponseExtraDataImpl;
- }
-
-+#if defined(OS_TIZEN_MOBILE)
-+namespace tizen {
-+class RendererMediaPlayerManager;
-+}
-+#endif
-+
- namespace content {
- class BrowserPluginManager;
- class DeviceOrientationDispatcher;
-@@ -1403,6 +1409,10 @@ class CONTENT_EXPORT RenderViewImpl
-
-   // A date/time picker object for date and time related input elements.
-   scoped_ptr<RendererDateTimePicker> date_time_picker_client_;
-+#elif defined(OS_TIZEN_MOBILE)
-+  // The media player manager for managing all the media players on this view
-+  // and for communicating with the audio session manager in browser process.
-+  tizen::RendererMediaPlayerManager* media_player_manager_;
- #endif
-
-   // Plugins -------------------------------------------------------------------
index de425ce..7dd4b67 100644 (file)
@@ -16,9 +16,9 @@
 %endif
 
 Name:           crosswalk
-Version:        9.38.198.0
+Version:        9.38.204.0
 Release:        0
-Summary:        Crosswalk is an app runtime based on Chromium
+Summary:        Chromium-based app runtime
 License:        (BSD-3-Clause and LGPL-2.1+)
 Group:          Web Framework/Web Run Time
 Url:            https://github.com/otcshare/crosswalk
@@ -89,6 +89,11 @@ BuildRequires:  pkgconfig(xt)
 BuildRequires:  pkgconfig(xtst)
 %endif
 
+%if "%{profile}" == "ivi"
+BuildRequires:  pkgconfig(murphy-common)
+BuildRequires:  pkgconfig(murphy-resource)
+%endif
+
 %if %{with wayland}
 BuildRequires:  pkgconfig(wayland-client)
 BuildRequires:  pkgconfig(wayland-cursor)
@@ -167,7 +172,7 @@ if [ -n "${BUILDDIR_NAME}" ]; then
 fi
 
 %if %{with wayland}
-GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Duse_ozone=1 -Denable_ozone_wayland_vkb=1 -Denable_xdg_shell=0"
+GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Duse_ozone=1 -Denable_ozone_wayland_vkb=1 -Denable_xdg_shell=1"
 %endif
 
 GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Ddisable_nacl=%{_disable_nacl}"
@@ -195,6 +200,10 @@ export CXXFLAGS=`echo $CXXFLAGS | sed s,-mfpu=vfpv3,-mfpu=neon,g`
 export FFLAGS=`echo $FFLAGS | sed s,-mfpu=vfpv3,-mfpu=neon,g`
 %endif
 
+%if "%{profile}" == "ivi"
+GYP_EXTRA_FLAGS="${GYP_EXTRA_FLAGS} -Denable_murphy=1"
+%endif
+
 # --no-parallel is added because chroot does not mount a /dev/shm, this will
 # cause python multiprocessing.SemLock error.
 export GYP_GENERATORS='ninja'
@@ -236,7 +245,7 @@ install -p -D src/out/Release/icudtl.dat %{buildroot}%{_libdir}/xwalk/icudtl.dat
 install -p -D src/out/Release/libffmpegsumo.so %{buildroot}%{_libdir}/xwalk/libffmpegsumo.so
 install -p -D src/out/Release/xwalk.pak %{buildroot}%{_libdir}/xwalk/xwalk.pak
 mkdir -p %{buildroot}%{_datadir}/xwalk
-install -p -D src/xwalk/application/common/installer/tizen/configuration/*.xsd %{buildroot}%{_datadir}/xwalk/
+install -p -D src/xwalk/application/common/tizen/configuration/*.xsd %{buildroot}%{_datadir}/xwalk/
 
 # PNaCl
 %if ! %{_disable_nacl}
index 0e2f345..4018075 100644 (file)
@@ -4,4 +4,5 @@ Description=Crosswalk
 [Service]
 Type=dbus
 BusName=org.crosswalkproject.Runtime1
+Environment=OZONE_WAYLAND_USE_XDG_SHELL='defined'
 ExecStart=@LIB_INSTALL_DIR@/xwalk/xwalk --external-extensions-path=@LIB_INSTALL_DIR@/tizen-extensions-crosswalk
diff --git a/src/xwalk/runtime/android/core/src/org/xwalk/core/SharedXWalkExceptionHandler.java b/src/xwalk/runtime/android/core/src/org/xwalk/core/SharedXWalkExceptionHandler.java
new file mode 100644 (file)
index 0000000..9d09489
--- /dev/null
@@ -0,0 +1,14 @@
+// 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;
+
+public abstract class SharedXWalkExceptionHandler {
+    boolean handleException(Throwable e) {
+        onSharedLibraryNotFound();
+        return true;
+    }
+
+    public abstract void onSharedLibraryNotFound();
+}
diff --git a/src/xwalk/runtime/android/core/src/org/xwalk/core/SharedXWalkView.java b/src/xwalk/runtime/android/core/src/org/xwalk/core/SharedXWalkView.java
new file mode 100644 (file)
index 0000000..7d8f349
--- /dev/null
@@ -0,0 +1,32 @@
+// 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;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * The XWalkView that allows to use Crosswalk's shared library.
+ */
+public class SharedXWalkView extends XWalkView {
+    public SharedXWalkView(Context context, AttributeSet attrs,
+            SharedXWalkExceptionHandler handler) {
+        super(verifyActivity(context, handler), attrs);
+    }
+
+    public SharedXWalkView(Context context, Activity activity,
+            SharedXWalkExceptionHandler handler) {
+        super(context, verifyActivity(activity, handler));
+    }
+
+    private static Activity verifyActivity(Context context, SharedXWalkExceptionHandler handler) {
+        assert context instanceof Activity;
+        assert context.getApplicationContext() instanceof XWalkApplication;
+        ReflectionHelper.allowCrossPackage();
+        ReflectionHelper.setExceptionHandler(handler);
+        return (Activity) context;
+    }
+}
@@ -2,19 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.app.runtime;
+package org.xwalk.core;
 
 import android.app.Application;
+import android.content.Context;
 import android.content.res.Resources;
 
 /**
- * XWalkRuntimeApplication is to support cross package resource loading.
+ * XWalkApplication is to support cross package resource loading.
  * It provides method to allow overriding getResources() behavior.
  */
-public class XWalkRuntimeApplication extends Application {
+public class XWalkApplication extends Application {
+    private static XWalkApplication gApp = null;
     private Resources mRes = null;
 
     @Override
+    public void onCreate(){
+        super.onCreate();
+        gApp = this;
+    }
+
+    @Override
     public Resources getResources() {
         return mRes == null ? super.getResources() : mRes;
     }
@@ -23,4 +31,8 @@ public class XWalkRuntimeApplication extends Application {
         if (mRes != null) return;
         mRes = new XWalkMixedResources(super.getResources(), res);
     }
+
+    static XWalkApplication getApplication() {
+        return gApp;
+    }
 }
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.app.runtime;
+package org.xwalk.core;
 
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.runtime;
+package org.xwalk.core.internal;
 
 import android.content.Context;
 import android.content.ContextWrapper;
index 414a4ab..1387183 100644 (file)
@@ -10,6 +10,9 @@ import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.HashMap;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
+
 /**
  * This class is used to encapsulate the reflection invoking for bridge and wrapper.
  *
@@ -63,20 +66,76 @@ public class ReflectionHelper {
     private static Map<String, ConstructorHelper> sConstructorHelperMap =
             new HashMap<String, ConstructorHelper>();
     private static ClassLoader sBridgeOrWrapperLoader = null;
+    private static Context sBridgeContext = null;
     private static boolean sIsWrapper;
     private final static String INTERNAL_PACKAGE = "org.xwalk.core.internal";
+    private final static String LIBRARY_APK_PACKAGE = "org.xwalk.core";
+    /* Wrapper Only
+    private static boolean sAllowCrossPackage = false;
+    private static SharedXWalkExceptionHandler sExceptionHandler = null;
+
+    static void setExceptionHandler(SharedXWalkExceptionHandler handler) {
+        sExceptionHandler = handler;
+    }
+
+    public static boolean shouldUseLibrary() {
+        // TODO(wang16): There are many other conditions here.
+        // e.g. Whether application uses the ApplicationClass we provided,
+        //      Whether native library arch is correct.
+        assert isWrapper();
+        try {
+            ReflectionHelper.class.getClassLoader().loadClass(
+                    INTERNAL_PACKAGE + "." + "ReflectionHelper");
+            return false;
+        } catch (ClassNotFoundException e) {
+            return true;
+        }
+    }
+    Wrapper Only */
+
+    public static Context getBridgeContext() {
+        return sBridgeContext;
+    }
+
+    /* Wrapper Only
+    public static void allowCrossPackage() {
+        sAllowCrossPackage = true;
+    }
+    Wrapper Only */
 
-    public static void init(boolean crossPackage) {
+    public static void init() {
         assert isWrapper();
-        if (!crossPackage) {
-            initClassLoader(ReflectionHelper.class.getClassLoader());
+        /* Wrapper Only
+        if (shouldUseLibrary()) {
+            if (!sAllowCrossPackage) {
+                handleException("Use SharedXWalkView if you want to support shared mode");
+            }
+            XWalkApplication app = XWalkApplication.getApplication();
+            if (app == null) {
+                // TODO(wang16): Handle this well.
+                handleException("Shared mode requires XWalkApplication");
+                return;
+            }
+            try {
+                sBridgeContext = app.createPackageContext(
+                        LIBRARY_APK_PACKAGE,
+                        Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+            } catch (PackageManager.NameNotFoundException e) {
+                handleException(e);
+            }
+            if (sBridgeContext != null) {
+                app.addResource(sBridgeContext.getResources());
+                initClassLoader(sBridgeContext.getClassLoader(), sBridgeContext);
+            }
         } else {
-            // TODO(wang16): Support shared mode and initClassLoader cross package.
+            initClassLoader(ReflectionHelper.class.getClassLoader(), null);
         }
+        Wrapper Only */
     }
 
-    public static void initClassLoader(ClassLoader loader) {
+    public static void initClassLoader(ClassLoader loader, Context bridgeContext) {
         sBridgeOrWrapperLoader = loader;
+        sBridgeContext = bridgeContext;
         sBridgeWrapperMap.clear();
         sConstructorMap.clear();
         try {
@@ -89,8 +148,9 @@ public class ReflectionHelper {
                 // with wrapper's classloader via reflection.
                 Class<?> helperInBridge =
                         sBridgeOrWrapperLoader.loadClass(INTERNAL_PACKAGE + "." + "ReflectionHelper");
-                Method initInBridge = helperInBridge.getMethod("initClassLoader", ClassLoader.class);
-                initInBridge.invoke(null, ReflectionHelper.class.getClassLoader());
+                Method initInBridge = helperInBridge.getMethod(
+                        "initClassLoader", ClassLoader.class, Context.class);
+                initInBridge.invoke(null, ReflectionHelper.class.getClassLoader(), sBridgeContext);
             } else {
                 // JavascriptInterface is an annotation class bridge will use but declared in
                 // wrapper.
@@ -115,7 +175,8 @@ public class ReflectionHelper {
     public static Class<?> loadClass(String clazz) {
         // Any embedder using Embedding API should only use the exposed APIs which are
         // in wrapper, so the initialization process is always starting from wrapper.
-        if (sBridgeOrWrapperLoader == null) init(false);
+        if (sBridgeOrWrapperLoader == null) init();
+        if (sBridgeOrWrapperLoader == null) return null;
         try {
             return sBridgeOrWrapperLoader.loadClass(clazz);
         } catch (ClassNotFoundException e) {
@@ -125,6 +186,7 @@ public class ReflectionHelper {
     }
 
     public static Method loadMethod(Class<?> clazz, String name, Object... paramTypes) {
+        if (sBridgeOrWrapperLoader == null) return null;
         Class<?>[] params = new Class<?>[paramTypes.length];
         for (int i = 0; i < paramTypes.length; i++) {
             Object type = paramTypes[i];
@@ -144,6 +206,11 @@ public class ReflectionHelper {
 
     public static void handleException(Exception e) {
         e.printStackTrace();
+        /* Wrapper Only
+        if (isWrapper() && sExceptionHandler != null) {
+            if (sExceptionHandler.handleException(e)) return;
+        }
+        Wrapper Only */
         throw new RuntimeException(e);
     }
 
@@ -178,6 +245,7 @@ public class ReflectionHelper {
     }
 
     public static Object invokeMethod(Method m, Object instance, Object... parameters) {
+        if (sBridgeOrWrapperLoader == null) return null;
         Object ret = null;
         if (m != null) {
             try {
@@ -197,6 +265,7 @@ public class ReflectionHelper {
 
     // Convert between wrapper and bridge instance.
     public static Object getBridgeOrWrapper(Object instance) {
+        if (sBridgeOrWrapperLoader == null) return null;
         if (instance == null) return null;
         Class<?> clazz = instance.getClass();
         Method method = sBridgeWrapperMap.get(clazz);
index 930ec01..0b98200 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.xwalk.core.internal.extension;
+package org.xwalk.core.internal;
 
 import android.os.Environment;
 
index 10b3ca3..c5cf72a 100644 (file)
@@ -135,6 +135,12 @@ public class XWalkPreferencesInternal {
      */
     static final String ENABLE_JAVASCRIPT = "enable-javascript";
 
+    /**
+     * The key string to enable/disable xwalk extensions.
+     *
+     */
+    static final String ENABLE_EXTENSIONS = "enable-extensions";
+
     static {
         sPrefMap.put(REMOTE_DEBUGGING, new PreferenceValue(false));
         sPrefMap.put(ANIMATABLE_XWALK_VIEW, new PreferenceValue(false));
@@ -143,6 +149,7 @@ public class XWalkPreferencesInternal {
         sPrefMap.put(
                 ALLOW_UNIVERSAL_ACCESS_FROM_FILE, new PreferenceValue(false));
         sPrefMap.put(SUPPORT_MULTIPLE_WINDOWS, new PreferenceValue(true));
+        sPrefMap.put(ENABLE_EXTENSIONS, new PreferenceValue(true));
     }
 
     /**
index 1847d98..fbc91f4 100644 (file)
@@ -30,9 +30,7 @@ import org.chromium.base.ActivityState;
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ApplicationStatus.ActivityStateListener;
 import org.chromium.base.CommandLine;
-
-import org.xwalk.core.internal.extension.XWalkExtensionManager;
-import org.xwalk.core.internal.extension.XWalkPathHelper;
+import org.xwalk.core.internal.extension.BuiltinXWalkExtensions;
 
 /**
  * <p>XWalkViewInternal represents an Android view for web apps/pages. Thus most of attributes
@@ -151,7 +149,6 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
     private XWalkContent mContent;
     private Activity mActivity;
     private Context mContext;
-    private XWalkExtensionManager mExtensionManager;
     private boolean mIsHidden;
     private XWalkActivityStateListener mActivityStateListener;
 
@@ -177,15 +174,17 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
     @XWalkAPI(preWrapperLines = {
                   "        super(${param1}, ${param2});"},
               postWrapperLines = {
+                  "        if (bridge == null) return;",
                   "        addView((FrameLayout)bridge, new FrameLayout.LayoutParams(",
                   "                FrameLayout.LayoutParams.MATCH_PARENT,",
                   "                FrameLayout.LayoutParams.MATCH_PARENT));"})
     public XWalkViewInternal(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        super(convertContext(context), attrs);
 
         checkThreadSafety();
-        mContext = context;
-        init(context, attrs);
+        mActivity = (Activity) context;
+        mContext = getContext();
+        init(mContext, attrs);
     }
 
     /**
@@ -198,17 +197,31 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
     @XWalkAPI(preWrapperLines = {
                   "        super(${param1}, null);"},
               postWrapperLines = {
+                  "        if (bridge == null) return;",
                   "        addView((FrameLayout)bridge, new FrameLayout.LayoutParams(",
                   "                FrameLayout.LayoutParams.MATCH_PARENT,",
                   "                FrameLayout.LayoutParams.MATCH_PARENT));"})
     public XWalkViewInternal(Context context, Activity activity) {
-        super(context, null);
-        checkThreadSafety();
+        super(convertContext(context), null);
 
+        checkThreadSafety();
         // Make sure mActivity is initialized before calling 'init' method.
         mActivity = activity;
-        mContext = context;
-        init(context, null);
+        mContext = getContext();
+        init(mContext, null);
+    }
+
+    private static Context convertContext(Context context) {
+        Context ret = context;
+        Context bridgeContext = ReflectionHelper.getBridgeContext();
+        if (bridgeContext == null || context == null ||
+                bridgeContext.getPackageName().equals(context.getPackageName())) {
+            // Not acrossing package
+            ret = context;
+        } else {
+            ret = new MixedContext(bridgeContext, context);
+        }
+        return ret;
     }
 
     /**
@@ -347,10 +360,9 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
         setNotificationService(new XWalkNotificationServiceImpl(context, this));
 
         if (!CommandLine.getInstance().hasSwitch("disable-xwalk-extensions")) {
-            // Enable xwalk extension mechanism and start load extensions here.
-            // Note that it has to be after above initialization.
-            mExtensionManager = new XWalkExtensionManager(context, getActivity());
-            mExtensionManager.loadExtensions();
+            BuiltinXWalkExtensions.load(context, getActivity());
+        } else {
+            XWalkPreferencesInternal.setValue(XWalkPreferencesInternal.ENABLE_EXTENSIONS, false);
         }
 
         XWalkPathHelper.initialize();
@@ -635,8 +647,6 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
     @XWalkAPI
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (mContent == null) return;
-        if (null != mExtensionManager)
-                mExtensionManager.onActivityResult(requestCode, resultCode, data);
         mContent.onActivityResult(requestCode, resultCode, data);
     }
 
@@ -809,7 +819,6 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
         if (mContent == null) return;
         ApplicationStatus.unregisterActivityStateListener(mActivityStateListener);
         mActivityStateListener = null;
-        if (null != mExtensionManager) mExtensionManager.onDestroy();
         mContent.destroy();
         disableRemoteDebugging();
     }
@@ -923,22 +932,18 @@ public class XWalkViewInternal extends android.widget.FrameLayout {
         switch (newState) {
             case ActivityState.STARTED:
                 onShow();
-                if (null != mExtensionManager) mExtensionManager.onStart();
                 break;
             case ActivityState.PAUSED:
                 pauseTimers();
-                if (null != mExtensionManager) mExtensionManager.onPause();
                 break;
             case ActivityState.RESUMED:
                 resumeTimers();
-                if (null != mExtensionManager) mExtensionManager.onResume();
                 break;
             case ActivityState.DESTROYED:
                 onDestroy();
                 break;
             case ActivityState.STOPPED:
                 onHide();
-                if (null != mExtensionManager) mExtensionManager.onStop();
                 break;
             default:
                 break;
index ea468ec..fe5e303 100644 (file)
@@ -43,7 +43,7 @@ class XWalkWebContentsDelegateAdapter extends XWalkWebContentsDelegate {
 
     @Override
     public void activateContents() {
-        // TODO: implement.
+        if (mXWalkContentsClient != null) mXWalkContentsClient.onRequestFocus();
     }
 
     @Override
diff --git a/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/BuiltinXWalkExtensions.java b/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/BuiltinXWalkExtensions.java
new file mode 100644 (file)
index 0000000..d3a0305
--- /dev/null
@@ -0,0 +1,130 @@
+// 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.internal.extension;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+import org.xwalk.core.internal.XWalkExtensionInternal;
+import org.xwalk.core.internal.extension.api.contacts.Contacts;
+import org.xwalk.core.internal.extension.api.device_capabilities.DeviceCapabilities;
+import org.xwalk.core.internal.extension.api.launchscreen.LaunchScreenExtension;
+import org.xwalk.core.internal.extension.api.messaging.Messaging;
+import org.xwalk.core.internal.extension.api.presentation.PresentationExtension;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.util.Log;
+
+public class BuiltinXWalkExtensions {
+    private static final String TAG = "BuiltinXWalkExtension";
+    private static HashMap<String, XWalkExtensionInternal> sBuiltinExtensions =
+            new HashMap<String, XWalkExtensionInternal>();
+
+    public static void load(Context context, Activity activity) {
+        // Create all built-in extension instances here.
+        {
+            String jsApiContent = "";
+            try {
+                jsApiContent = getExtensionJSFileContent(
+                        context, PresentationExtension.JS_API_PATH, true);
+                sBuiltinExtensions.put(PresentationExtension.JS_API_PATH,
+                        new PresentationExtension(jsApiContent, activity));
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to read JS API file: " + PresentationExtension.JS_API_PATH);
+            }
+        }
+
+        {
+            String jsApiContent = "";
+            try {
+                jsApiContent = getExtensionJSFileContent(
+                        context, LaunchScreenExtension.JS_API_PATH, true);
+                sBuiltinExtensions.put(LaunchScreenExtension.JS_API_PATH,
+                        new LaunchScreenExtension(jsApiContent, activity));
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to read JS API file: " + LaunchScreenExtension.JS_API_PATH);
+            }
+        }
+
+        {
+            String jsApiContent = "";
+            try {
+                jsApiContent = getExtensionJSFileContent(
+                        context, Contacts.JS_API_PATH, true);
+                sBuiltinExtensions.put(Contacts.JS_API_PATH,
+                        new Contacts(jsApiContent, activity));
+            } catch(IOException e) {
+                Log.w(TAG, "Failed to read JS API file: " + Contacts.JS_API_PATH);
+            }
+        }
+
+        {
+            String jsApiContent = "";
+            try {
+                jsApiContent = getExtensionJSFileContent(
+                        context, DeviceCapabilities.JS_API_PATH, true);
+                sBuiltinExtensions.put(DeviceCapabilities.JS_API_PATH,
+                        new DeviceCapabilities(jsApiContent, activity));
+            } catch(IOException e) {
+                Log.w(TAG, "Failed to read JS API file: " + DeviceCapabilities.JS_API_PATH);
+            }
+        }
+
+        {
+            String jsApiContent = "";
+            try {
+                jsApiContent = getExtensionJSFileContent(
+                        context, Messaging.JS_API_PATH, true);
+                sBuiltinExtensions.put(Messaging.JS_API_PATH,
+                        new Messaging(jsApiContent, activity));
+            } catch(IOException e) {
+                Log.w(TAG, "Failed to read JS API file: " + Messaging.JS_API_PATH);
+            }
+        }
+    }
+
+
+    private static String getExtensionJSFileContent(Context context, String fileName, boolean fromRaw)
+            throws IOException {
+        String result = "";
+        InputStream inputStream = null;
+        try {
+            if (fromRaw) {
+                // If fromRaw is true, Try to find js file in res/raw first.
+                // And then try to get it from assets if failed.
+                Resources resource = context.getResources();
+                String resName = (new File(fileName).getName().split("\\."))[0];
+                int resId = resource.getIdentifier(resName, "raw", context.getPackageName());
+                if (resId > 0) {
+                    try {
+                        inputStream = resource.openRawResource(resId);
+                    } catch (NotFoundException e) {
+                        Log.w(TAG, "Inputstream failed to open for R.raw." + resName +
+                                   ", try to find it in assets");
+                    }
+                }
+            }
+            if (inputStream == null) {
+                AssetManager assetManager = context.getAssets();
+                inputStream = assetManager.open(fileName);
+            }
+            int size = inputStream.available();
+            byte[] buffer = new byte[size];
+            inputStream.read(buffer);
+            result = new String(buffer);
+        } finally {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtension.java b/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtension.java
deleted file mode 100644 (file)
index 01302f6..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2013 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.internal.extension;
-
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * The public base class of xwalk extensions. Each extension should inherit
- * this class and implement its interfaces. Note that it's for every extensions.
- * For internal extensions, each one should base on it directly. For external
- * extensions, there'll be a bridge class in the runtime client side.
- */
-public abstract class XWalkExtension {
-    // The unique name for this extension.
-    protected String mName;
-
-    // The JavaScript code stub. Will be injected to JS engine.
-    protected String mJsApi;
-
-    // The entry points are used when extension needs to have objects outside
-    // the namespace that is implicitly created using its name.
-    protected String[] mEntryPoints;
-
-    // The context used by extensions.
-    protected XWalkExtensionContext mExtensionContext;
-
-    /**
-     * Constructor with the information of an extension.
-     * @param name the extension name.
-     * @param apiVersion the version of API.
-     * @param jsApi the code stub of JavaScript for this extension.
-     * @param context the extension context.
-     */
-    public XWalkExtension(String name, String jsApi, XWalkExtensionContext context) {
-        mName = name;
-        mJsApi = jsApi;
-        mEntryPoints = null;
-        mExtensionContext = context;
-        mExtensionContext.registerExtension(this);
-    }
-
-    /**
-     * Constructor with the information of an extension.
-     * @param name the extension name.
-     * @param apiVersion the version of API.
-     * @param jsApi the code stub of JavaScript for this extension.
-     * @param entryPoints the entry points of JavaScript for this extension.
-     * @param context the extension context.
-     */
-    public XWalkExtension(String name, String jsApi, String[] entryPoints, XWalkExtensionContext context) {
-        mName = name;
-        mJsApi = jsApi;
-        mEntryPoints = entryPoints;
-        mExtensionContext = context;
-        mExtensionContext.registerExtension(this);
-    }
-
-    /**
-     * Get the unique name of extension.
-     * @return the name of extension set from constructor.
-     */
-    public String getExtensionName() {
-        return mName;
-    }
-
-    /**
-     * Get the JavaScript code stub.
-     * @return the JavaScript code stub.
-     */
-    public String getJsApi() {
-        return mJsApi;
-    }
-
-    /**
-     * Get the entry points of extension.
-     * @return the entry points.
-     */
-    public String[] getEntryPoints() {
-        return mEntryPoints;
-    }
-
-    /**
-     * JavaScript calls into Java code. The message is handled by
-     * the extension implementation. The inherited classes should
-     * override and add its implementation.
-     * @param instanceID the ID of extension instance where the message came from.
-     * @param message the message from JavaScript code.
-     */
-    public abstract void onMessage(int instanceID, String message);
-
-    /**
-     * Synchronized JavaScript calls into Java code. Similar to
-     * onMessage. The only difference is it's a synchronized
-     * message.
-     * @param instanceID the ID of extension instance where the message came from.
-     * @param message the message from JavaScript code.
-     */
-    public String onSyncMessage(int instanceID, String message) {
-        return null;
-    }
-
-    /**
-     * Post messages to JavaScript via extension's context.
-     * It's used by child classes to post message from Java side
-     * to JavaScript side.
-     * @param instanceID the ID of target extension instance.
-     * @param message the message to be passed to Javascript.
-     */
-    public final void postMessage(int instanceID, String message) {
-        mExtensionContext.postMessage(this, instanceID, message);
-    }
-
-    /**
-     * Broadcast messages to JavaScript via extension's context.
-     * It's used by child classes to broad message from Java side
-     * to all JavaScript side instances of the extension.
-     * @param message the message to be passed to Javascript.
-     */
-    public final void broadcastMessage(String message) {
-        mExtensionContext.broadcastMessage(this, message);
-    }
-
-    /**
-     * Called when this app is onStart.
-     */
-    public void onStart() {
-    }
-
-    /**
-     * Called when this app is onResume.
-     */
-    public void onResume() {
-    }
-
-    /**
-     * Called when this app is onPause.
-     */
-    public void onPause() {
-    }
-
-    /**
-     * Called when this app is onStop.
-     */
-    public void onStop() {
-    }
-
-    /**
-     * Called when this app is onDestroy.
-     */
-    public void onDestroy() {
-    }
-
-    /**
-     * Tell extension that one activity exists so that it can know the result
-     * of the exit code.
-     */
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-    }
-}
diff --git a/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionClientImpl.java b/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionClientImpl.java
deleted file mode 100644 (file)
index f0f3745..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2013 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.internal.extension;
-
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * The public base class of xwalk external extensions. It acts a bridge class from
- * runtime to runtime client. The objects of class 'XWalkExtensionClient' in runtime
- * client side will be passed into this class because we need to call its methods.
- */
-class XWalkExtensionClientImpl extends XWalkExtension {
-
-    private static final String TAG = XWalkExtensionClientImpl.class.getName();
-    private Object mExtensionClient;
-    private Method mOnMessage;
-    private Method mOnSyncMessage;
-    private Method mOnStart;
-    private Method mOnResume;
-    private Method mOnPause;
-    private Method mOnStop;
-    private Method mOnDestroy;
-    private Method mOnActivityResult;
-
-    public XWalkExtensionClientImpl(String name, String jsApi,
-            XWalkExtensionContextWrapper context, Object extensionClient) {
-        super(name, jsApi, context);
-
-        mExtensionClient = extensionClient;
-        mOnMessage = lookupMethod("onMessage", int.class, String.class);
-        mOnSyncMessage = lookupMethod("onSyncMessage", int.class, String.class);
-        mOnStart = lookupMethod("onStart");
-        mOnResume = lookupMethod("onResume");
-        mOnPause = lookupMethod("onPause");
-        mOnStop = lookupMethod("onStop");
-        mOnDestroy = lookupMethod("onDestroy");
-        mOnActivityResult = lookupMethod("onActivityResult", int.class, int.class, Intent.class);
-    }
-
-    @Override
-    public void onMessage(int extensionInstanceID, String message) {
-        invokeMethod(mOnMessage, mExtensionClient, extensionInstanceID, message);
-    }
-
-    @Override
-    public String onSyncMessage(int extensionInstanceID, String message) {
-        return (String) invokeMethod(mOnSyncMessage, mExtensionClient, extensionInstanceID, message);
-    }
-
-    @Override
-    public void onStart() {
-        invokeMethod(mOnStart, mExtensionClient);
-    }
-
-    @Override
-    public void onResume() {
-        invokeMethod(mOnResume, mExtensionClient);
-    }
-
-    @Override
-    public void onPause() {
-        invokeMethod(mOnPause, mExtensionClient);
-    }
-
-    @Override
-    public void onStop() {
-        invokeMethod(mOnStop, mExtensionClient);
-    }
-
-    @Override
-    public void onDestroy() {
-        invokeMethod(mOnDestroy, mExtensionClient);
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        invokeMethod(mOnActivityResult, mExtensionClient, requestCode, resultCode, data);
-    }
-
-    private Method lookupMethod(String method, Class<?>... parameters) {
-        Class<?> clientClass = mExtensionClient.getClass();
-        try {
-            return clientClass.getMethod(method, parameters);
-        } catch (NoSuchMethodException e) {
-            handleException(e);
-        }
-        return null;
-    }
-
-    private static Object invokeMethod(Method method, Object instance, Object... parameters) {
-        Object result = null;
-        if (method != null) {
-            try {
-                result = method.invoke(instance, parameters);
-            } catch (IllegalArgumentException e) {
-                handleException(e);
-            } catch (IllegalAccessException e) {
-                handleException(e);
-            } catch (InvocationTargetException e) {
-                handleException(e);
-            } catch (NullPointerException e) {
-                handleException(e);
-            }
-        }
-        return result;
-    }
-
-    private static void handleException(Exception e) {
-        Log.e(TAG, "Error in calling methods of external extensions. " + e.toString());
-        e.printStackTrace();
-    }
-}
diff --git a/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionContext.java b/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionContext.java
deleted file mode 100644 (file)
index 72d8762..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2013 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.internal.extension;
-
-import android.app.Activity;
-import android.content.Context;
-
-/**
- * Interface for extension context
- *
- * It is responsible for maintaining all xwalk extensions and providing a way to
- * post message to JavaScript side for each xwalk extension.
- */
-public interface XWalkExtensionContext {
-    /**
-     * Register an xwalk extension into context.
-     */
-    public void registerExtension(XWalkExtension extension);
-
-    /**
-     * Unregister an xwalk extension with the given unique name from context.
-     */
-    public void unregisterExtension(String name);
-
-    /**
-     * Post a message to the given extension instance.
-     *
-     * @param extension The xwalk extension
-     * @param instanceId The unique id to identify the extension instance as the
-     *                   message destination.
-     * @param message The message content to be posted.
-     */
-    public void postMessage(XWalkExtension extension, int instanceId, String message);
-
-    /**
-     * Broadcast a message to all extension instances.
-     *
-     * @param extension The xwalk extension
-     * @param message The message content to be broadcasted.
-     */
-    public void broadcastMessage(XWalkExtension extension, String message);
-
-    /**
-     * Get current Android Context.
-     * @return the current Android Context.
-     */
-    public Context getContext();
-
-    /**
-     * Get the current Android Activity.
-     * @return the current Android Activity.
-     */
-    public Activity getActivity();
-}
diff --git a/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionContextWrapper.java b/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionContextWrapper.java
deleted file mode 100644 (file)
index eb08b54..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2013 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.internal.extension;
-
-import android.app.Activity;
-import android.content.Context;
-
-/**
- * This is a public class to provide context for extensions.
- * It'll be shared by all external extensions.
- */
-class XWalkExtensionContextWrapper implements XWalkExtensionContext {
-    private XWalkExtensionContext mOriginContext;
-
-    public XWalkExtensionContextWrapper(XWalkExtensionContext context) {
-        mOriginContext = context;
-    }
-
-    public void registerExtension(XWalkExtension extension) {
-        mOriginContext.registerExtension(extension);
-    }
-
-    public void unregisterExtension(String name) {
-        mOriginContext.unregisterExtension(name);
-    }
-
-    public void postMessage(XWalkExtension extension, int instanceID, String message) {
-        mOriginContext.postMessage(extension, instanceID, message);
-    }
-
-    public void broadcastMessage(XWalkExtension extension, String message) {
-        mOriginContext.broadcastMessage(extension, message);
-    }
-
-    public Context getContext() {
-        // This is very tricky because for external extensions, we should
-        // use Activity which contains the context for runtime client side.
-        // mOriginContext.getContext() returns the context of library package,
-        // e.g., the package context of runtime side.
-        return mOriginContext.getActivity();
-    }
-
-    public Activity getActivity() {
-        return mOriginContext.getActivity();
-    }
-}
diff --git a/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionWithActivityStateListener.java b/src/xwalk/runtime/android/core_internal/src/org/xwalk/core/internal/extension/XWalkExtensionWithActivityStateListener.java
new file mode 100644 (file)
index 0000000..37de6c9
--- /dev/null
@@ -0,0 +1,56 @@
+// 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.internal.extension;
+
+import java.lang.ref.WeakReference;
+
+import org.chromium.base.ApplicationStatus;
+import org.chromium.base.ApplicationStatus.ActivityStateListener;
+import org.xwalk.core.internal.XWalkExtensionInternal;
+import org.xwalk.core.internal.XWalkViewInternal;
+
+import android.app.Activity;
+import android.content.Context;
+
+/**
+ * Base class for internal extensions which cares about host activity's lifecycle.
+ */
+public abstract class XWalkExtensionWithActivityStateListener extends XWalkExtensionInternal {
+
+    private class XWalkActivityStateListener implements ActivityStateListener {
+        WeakReference<XWalkExtensionWithActivityStateListener> mExtensionRef;
+
+        XWalkActivityStateListener(XWalkExtensionWithActivityStateListener extension) {
+            mExtensionRef = new WeakReference<XWalkExtensionWithActivityStateListener>(extension);
+        }
+
+        @Override
+        public void onActivityStateChange(Activity activity, int newState) {
+            XWalkExtensionWithActivityStateListener extension = mExtensionRef.get();
+            if (extension == null) return;
+            extension.onActivityStateChange(activity, newState);
+        }
+    }
+
+    private XWalkActivityStateListener mActivityStateListener;
+
+    private void initActivityStateListener(Activity activity) {
+        mActivityStateListener = new XWalkActivityStateListener(this);
+        ApplicationStatus.registerStateListenerForActivity(mActivityStateListener, activity);
+    }
+
+    public abstract void onActivityStateChange(Activity activity, int newState);
+
+    public XWalkExtensionWithActivityStateListener(String name, String jsApi, Activity activity) {
+        super(name, jsApi);
+        initActivityStateListener(activity);
+    }
+
+    public XWalkExtensionWithActivityStateListener(
+            String name, String jsApi, String[] entryPoints, Activity activity) {
+        super(name, jsApi, entryPoints);
+        initActivityStateListener(activity);
+    }
+}
index b910cae..b2c64d0 100644 (file)
@@ -4,8 +4,10 @@
 
 package org.xwalk.core.internal.extension.api.contacts;
 
+import android.app.Activity;
 import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.OperationApplicationException;
 import android.database.Cursor;
 import android.net.Uri;
@@ -17,14 +19,14 @@ import android.util.Log;
 
 import java.util.ArrayList;
 
+import org.chromium.base.ActivityState;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import org.xwalk.core.internal.extension.XWalkExtension;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
+import org.xwalk.core.internal.extension.XWalkExtensionWithActivityStateListener;
 
-public class Contacts extends XWalkExtension {
+public class Contacts extends XWalkExtensionWithActivityStateListener {
     public static final String JS_API_PATH = "jsapi/contacts_api.js";
 
     private static final String TAG = "Contacts";
@@ -33,13 +35,19 @@ public class Contacts extends XWalkExtension {
     private final ContactEventListener mObserver;
     private final ContentResolver mResolver;
 
-    public Contacts(String jsApiContent, XWalkExtensionContext context) {
-        super(NAME, jsApiContent, context);
-        mResolver = context.getContext().getContentResolver();
+    public Contacts(String jsApiContent, Activity activity) {
+        super(NAME, jsApiContent, activity);
+        mResolver = activity.getContentResolver();
         mObserver = new ContactEventListener(new Handler(), this, mResolver);
         mResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, mObserver);
     }
 
+
+    @Override
+    public String onSyncMessage(int instanceID, String message) {
+        return null;
+    }
+
     @Override
     public void onMessage(int instanceID, String message) {
         if (message.isEmpty()) return;
@@ -89,22 +97,6 @@ public class Contacts extends XWalkExtension {
         }
     }
 
-    @Override
-    public void onResume() {
-        mObserver.onResume();
-        mResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, mObserver);
-    }
-
-    @Override
-    public void onPause() {
-        mResolver.unregisterContentObserver(mObserver);
-    }
-
-    @Override
-    public void onDestroy() {
-        mResolver.unregisterContentObserver(mObserver);
-    }
-
     // Remove all contacts.
     private void handleClear() {
         Cursor c = null;
@@ -121,4 +113,21 @@ public class Contacts extends XWalkExtension {
             if (c != null) c.close();
         }
     }
+
+
+    @Override
+    public void onActivityStateChange(Activity activity, int newState) {
+        switch (newState) {
+            case ActivityState.RESUMED:
+                mObserver.onResume();
+                mResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, mObserver);
+                break;
+            case ActivityState.PAUSED:
+            case ActivityState.DESTROYED:
+                mResolver.unregisterContentObserver(mObserver);
+                break;
+            default:
+                break;
+        }
+    }
 }
index 6ccb6ff..e5a0fc8 100644 (file)
@@ -4,15 +4,18 @@
 
 package org.xwalk.core.internal.extension.api.device_capabilities;
 
+import android.app.Activity;
+import android.content.Context;
+import android.provider.ContactsContract;
 import android.util.Log;
 
-import org.xwalk.core.internal.extension.XWalkExtension;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
+import org.xwalk.core.internal.extension.XWalkExtensionWithActivityStateListener;
 
+import org.chromium.base.ActivityState;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-public class DeviceCapabilities extends XWalkExtension {
+public class DeviceCapabilities extends XWalkExtensionWithActivityStateListener {
     public static final String JS_API_PATH = "jsapi/device_capabilities_api.js";
 
     private static final String TAG = "DeviceCapabilities";
@@ -24,14 +27,16 @@ public class DeviceCapabilities extends XWalkExtension {
     private DeviceCapabilitiesMemory mMemory;
     private DeviceCapabilitiesStorage mStorage;
 
-    public DeviceCapabilities(String jsApiContent, XWalkExtensionContext context) {
-        super(NAME, jsApiContent, context);
+    public DeviceCapabilities(String jsApiContent, Activity activity) {
+        super(NAME, jsApiContent, activity);
 
-        mCPU = new DeviceCapabilitiesCPU(this, context);
-        mCodecs = new DeviceCapabilitiesCodecs(this, context);
+        Context context = activity.getApplicationContext();
+
+        mCPU = new DeviceCapabilitiesCPU(this);
+        mCodecs = new DeviceCapabilitiesCodecs(this);
         mDisplay = new DeviceCapabilitiesDisplay(this, context);
         mMemory = new DeviceCapabilitiesMemory(this, context);
-        mStorage = new DeviceCapabilitiesStorage(this, context);
+        mStorage = new DeviceCapabilitiesStorage(this, activity);
     }
 
     private void handleMessage(int instanceID, String message) {
@@ -102,20 +107,27 @@ public class DeviceCapabilities extends XWalkExtension {
     }
 
     @Override
-    public void onResume() {
-        mDisplay.onResume();
-        mStorage.onResume();
-    }
-
-    @Override
-    public void onPause() {
-        mDisplay.onPause();
-        mStorage.onPause();
+    public void onActivityStateChange(Activity activity, int newState) {
+        switch (newState) {
+            case ActivityState.RESUMED:
+                mDisplay.onResume();
+                mStorage.onResume();
+                break;
+            case ActivityState.PAUSED:
+                mDisplay.onPause();
+                mStorage.onPause();
+                break;
+            case ActivityState.DESTROYED:
+                mDisplay.onDestroy();
+                mStorage.onDestroy();
+                break;
+            default:
+                break;
+        }
     }
 
     @Override
-    public void onDestroy() {
-        mDisplay.onDestroy();
-        mStorage.onDestroy();
+    public String onSyncMessage(int instanceID, String message) {
+        return null;
     }
 }
index 1dcdd43..640c7ef 100644 (file)
@@ -11,7 +11,6 @@ import java.io.IOException;
 
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
 
 class DeviceCapabilitiesCPU {
     private static final String SYSTEM_INFO_STAT_FILE = "/proc/stat";
@@ -23,8 +22,7 @@ class DeviceCapabilitiesCPU {
     private String mCPUArch = "Unknown";
     private double mCPULoad = 0.0;
 
-    public DeviceCapabilitiesCPU(DeviceCapabilities instance,
-                                 XWalkExtensionContext context) {
+    public DeviceCapabilitiesCPU(DeviceCapabilities instance) {
         mDeviceCapabilities = instance;
 
         // Get arch and core number at constructor since they won't change time to time.
index bfb3629..cbe799e 100644 (file)
@@ -5,13 +5,11 @@
 package org.xwalk.core.internal.extension.api.device_capabilities;
 
 import org.json.JSONObject;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
 
 class DeviceCapabilitiesCodecs {
     private XWalkMediaCodec mediaCodec;
 
-    public DeviceCapabilitiesCodecs(DeviceCapabilities instance,
-                                    XWalkExtensionContext context) {
+    public DeviceCapabilitiesCodecs(DeviceCapabilities instance) {
         mediaCodec = XWalkMediaCodec.Create(instance);
     }
 
index a02c239..06996b2 100644 (file)
@@ -15,7 +15,6 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.xwalk.core.internal.extension.api.XWalkDisplayManager;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
 
 class DeviceCapabilitiesDisplay {
     private static final String TAG = "DeviceCapabilitiesDisplay";
@@ -53,9 +52,9 @@ class DeviceCapabilitiesDisplay {
     };
 
     public DeviceCapabilitiesDisplay(DeviceCapabilities instance,
-                                     XWalkExtensionContext context) {
+                                     Context context) {
         mDeviceCapabilities = instance;
-        mDisplayManager = XWalkDisplayManager.getInstance(context.getContext());
+        mDisplayManager = XWalkDisplayManager.getInstance(context);
 
         // Fetch the original display list
         initDisplayList();
index 3a039b4..cc2c8ca 100644 (file)
@@ -15,7 +15,6 @@ import java.io.IOException;
 
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
 
 class DeviceCapabilitiesMemory {
     private static final String MEM_INFO_FILE = "/proc/meminfo";
@@ -28,9 +27,9 @@ class DeviceCapabilitiesMemory {
     private long mCapacity = 0;
 
     public DeviceCapabilitiesMemory(DeviceCapabilities instance,
-                                    XWalkExtensionContext context) {
+                                    Context context) {
         mDeviceCapabilities = instance;
-        mContext = context.getContext();
+        mContext = context;
     }
 
     public JSONObject getInfo() {
index 7ab1a81..caf00b9 100644 (file)
@@ -4,6 +4,7 @@
 
 package org.xwalk.core.internal.extension.api.device_capabilities;
 
+import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -16,17 +17,17 @@ import android.util.Log;
 import android.util.SparseArray;
 
 import java.io.File;
+import java.lang.ref.WeakReference;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
 
 class DeviceCapabilitiesStorage {
     private static final String TAG = "DeviceCapabilitiesStorage";
 
     private DeviceCapabilities mDeviceCapabilities;
-    private XWalkExtensionContext mExtensionContext;
+    private WeakReference<Activity> mActivity;
 
     private static int mStorageCount = 0;
     // Holds all available storages.
@@ -135,9 +136,9 @@ class DeviceCapabilitiesStorage {
     };
 
     public DeviceCapabilitiesStorage(DeviceCapabilities instance,
-                                     XWalkExtensionContext context) {
+                                     Activity activity) {
         mDeviceCapabilities = instance;
-        mExtensionContext = context;
+        mActivity = new WeakReference<Activity>(activity);
 
         registerIntentFilter();
 
@@ -222,7 +223,8 @@ class DeviceCapabilitiesStorage {
         }
 
         mIsListening = true;
-        mExtensionContext.getActivity().registerReceiver(mStorageListener, mIntentFilter);
+        Activity activity = mActivity.get();
+        if (activity != null) activity.registerReceiver(mStorageListener, mIntentFilter);
     }
 
     public void unregisterListener() {
@@ -231,7 +233,8 @@ class DeviceCapabilitiesStorage {
         }
 
         mIsListening = false;
-        mExtensionContext.getActivity().unregisterReceiver(mStorageListener);
+        Activity activity = mActivity.get();
+        if (activity != null) activity.unregisterReceiver(mStorageListener);
     }
 
     private void notifyAndSaveAttachedStorage() {
index b862f92..ad69d37 100644 (file)
@@ -4,17 +4,17 @@
 
 package org.xwalk.core.internal.extension.api.launchscreen;
 
+import android.content.Context;
 import android.content.Intent;
 import android.util.Log;
 
+import org.xwalk.core.internal.XWalkExtensionInternal;
 import org.xwalk.core.internal.XWalkLaunchScreenManager;
-import org.xwalk.core.internal.extension.XWalkExtension;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
 
 /**
  * A XWalk extension for LaunchScreen API implementation on Android.
  */
-public class LaunchScreenExtension extends XWalkExtension {
+public class LaunchScreenExtension extends XWalkExtensionInternal {
     public final static String JS_API_PATH = "jsapi/launch_screen_api.js";
 
     private final static String NAME = "xwalk.launchscreen";
@@ -25,8 +25,11 @@ public class LaunchScreenExtension extends XWalkExtension {
     // Command messages:
     private final static String CMD_HIDE_LAUNCH_SCREEN = "hideLaunchScreen";
 
-    public LaunchScreenExtension(String jsApi, XWalkExtensionContext context) {
-        super(NAME, jsApi, JS_ENTRY_POINTS, context);
+    private Context mContext;
+
+    public LaunchScreenExtension(String jsApi, Context context) {
+        super(NAME, jsApi, JS_ENTRY_POINTS);
+        mContext = context;
     }
 
     @Override
@@ -42,6 +45,11 @@ public class LaunchScreenExtension extends XWalkExtension {
         // Need to be well designed in the future.
         String filterStr = XWalkLaunchScreenManager.getHideLaunchScreenFilterStr();
         Intent intent = new Intent(filterStr);
-        mExtensionContext.getActivity().sendBroadcast(intent);
+        mContext.sendBroadcast(intent);
+    }
+
+    @Override
+    public String onSyncMessage(int instanceID, String message) {
+        return null;
     }
 }
index 9b9dbaa..3107be3 100644 (file)
@@ -16,19 +16,19 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.chromium.base.ActivityState;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.xwalk.core.internal.extension.api.messaging.MessagingManager;
 import org.xwalk.core.internal.extension.api.messaging.MessagingSmsManager;
-import org.xwalk.core.internal.extension.XWalkExtension;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
+import org.xwalk.core.internal.extension.XWalkExtensionWithActivityStateListener;
 
 interface Command {
     void runCommand(int instanceID, JSONObject jsonMsg);
 }
 
-public class Messaging extends XWalkExtension {
+public class Messaging extends XWalkExtensionWithActivityStateListener {
     public static final String JS_API_PATH = "jsapi/messaging_api.js";
 
     private static final String NAME = "xwalk.experimental.messaging";
@@ -99,23 +99,16 @@ public class Messaging extends XWalkExtension {
         }
     }
 
-    public Messaging(String jsApiContent, XWalkExtensionContext context) {
-        super(NAME, jsApiContent, context);
-        mSmsManager = new MessagingSmsManager(mExtensionContext.getActivity(), this);
+    public Messaging(String jsApiContent, Activity activity) {
+        super(NAME, jsApiContent, activity);
+        mSmsManager = new MessagingSmsManager(activity, this);
+        mMessagingManager = new MessagingManager(activity, this);
         mSmsManager.registerIntentFilters();
-        //FIXME:(shawn) When onStart and OnStop are ready. This should be moved to onStart.
-        mMessagingManager = new MessagingManager(mExtensionContext.getActivity(), this);
 
         initMethodMap();
     }
 
     @Override
-    public void onDestroy() {
-        mSmsManager.unregisterIntentFilters();
-        //FIXME:(shawn) When onStart and OnStop are ready. This should be moved to onStop.
-    }
-
-    @Override
     public void onMessage(int instanceID, String message) {
         Command command = sMethodMap.get(getCommandString(message));
 
@@ -136,4 +129,10 @@ public class Messaging extends XWalkExtension {
         }
         return "";
     }
+
+    @Override
+    public void onActivityStateChange(Activity activity, int newState) {
+        if (newState == ActivityState.STOPPED) mSmsManager.unregisterIntentFilters();
+        else if (newState == ActivityState.STARTED) mSmsManager.registerIntentFilters();
+    }
 }
index 627d79e..0a2d61e 100644 (file)
@@ -19,6 +19,7 @@ import android.telephony.TelephonyManager;
 import android.net.Uri; 
 import android.util.Log; 
 
+import java.lang.ref.WeakReference;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 
@@ -34,7 +35,7 @@ public class MessagingSmsManager {
     private final static String EXTRA_MSGTO = "to";
     private final static String EXTRA_MSGINSTANCEID = "instanceid";
     private final static String DEFAULT_SERVICE_ID = "sim0";
-    private final Activity mMainActivity;
+    private final WeakReference<Activity> mActivity;
     private final Messaging mMessagingHandler;
     private BroadcastReceiver mSmsSentReceiver, mSmsDeliveredReceiver,
                               mSmsReceiveReceiver, mSmsServiceReceiver;
@@ -48,13 +49,15 @@ public class MessagingSmsManager {
     }
 
     MessagingSmsManager(Activity activity, Messaging messaging) {
-        mMainActivity = activity;
+        mActivity = new WeakReference<Activity>(activity);
         mMessagingHandler = messaging;
     }
 
     private boolean checkService(String serviceID) {
+        Activity activity = mActivity.get();
+        if (activity == null) return false;
         TelephonyManager tm = 
-            (TelephonyManager)mMainActivity.getSystemService(Context.TELEPHONY_SERVICE);
+            (TelephonyManager) activity.getSystemService(Context.TELEPHONY_SERVICE);
         return (TelephonyManager.SIM_STATE_READY == tm.getSimState());
     }
 
@@ -62,6 +65,9 @@ public class MessagingSmsManager {
         if (!checkService(DEFAULT_SERVICE_ID)) {
             Log.e(TAG, "No Sim Card");
         }
+        Activity activity = mActivity.get();
+        if (activity == null) return;
+
         String asyncCallId = null;
         JSONObject eventBody = null;
         String phone = null;
@@ -84,7 +90,7 @@ public class MessagingSmsManager {
         String instanceIDString = Integer.toString(instanceID);
         intentSmsSent.putExtra(EXTRA_MSGINSTANCEID, instanceIDString);
         int promiseIdInt = Integer.valueOf(asyncCallId);
-        PendingIntent piSent = PendingIntent.getBroadcast(mMainActivity, 
+        PendingIntent piSent = PendingIntent.getBroadcast(activity, 
                                                           promiseIdInt, 
                                                           intentSmsSent, 
                                                           PendingIntent.FLAG_ONE_SHOT);
@@ -92,7 +98,7 @@ public class MessagingSmsManager {
         intentSmsDelivered.putExtra(EXTRA_MSGID, asyncCallId);
         intentSmsDelivered.putExtra(EXTRA_MSGTEXT, smsMessage);
         intentSmsDelivered.putExtra(EXTRA_MSGINSTANCEID, instanceIDString);
-        PendingIntent piDelivered = PendingIntent.getBroadcast(mMainActivity, 
+        PendingIntent piDelivered = PendingIntent.getBroadcast(activity, 
                                                                -promiseIdInt, 
                                                                intentSmsDelivered,
                                                                PendingIntent.FLAG_ONE_SHOT);
@@ -104,6 +110,9 @@ public class MessagingSmsManager {
     }
 
     public void onSmsClear(int instanceID, JSONObject jsonMsg) {
+        Activity activity = mActivity.get();
+        if (activity == null) return;
+
         String asyncCallId = null, cmd = null;
         JSONObject eventBody = null;
         String serviceID = null;
@@ -117,7 +126,7 @@ public class MessagingSmsManager {
             return;
         }
 
-        ContentResolver cr = mMainActivity.getContentResolver();
+        ContentResolver cr = activity.getContentResolver();
         cr.delete(Uri.parse("content://sms"), null, null);
 
         JSONObject jsonMsgRet = null;
@@ -180,6 +189,9 @@ public class MessagingSmsManager {
     }
 
     public void registerIntentFilters() {
+        Activity activity = mActivity.get();
+        if (activity == null) return;
+
         mSmsReceiveReceiver = new MessagingReceiver(mMessagingHandler) {
             @Override
             public void onReceive(Context context, Intent intent) {
@@ -221,6 +233,9 @@ public class MessagingSmsManager {
         mSmsSentReceiver = new MessagingReceiver(mMessagingHandler) {
             @Override
             public void onReceive(Context content, Intent intent) {
+                Activity activity = mActivity.get();
+                if (activity == null) return;
+
                 boolean error = getResultCode() != Activity.RESULT_OK;
                 String asyncCallId = intent.getStringExtra(EXTRA_MSGID);
                 String smsMessage = intent.getStringExtra(EXTRA_MSGTEXT);
@@ -261,7 +276,7 @@ public class MessagingSmsManager {
                 ContentValues values = new ContentValues();
                 values.put("address", to);
                 values.put("body", smsMessage);
-                mMainActivity.getContentResolver().insert(Uri.parse("content://sms/sent"), values);
+                activity.getContentResolver().insert(Uri.parse("content://sms/sent"), values);
             }
         };
 
@@ -314,21 +329,24 @@ public class MessagingSmsManager {
             }
         };
 
-        mMainActivity.registerReceiver(
+        activity.registerReceiver(
             mSmsReceiveReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
-        mMainActivity.registerReceiver(
+        activity.registerReceiver(
             mSmsSentReceiver, new IntentFilter("SMS_SENT"));
-        mMainActivity.registerReceiver(
+        activity.registerReceiver(
             mSmsDeliveredReceiver,new IntentFilter("SMS_DELIVERED"));
-        mMainActivity.registerReceiver(
+        activity.registerReceiver(
             mSmsServiceReceiver,new IntentFilter("android.intent.action.SIM_STATE_CHANGED"));
     }
 
     public void unregisterIntentFilters() {
-        mMainActivity.unregisterReceiver(mSmsReceiveReceiver);
-        mMainActivity.unregisterReceiver(mSmsSentReceiver);
-        mMainActivity.unregisterReceiver(mSmsDeliveredReceiver);
-        mMainActivity.unregisterReceiver(mSmsServiceReceiver);
+        Activity activity = mActivity.get();
+        if (activity == null) return;
+
+        activity.unregisterReceiver(mSmsReceiveReceiver);
+        activity.unregisterReceiver(mSmsSentReceiver);
+        activity.unregisterReceiver(mSmsDeliveredReceiver);
+        activity.unregisterReceiver(mSmsServiceReceiver);
     }
 
     public String getServiceIds() {
index e958fd6..03775ae 100644 (file)
@@ -4,9 +4,11 @@
 
 package org.xwalk.core.internal.extension.api.presentation;
 
+import android.app.Activity;
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
+import android.provider.ContactsContract;
 import android.util.JsonReader;
 import android.util.JsonWriter;
 import android.util.Log;
@@ -16,19 +18,20 @@ import android.view.ViewGroup;
 import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.lang.ref.WeakReference;
 import java.net.URI;
 import java.net.URISyntaxException;
 
+import org.chromium.base.ActivityState;
 import org.chromium.base.ThreadUtils;
 
 import org.xwalk.core.internal.extension.api.XWalkDisplayManager;
-import org.xwalk.core.internal.extension.XWalkExtension;
-import org.xwalk.core.internal.extension.XWalkExtensionContext;
+import org.xwalk.core.internal.extension.XWalkExtensionWithActivityStateListener;
 
 /**
  * A XWalk extension for Presentation API implementation on Android.
  */
-public class PresentationExtension extends XWalkExtension {
+public class PresentationExtension extends XWalkExtensionWithActivityStateListener {
     public final static String JS_API_PATH = "jsapi/presentation_api.js";
 
     private final static String NAME = "navigator.presentation";
@@ -65,6 +68,8 @@ public class PresentationExtension extends XWalkExtension {
     private XWalkPresentationContent mPresentationContent;
     private XWalkPresentationContent.PresentationDelegate mPresentationDelegate;
     private PresentationView mPresentationView;
+    private Context mContext;
+    private WeakReference<Activity> mActivity;
 
     /**
      * Listens for the secondary display arrival and removal.
@@ -109,10 +114,12 @@ public class PresentationExtension extends XWalkExtension {
         }
     };
 
-    public PresentationExtension(String jsApi, XWalkExtensionContext context) {
-        super(NAME, jsApi, context);
+    public PresentationExtension(String jsApi, Activity activity) {
+        super(NAME, jsApi, activity);
 
-        mDisplayManager = XWalkDisplayManager.getInstance(context.getContext());
+        mContext = activity.getApplicationContext();
+        mActivity = new WeakReference<Activity>(activity);
+        mDisplayManager = XWalkDisplayManager.getInstance(activity.getApplicationContext());
         Display[] displays = mDisplayManager.getPresentationDisplays();
         mAvailableDisplayCount = displays.length;
     }
@@ -263,8 +270,8 @@ public class PresentationExtension extends XWalkExtension {
                 }
 
                 mPresentationContent = new XWalkPresentationContent(
-                        mExtensionContext.getContext(),
-                        mExtensionContext.getActivity(),
+                        mContext,
+                        mActivity,
                         new XWalkPresentationContent.PresentationDelegate() {
                     @Override
                     public void onContentLoaded(XWalkPresentationContent content) {
@@ -300,7 +307,6 @@ public class PresentationExtension extends XWalkExtension {
         }
     }
 
-    @Override
     public void onResume() {
         Display[] displays = mDisplayManager.getPresentationDisplays();
 
@@ -361,7 +367,7 @@ public class PresentationExtension extends XWalkExtension {
             ViewGroup parent = (ViewGroup)mPresentationContent.getContentView().getParent();
             if (parent != null) parent.removeView(mPresentationContent.getContentView());
 
-            mPresentationView = PresentationView.createInstance(mExtensionContext.getContext(), preferredDisplay);
+            mPresentationView = PresentationView.createInstance(mContext, preferredDisplay);
             mPresentationView.setContentView(mPresentationContent.getContentView());
             mPresentationView.setPresentationListener(new PresentationView.PresentationListener() {
                 @Override
@@ -389,22 +395,6 @@ public class PresentationExtension extends XWalkExtension {
         mPresentationView.show();
     }
 
-    @Override
-    public void onPause() {
-        dismissPresentationView();
-
-        if (mPresentationContent != null) mPresentationContent.onPause();
-
-        // No need to listen display changes when the activity is paused.
-        mDisplayManager.unregisterDisplayListener(mDisplayListener);
-    }
-
-    @Override
-    public void onDestroy() {
-        // close the presentation content if have.
-        closePresentationContent();
-    }
-
     private void dismissPresentationView() {
         if (mPresentationView == null) return;
 
@@ -418,4 +408,25 @@ public class PresentationExtension extends XWalkExtension {
         mPresentationContent.close();
         mPresentationContent = null;
     }
+
+    @Override
+    public void onActivityStateChange(Activity activity, int newState) {
+        switch (newState) {
+            case ActivityState.RESUMED:
+                onResume();
+                break;
+            case ActivityState.PAUSED:
+                dismissPresentationView();
+                if (mPresentationContent != null) mPresentationContent.onPause();
+                // No need to listen display changes when the activity is paused.
+                mDisplayManager.unregisterDisplayListener(mDisplayListener);
+                break;
+            case ActivityState.DESTROYED:
+                // close the presentation content if have.
+                closePresentationContent();
+                break;
+            default:
+                break;
+        }
+    }
 }
index 50c4e79..bf1f852 100644 (file)
@@ -4,6 +4,8 @@
 
 package org.xwalk.core.internal.extension.api.presentation;
 
+import java.lang.ref.WeakReference;
+
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
@@ -22,19 +24,23 @@ public class XWalkPresentationContent {
     private int mPresentationId = INVALID_PRESENTATION_ID;
     private XWalkViewInternal mContentView;
     private Context mContext;
-    private Activity mActivity;
+    private WeakReference<Activity> mActivity;
     private PresentationDelegate mDelegate;
 
 
-    public XWalkPresentationContent(Context context, Activity activity, PresentationDelegate delegate) {
+    public XWalkPresentationContent(
+            Context context, WeakReference<Activity> activity, PresentationDelegate delegate) {
         mContext = context;
         mActivity = activity;
         mDelegate = delegate;
     }
 
     public void load(final String url) {
+        Activity activity = mActivity.get();
+        if (activity == null) return;
+
         if (mContentView == null) {
-            mContentView = new XWalkViewInternal(mContext, mActivity);
+            mContentView = new XWalkViewInternal(mContext, activity);
             final XWalkUIClientInternal xWalkUIClient = new XWalkUIClientInternal(mContentView) {
                 @Override
                 public void onJavascriptCloseWindow(XWalkViewInternal view) {
diff --git a/src/xwalk/runtime/android/runtime/res/values/strings.xml b/src/xwalk/runtime/android/runtime/res/values/strings.xml
deleted file mode 100644 (file)
index e99ec05..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2012 The Chromium Authors. All rights reserved.
-
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file.
--->
-
-<!-- DO NOT ADD STRINGS HERE.
-
-    Android content strings now live in
-    xwalk/runtime/android/java/strings/android_xwalk_strings.grd
-
-    See http://www.chromium.org/developers/design-documents/ui-localization
--->
-
-<resources/>
index 106b7ae..7d6261c 100644 (file)
@@ -7,10 +7,10 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.xwalk.runtime.lib">
+    package="org.xwalk.core">
 
-    <application android:name="org.xwalk.runtime.lib.RuntimeLibApplication"
-        android:label="XWalkRuntimeLib" android:hardwareAccelerated="true" android:icon="@drawable/crosswalk">
+    <application
+        android:label="XWalkCoreLibrary" android:hardwareAccelerated="true" android:icon="@drawable/crosswalk">
     </application>
 
   <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
diff --git a/src/xwalk/runtime/android/runtime_lib/src/README.md b/src/xwalk/runtime/android/runtime_lib/src/README.md
new file mode 100644 (file)
index 0000000..e9629c0
--- /dev/null
@@ -0,0 +1,10 @@
+# Source folder for xwalk_runtime_lib_apk
+## Why it's empty
+The "xwalk_runtime_lib_apk" is an apk target which
+provide xwalk_core_internal_java as library. The purpose
+of it is to be shared for other xwalk core embedders.
+So there is no java src here.
+## Why put me here
+To make git keep the folder, the src directory is needed to
+build an apk.
+
diff --git a/src/xwalk/runtime/android/runtime_lib/src/org/xwalk/runtime/lib/RuntimeLibApplication.java b/src/xwalk/runtime/android/runtime_lib/src/org/xwalk/runtime/lib/RuntimeLibApplication.java
deleted file mode 100644 (file)
index 34071ee..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2013 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.runtime.lib;
-
-import android.app.Application;
-
-public class RuntimeLibApplication extends Application {
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-    }
-}
-
diff --git a/src/xwalk/runtime/android/runtime_shell/AndroidManifest.xml b/src/xwalk/runtime/android/runtime_shell/AndroidManifest.xml
deleted file mode 100644 (file)
index 95a7909..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--  Copyright (c) 2013 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.xwalk.runtime.shell">
-
-    <application android:name="android.app.Application"
-        android:label="XWalkRuntimeShell" android:hardwareAccelerated="true">
-        <activity android:name="org.xwalk.runtime.shell.XWalkRuntimeShellActivity"
-            android:theme="@android:style/Theme.Holo.Light.NoActionBar"
-            android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
-            android:label="XWalkRuntimeShell">
-          <intent-filter>
-            <action android:name="android.intent.action.MAIN" />
-            <category android:name="android.intent.category.LAUNCHER" />
-          </intent-filter>
-        </activity>
-        <activity android:name="org.xwalk.runtime.test.XWalkRuntimeTestRunnerActivity"
-            android:label="XWalkRuntimeTestRunnerActivity">
-          <intent-filter>
-            <action android:name="android.intent.action.MAIN" />
-            <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-          </intent-filter>
-        </activity>
-        <provider android:name="org.xwalk.core.xwview.test.TestContentProvider"
-            android:authorities="org.xwalk.core.xwview.test.TestContentProvider" />
-    </application>
-
-  <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
-  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
-  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-  <uses-permission android:name="android.permission.CAMERA"/>
-  <uses-permission android:name="android.permission.INTERNET"/>
-  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
-  <uses-permission android:name="android.permission.READ_CONTACTS"/>
-  <uses-permission android:name="android.permission.READ_SMS" />
-  <uses-permission android:name="android.permission.RECEIVE_SMS" />
-  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
-  <uses-permission android:name="android.permission.SEND_SMS" />
-  <uses-permission android:name="android.permission.WAKE_LOCK"/>
-  <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
-  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-  <uses-permission android:name="android.permission.WRITE_SMS" />
-</manifest>
diff --git a/src/xwalk/runtime/android/runtime_shell/res/layout/testshell_activity.xml b/src/xwalk/runtime/android/runtime_shell/res/layout/testshell_activity.xml
deleted file mode 100644 (file)
index 9d7ce5d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright (c) 2013 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.
- -->
-
-<LinearLayout android:id="@+id/testshell_activity"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <LinearLayout android:id="@+id/toolbar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal">
-        <EditText android:id="@+id/url"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:gravity="bottom"
-            android:textSize="18sp"
-            android:autoText="true"
-            android:capitalize="sentences"
-            android:singleLine="true"
-            android:selectAllOnFocus="true"
-            android:inputType="textUri"
-            android:imeOptions="actionGo" />
-    </LinearLayout>
-
-    <org.xwalk.runtime.XWalkRuntimeView android:id="@+id/content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-    </org.xwalk.runtime.XWalkRuntimeView>
-
-</LinearLayout>
-
diff --git a/src/xwalk/runtime/android/runtime_shell/res/values/strings.xml b/src/xwalk/runtime/android/runtime_shell/res/values/strings.xml
deleted file mode 100644 (file)
index 5a3dade..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2013 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.
--->
-
-<resources>
-    <string name="test_string">Hello, Crosswalk!</string>
-</resources>
diff --git a/src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/shell/XWalkRuntimeShellActivity.java b/src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/shell/XWalkRuntimeShellActivity.java
deleted file mode 100644 (file)
index 6c039f3..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2013 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.runtime.shell;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnFocusChangeListener;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-
-import org.chromium.base.CommandLine;
-import org.chromium.base.BaseSwitches;
-import org.xwalk.runtime.XWalkRuntimeView;
-
-public class XWalkRuntimeShellActivity extends Activity {
-    // TODO(yongsheng): Add one flag to hide the url bar.
-    public static final String COMMAND_LINE_FILE = "/data/local/tmp/runtime-shell-command-line";
-    private static final String TAG = XWalkRuntimeShellActivity.class.getName();
-    public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs";
-
-    private EditText mUrlTextView;
-    private XWalkRuntimeView mRuntimeView;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        if (!CommandLine.isInitialized()) {
-            CommandLine.initFromFile(COMMAND_LINE_FILE);
-            String[] commandLineParams = getCommandLineParamsFromIntent(getIntent());
-            if (commandLineParams != null) {
-                CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams);
-            }
-        }
-
-        waitForDebuggerIfNeeded();
-
-        setContentView(R.layout.testshell_activity);
-        mRuntimeView = (XWalkRuntimeView) findViewById(R.id.content_container);
-
-        initializeUrlField();
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        mRuntimeView.onStart();
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mRuntimeView.onPause();
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mRuntimeView.onResume();
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        mRuntimeView.onStop();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        mRuntimeView.onDestroy();
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        mRuntimeView.onActivityResult(requestCode, resultCode, data);
-    }
-
-    private void waitForDebuggerIfNeeded() {
-        if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) {
-            Log.e(TAG, "Waiting for Java debugger to connect...");
-            android.os.Debug.waitForDebugger();
-            Log.e(TAG, "Java debugger connected. Resuming execution.");
-        }
-    }
-
-    private static String[] getCommandLineParamsFromIntent(Intent intent) {
-        return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null;
-    }
-
-    private static String sanitizeUrl(String url) {
-        if (url == null) return url;
-        if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
-        return url;
-    }
-
-    private void initializeUrlField() {
-        mUrlTextView = (EditText) findViewById(R.id.url);
-        mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
-            @Override
-            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-                if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null ||
-                        event.getKeyCode() != KeyEvent.KEYCODE_ENTER ||
-                        event.getAction() != KeyEvent.ACTION_DOWN)) {
-                    return false;
-                }
-
-                mRuntimeView.loadAppFromUrl(sanitizeUrl(mUrlTextView.getText().toString()));
-                mUrlTextView.clearFocus();
-                setKeyboardVisibilityForUrl(false);
-                return true;
-            }
-        });
-        mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                setKeyboardVisibilityForUrl(hasFocus);
-                if (!hasFocus) {
-                    // TODO(yongsheng): Fix this.
-                    // mUrlTextView.setText(mRuntimeView.getUrl());
-                }
-            }
-        });
-    }
-
-    private void setKeyboardVisibilityForUrl(boolean visible) {
-        InputMethodManager imm = (InputMethodManager) getSystemService(
-                Context.INPUT_METHOD_SERVICE);
-        if (visible) {
-            imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
-        } else {
-            imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
-        }
-    }
-}
diff --git a/src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/test/TestContentProvider.java b/src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/test/TestContentProvider.java
deleted file mode 100644 (file)
index 7e7ceb3..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Content provider for testing content URLs.
- */
-
-package org.xwalk.runtime.test;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.database.AbstractCursor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-// Note: if you move this class, make sure you have also updated AndroidManifest.xml
-public class TestContentProvider extends ContentProvider {
-    private static final String AUTHORITY =
-            "org.xwalk.runtime.test.TestContentProvider";
-    private static final String CONTENT_SCHEME = "content://";
-    private static final String CONTENT_TYPE = "image/png";
-    private static final String GET_RESOURCE_REQUEST_COUNT = "get_resource_request_count";
-    private static final String RESET_RESOURCE_REQUEST_COUNT = "reset_resource_request_count";
-    private static final String TAG = "TestContentProvider";
-    private enum ColumnIndex {
-        RESOURCE_REQUEST_COUNT_COLUMN,
-    };
-    private final Map<String, Integer> mResourceRequestCount;
-
-    public static String createContentUrl(String target) {
-        return CONTENT_SCHEME + AUTHORITY + "/" + target;
-    }
-
-    private static Uri createRequestUri(final String target, String resource) {
-        return Uri.parse(createContentUrl(target) + "?" + resource);
-    }
-
-    public static int getResourceRequestCount(Context context, String resource) {
-        Uri uri = createRequestUri(GET_RESOURCE_REQUEST_COUNT, resource);
-        final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
-        try {
-            cursor.moveToFirst();
-            return cursor.getInt(ColumnIndex.RESOURCE_REQUEST_COUNT_COLUMN.ordinal());
-        } finally {
-            cursor.close();
-        }
-    }
-
-    public static void resetResourceRequestCount(Context context, String resource) {
-        Uri uri = createRequestUri(RESET_RESOURCE_REQUEST_COUNT, resource);
-        // A null cursor is returned for this request.
-        context.getContentResolver().query(uri, null, null, null, null);
-    }
-
-    public TestContentProvider() {
-        super();
-        mResourceRequestCount = new HashMap<String, Integer>();
-    }
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
-        String resource = uri.getLastPathSegment();
-        if (mResourceRequestCount.containsKey(resource)) {
-            mResourceRequestCount.put(resource, mResourceRequestCount.get(resource) + 1);
-        } else {
-            mResourceRequestCount.put(resource, 1);
-        }
-        return createImage();
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        return CONTENT_TYPE;
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String where,
-                      String[] whereArgs) {
-        return 0;
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        return 0;
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        return null;
-    }
-
-    /**
-     * Cursor object for retrieving resource request counters.
-     */
-    private static class ProviderStateCursor extends AbstractCursor {
-        private final int mResourceRequestCount;
-
-        public ProviderStateCursor(int resourceRequestCount) {
-            mResourceRequestCount = resourceRequestCount;
-        }
-
-        @Override
-        public boolean isNull(int columnIndex) {
-            return columnIndex != ColumnIndex.RESOURCE_REQUEST_COUNT_COLUMN.ordinal();
-        }
-
-        @Override
-        public int getCount() {
-            return 1;
-        }
-
-        @Override
-        public int getType(int columnIndex) {
-            if (columnIndex == ColumnIndex.RESOURCE_REQUEST_COUNT_COLUMN.ordinal()) {
-                return Cursor.FIELD_TYPE_INTEGER;
-            }
-            return Cursor.FIELD_TYPE_NULL;
-        }
-
-        private void unsupported() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public double getDouble(int columnIndex) {
-            unsupported();
-            return 0.0;
-        }
-
-        @Override
-        public float getFloat(int columnIndex) {
-            unsupported();
-            return 0.0f;
-        }
-
-        @Override
-        public int getInt(int columnIndex) {
-            if (columnIndex == ColumnIndex.RESOURCE_REQUEST_COUNT_COLUMN.ordinal()) {
-                return mResourceRequestCount;
-            }
-            return -1;
-        }
-
-        @Override
-        public short getShort(int columnIndex) {
-            unsupported();
-            return 0;
-        }
-
-        @Override
-        public long getLong(int columnIndex) {
-            return getInt(columnIndex);
-        }
-
-        @Override
-        public String getString(int columnIndex) {
-            unsupported();
-            return null;
-        }
-
-        @Override
-        public String[] getColumnNames() {
-            return new String[] { GET_RESOURCE_REQUEST_COUNT };
-        }
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection,
-                        String[] selectionArgs, String sortOrder) {
-        String action = uri.getLastPathSegment();
-        String resource = uri.getQuery();
-        if (GET_RESOURCE_REQUEST_COUNT.equals(action)) {
-            return new ProviderStateCursor(
-                    mResourceRequestCount.containsKey(resource) ?
-                    mResourceRequestCount.get(resource) : 0);
-        } else if (RESET_RESOURCE_REQUEST_COUNT.equals(action)) {
-            mResourceRequestCount.put(resource, 0);
-        }
-        return null;
-    }
-
-    // 1x1 black dot png image.
-    private static final byte[] IMAGE = {
-        (byte)0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00,
-        0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-        0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x7e, (byte)0x9b, 0x55, 0x00,
-        0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, (byte)0xae, (byte)0xce,
-        0x1c, (byte)0xe9, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x44, 0x41, 0x54, 0x08,
-        0x1d, 0x01, 0x02, 0x00, (byte)0xfd, (byte)0xff, 0x00, 0x00, 0x00, 0x02,
-        0x00, 0x01, (byte)0xcd, (byte)0xe3, (byte)0xd1, 0x2b, 0x00, 0x00, 0x00,
-        0x00, 0x49, 0x45, 0x4e, 0x44, (byte)0xae, 0x42, 0x60, (byte)0x82
-    };
-
-    private static AssetFileDescriptor createImage() {
-        ParcelFileDescriptor[] pfds = null;
-        FileOutputStream fileOut = null;
-        try {
-            try {
-                pfds = ParcelFileDescriptor.createPipe();
-                fileOut = new FileOutputStream(pfds[1].getFileDescriptor());
-                fileOut.write(IMAGE);
-                fileOut.flush();
-                return new AssetFileDescriptor(pfds[0], 0, -1);
-            } finally {
-                if (fileOut != null) fileOut.close();
-                if (pfds != null && pfds[1] != null) pfds[1].close();
-            }
-        } catch (IOException e) {
-            Log.e(TAG, e.getMessage(), e);
-        }
-        return null;
-    }
-}
diff --git a/src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/test/XWalkRuntimeTestRunnerActivity.java b/src/xwalk/runtime/android/runtime_shell/src/org/xwalk/runtime/test/XWalkRuntimeTestRunnerActivity.java
deleted file mode 100644 (file)
index df29723..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.xwalk.runtime.test;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
-import android.widget.LinearLayout;
-
-/*
- * This is a lightweight activity for tests that only require XWalk functionality.
- */
-public class XWalkRuntimeTestRunnerActivity extends Activity {
-
-    private LinearLayout mLinearLayout;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        boolean hardwareAccelerated = true;
-
-        if (hardwareAccelerated) {
-            getWindow().setFlags(
-                    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
-        }
-
-        mLinearLayout = new LinearLayout(this);
-        mLinearLayout.setOrientation(LinearLayout.VERTICAL);
-        mLinearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
-        mLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
-                LayoutParams.WRAP_CONTENT));
-
-        setContentView(mLinearLayout);
-    }
-
-    /**
-     * Adds a view to the main linear layout.
-     */
-    public void addView(View view) {
-        view.setLayoutParams(new LinearLayout.LayoutParams(
-                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1f));
-        mLinearLayout.addView(view);
-    }
-
-    /**
-     * Clears the main linear layout.
-     */
-    public void removeAllViews() {
-        mLinearLayout.removeAllViews();
-    }
-}
index 8764764..fa3089c 100644 (file)
@@ -243,7 +243,6 @@ jboolean XWalkContent::SetManifest(JNIEnv* env,
       manifest_dictionary_ptr(manifest_dictionary);
 
   xwalk::application::Manifest manifest(
-      xwalk::application::Manifest::INVALID_TYPE,
       manifest_dictionary_ptr.Pass());
 
   std::string url;
index 84cd31d..b8c51a3 100644 (file)
@@ -36,12 +36,14 @@ void XWalkBrowserMainPartsTizen::PreMainMessageLoopStart() {
   // Enable Accelerated 2D Canvas.
   command_line->AppendSwitch(switches::kGpuNoContextLost);
 
-  const char* gl_name;
-  if (base::PathExists(base::FilePath("/usr/lib/libGL.so")))
-    gl_name = gfx::kGLImplementationDesktopName;
-  else
-    gl_name = gfx::kGLImplementationEGLName;
-  command_line->AppendSwitchASCII(switches::kUseGL, gl_name);
+  if (!command_line->HasSwitch(switches::kUseGL)) {
+    const char* gl_name;
+    if (base::PathExists(base::FilePath("/usr/lib/libGL.so")))
+      gl_name = gfx::kGLImplementationDesktopName;
+    else
+      gl_name = gfx::kGLImplementationEGLName;
+    command_line->AppendSwitchASCII(switches::kUseGL, gl_name);
+  }
 
   XWalkBrowserMainParts::PreMainMessageLoopStart();
 }
index c51ac4a..9fe1ee0 100644 (file)
 #include "content/public/common/content_switches.h"
 #include "content/public/common/user_agent.h"
 #include "content/public/common/pepper_plugin_info.h"
+#if !defined(DISABLE_NACL)
+#include "ppapi/native_client/src/trusted/plugin/ppapi_entrypoints.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
+#endif
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "xwalk/application/common/constants.h"
@@ -25,6 +28,7 @@ const char* const xwalk::XWalkContentClient::kNaClPluginName = "Native Client";
 
 namespace {
 
+#if !defined(DISABLE_NACL)
 const char kNaClPluginMimeType[] = "application/x-nacl";
 const char kNaClPluginExtension[] = "";
 const char kNaClPluginDescription[] = "Native Client Executable";
@@ -34,6 +38,7 @@ const uint32 kNaClPluginPermissions = ppapi::PERMISSION_PRIVATE |
 const char kPnaclPluginMimeType[] = "application/x-pnacl";
 const char kPnaclPluginExtension[] = "";
 const char kPnaclPluginDescription[] = "Portable Native Client Executable";
+#endif
 
 }  // namespace
 
@@ -65,36 +70,40 @@ XWalkContentClient::~XWalkContentClient() {
 
 void XWalkContentClient::AddPepperPlugins(
     std::vector<content::PepperPluginInfo>* plugins) {
+#if !defined(DISABLE_NACL)
   // Handle Native Client just like the PDF plugin. This means that it is
   // enabled by default for the non-portable case.  This allows apps installed
   // from the Chrome Web Store to use NaCl even if the command line switch
   // isn't set.  For other uses of NaCl we check for the command line switch.
   // Specifically, Portable Native Client is only enabled by the command line
   // switch.
-  static bool skip_nacl_file_check = false;
   base::FilePath path;
   if (PathService::Get(xwalk::FILE_NACL_PLUGIN, &path)) {
-    if (skip_nacl_file_check || base::PathExists(path)) {
-      content::PepperPluginInfo nacl;
-      nacl.path = path;
-      nacl.name = XWalkContentClient::kNaClPluginName;
-      content::WebPluginMimeType nacl_mime_type(kNaClPluginMimeType,
-                                                kNaClPluginExtension,
-                                                kNaClPluginDescription);
-      nacl.mime_types.push_back(nacl_mime_type);
-      if (!CommandLine::ForCurrentProcess()->HasSwitch(
-              switches::kDisablePnacl)) {
-        content::WebPluginMimeType pnacl_mime_type(kPnaclPluginMimeType,
-                                                   kPnaclPluginExtension,
-                                                   kPnaclPluginDescription);
-        nacl.mime_types.push_back(pnacl_mime_type);
-      }
-      nacl.permissions = kNaClPluginPermissions;
-      plugins->push_back(nacl);
-
-      skip_nacl_file_check = true;
+    content::PepperPluginInfo nacl;
+    // The nacl plugin is now built into the Chromium binary.
+    nacl.is_internal = true;
+    nacl.path = path;
+    nacl.name = XWalkContentClient::kNaClPluginName;
+    content::WebPluginMimeType nacl_mime_type(kNaClPluginMimeType,
+                                              kNaClPluginExtension,
+                                              kNaClPluginDescription);
+    nacl.mime_types.push_back(nacl_mime_type);
+    if (!CommandLine::ForCurrentProcess()->HasSwitch(
+        switches::kDisablePnacl)) {
+      content::WebPluginMimeType pnacl_mime_type(kPnaclPluginMimeType,
+                                                 kPnaclPluginExtension,
+                                                 kPnaclPluginDescription);
+      nacl.mime_types.push_back(pnacl_mime_type);
     }
+    nacl.internal_entry_points.get_interface = nacl_plugin::PPP_GetInterface;
+    nacl.internal_entry_points.initialize_module =
+        nacl_plugin::PPP_InitializeModule;
+    nacl.internal_entry_points.shutdown_module =
+        nacl_plugin::PPP_ShutdownModule;
+    nacl.permissions = kNaClPluginPermissions;
+    plugins->push_back(nacl);
   }
+#endif
 }
 
 std::string XWalkContentClient::GetProduct() const {
index 40e2160..d8067e8 100644 (file)
@@ -175,6 +175,11 @@ bool PathProvider(int key, base::FilePath* path) {
         return false;
       cur = cur.Append(FILE_PATH_LITERAL("Widget Storage"));
       break;
+    case xwalk::DIR_APPLICATION_PATH:
+      if (!GetXWalkDataPath(&cur))
+        return false;
+      cur = cur.Append(FILE_PATH_LITERAL("applications"));
+      break;
     default:
       return false;
   }
index 8f53c42..b7cf4f4 100644 (file)
@@ -20,6 +20,7 @@ enum {
                                // (subdir of DIR_PNACL_BASE).
   DIR_TEST_DATA,               // Directory where unit test data resides.
   DIR_WGT_STORAGE_PATH,        // Directory where widget storage data resides.
+  DIR_APPLICATION_PATH,        // Directory where applications data is stored.
   PATH_END
 };
 
index c2c5a18..9081d62 100644 (file)
@@ -31,13 +31,13 @@ public class EnterAndLeaveFullscreenTest extends XWalkViewTestBase {
             @Override
             public void run() {
                 try {
-                    clickOnElementId("enter_fullscreen");
+                    clickOnElementId("enter_fullscreen", null);
                     assertTrue(getXWalkView().hasEnteredFullscreen());
                     getXWalkView().leaveFullscreen();
                     assertFalse(getXWalkView().hasEnteredFullscreen());
 
-                    clickOnElementId("enter_fullscreen");
-                    clickOnElementId("exit_fullscreen");
+                    clickOnElementId("enter_fullscreen", null);
+                    clickOnElementId("exit_fullscreen", null);
                     assertFalse(getXWalkView().hasEnteredFullscreen());
                 } catch (Throwable e) {
                     e.printStackTrace();
diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnRequestFocusTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/OnRequestFocusTest.java
new file mode 100644 (file)
index 0000000..8063203
--- /dev/null
@@ -0,0 +1,34 @@
+// 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 org.chromium.base.test.util.Feature;
+
+/**
+ * Test suite for OnRequestFocus().
+ */
+public class OnRequestFocusTest extends XWalkViewTestBase {
+    private TestHelperBridge.OnRequestFocusHelper mOnRequestFocusHelper;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mOnRequestFocusHelper = mTestHelperBridge.getOnRequestFocusHelper();
+    }
+
+    @SmallTest
+    @Feature({"OnRequestFocus"})
+    public void testOnRequestFocus() throws Throwable {
+        final String url = "file:///android_asset/www/request_focus_main.html";
+        int count = mOnRequestFocusHelper.getCallCount();
+
+        loadUrlSync(url);
+        clickOnElementId("left_frame", "LeftFrame");
+        mOnRequestFocusHelper.waitForCallback(count);
+        assertTrue(mOnRequestFocusHelper.getCalled());
+    }
+}
index 683a59c..130745e 100644 (file)
@@ -172,7 +172,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
         final int shouldOverrideUrlLoadingCallCount = mShouldOverrideUrlLoadingHelper.getCallCount();
         final int onPageStartedCallCount = onPageStartedHelper.getCallCount();
         setShouldOverrideUrlLoadingReturnValueOnUiThread(true);
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(shouldOverrideUrlLoadingCallCount);
         assertEquals(onPageStartedCallCount, onPageStartedHelper.getCallCount());
@@ -191,7 +191,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
 
         setShouldOverrideUrlLoadingReturnValueOnUiThread(true);
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(shouldOverrideUrlLoadingCallCount);
 
@@ -231,7 +231,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
 
         final int shouldOverrideUrlLoadingCallCount = mShouldOverrideUrlLoadingHelper.getCallCount();
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         // After we load this URL we're certain that any in-flight callbacks for the previous
         // navigation have been delivered.
@@ -250,7 +250,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
     }
@@ -267,7 +267,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
         assertEquals(httpPathOnServer,
@@ -284,7 +284,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
     }
@@ -298,7 +298,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
                 getHtmlForPageWithJsReplaceLinkTo(redirectTargetUrl), "text/html", false);
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        clickOnElementId("link");
+        clickOnElementId("link", null);
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
     }
 
@@ -310,7 +310,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
                 CommonResources.makeHtmlPageWithSimpleLinkTo(redirectTargetUrl), "text/html", false);
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        clickOnElementId("link");
+        clickOnElementId("link", null);
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
         assertEquals(redirectTargetUrl,
                 mShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl());
@@ -334,7 +334,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
         setShouldOverrideUrlLoadingReturnValueOnUiThread(true);
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        clickOnElementId("link");
+        clickOnElementId("link", null);
         // Some time around here true should be returned from the shouldOverrideUrlLoading
         // callback causing the navigation caused by calling clickOnElementId to be ignored.
         // We validate this by checking which pages were loaded on the server.
@@ -360,7 +360,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
                 CommonResources.makeHtmlPageWithSimpleLinkTo(dataUrl), "text/html", false);
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
         assertTrue("Expected URL that starts with 'data:' but got: <" +
@@ -378,7 +378,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
                         false);
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
         assertEquals(unsupportedSchemeUrl,
@@ -399,7 +399,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
             mShouldOverrideUrlLoadingHelper.getCallCount();
 
         assertEquals(0, mWebServer.getRequestCount(REDIRECT_TARGET_PATH));
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         // Wait for the target URL to be fetched from the server.
         pollOnUiThread(new Callable<Boolean>() {
@@ -429,7 +429,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
 
         final int shouldOverrideUrlLoadingCallCount = mShouldOverrideUrlLoadingHelper.getCallCount();
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(shouldOverrideUrlLoadingCallCount);
 
@@ -490,7 +490,7 @@ public class ShouldOverrideUrlLoadingTest extends XWalkViewTestBase {
         int indirectLoadCallCount = mShouldOverrideUrlLoadingHelper.getCallCount();
         loadUrlSync(pageWithLinkToRedirectUrl);
 
-        clickOnElementId("link");
+        clickOnElementId("link", null);
 
         mShouldOverrideUrlLoadingHelper.waitForCallback(indirectLoadCallCount, 3);
         assertEquals(redirectTarget,
index 1c7a13a..90f615e 100644 (file)
@@ -206,6 +206,20 @@ class TestHelperBridge {
         }
     }
 
+    public class OnRequestFocusHelper extends CallbackHelper {
+        private boolean mCalled = false;
+
+        public boolean getCalled() {
+            assert getCallCount() > 0;
+            return mCalled;
+        }
+
+        public void notifyCalled(boolean called) {
+            mCalled = called;
+            notifyCalled();
+        }
+    }
+
     private String mChangedTitle;
     private final OnPageStartedHelper mOnPageStartedHelper;
     private final OnPageFinishedHelper mOnPageFinishedHelper;
@@ -220,6 +234,7 @@ class TestHelperBridge {
     private final OnProgressChangedHelper mOnProgressChangedHelper;
     private final ShouldOverrideUrlLoadingHelper mShouldOverrideUrlLoadingHelper;
     private final OnScaleChangedHelper mOnScaleChangedHelper;
+    private final OnRequestFocusHelper mOnRequestFocusHelper;
 
     public TestHelperBridge() {
         mOnPageStartedHelper = new OnPageStartedHelper();
@@ -233,6 +248,7 @@ class TestHelperBridge {
         mOnProgressChangedHelper = new OnProgressChangedHelper();
         mShouldOverrideUrlLoadingHelper = new ShouldOverrideUrlLoadingHelper();
         mOnScaleChangedHelper = new OnScaleChangedHelper();
+        mOnRequestFocusHelper = new OnRequestFocusHelper();
     }
 
     public OnPageStartedHelper getOnPageStartedHelper() {
@@ -279,6 +295,10 @@ class TestHelperBridge {
         return mOnScaleChangedHelper;
     }
 
+    public OnRequestFocusHelper getOnRequestFocusHelper() {
+        return mOnRequestFocusHelper;
+    }
+
     public void onTitleChanged(String title) {
         mChangedTitle = title;
         mOnTitleUpdatedHelper.notifyCalled(title);
@@ -328,4 +348,8 @@ class TestHelperBridge {
     public void onScaleChanged(float scale) {
         mOnScaleChangedHelper.notifyCalled(scale);
     }
+
+    public void onRequestFocus() {
+        mOnRequestFocusHelper.notifyCalled(true);
+    }
 }
index cfafe9a..01ae91b 100644 (file)
@@ -71,6 +71,11 @@ public class XWalkViewTestBase
         public void onScaleChanged(XWalkView view, float oldScale, float newScale) {
             mInnerContentsClient.onScaleChanged(newScale);
         }
+
+        @Override
+        public void onRequestFocus(XWalkView view) {
+            mInnerContentsClient.onRequestFocus();
+        }
     }
 
     class TestXWalkUIClient extends TestXWalkUIClientBase {
@@ -486,13 +491,20 @@ public class XWalkViewTestBase
         });
     }
 
-    public void clickOnElementId(final String id) throws Exception {
+    public void clickOnElementId(final String id, String frameName) throws Exception {
+        String str;
+        if (frameName != null) {
+            str = "top.window." + "LeftFrame" + ".document.getElementById('" + id + "')";
+        } else {
+            str = "document.getElementById('" + id + "')";
+        }
+        final String script1 = str + " != null";
+        final String script2 = str + ".dispatchEvent(evObj);";
         Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
             @Override
             public boolean isSatisfied() {
                 try {
-                    String idIsNotNull = executeJavaScriptAndWaitForResult(
-                        "document.getElementById('" + id + "') != null");
+                    String idIsNotNull = executeJavaScriptAndWaitForResult(script1);
                     return idIsNotNull.equals("true");
                 } catch (Throwable t) {
                     t.printStackTrace();
@@ -506,7 +518,7 @@ public class XWalkViewTestBase
             String result = executeJavaScriptAndWaitForResult(
                 "var evObj = document.createEvent('Events'); " +
                 "evObj.initEvent('click', true, false); " +
-                "document.getElementById('" + id + "').dispatchEvent(evObj);" +
+                script2 +
                 "console.log('element with id [" + id + "] clicked');");
         } catch (Throwable t) {
             t.printStackTrace();
diff --git a/src/xwalk/test/android/data/request_focus_left_frame.html b/src/xwalk/test/android/data/request_focus_left_frame.html
new file mode 100644 (file)
index 0000000..62558b1
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+<a href="request_focus_right_frame1.html" id="left_frame" target="RightFrame">Click me</a>
+</body>
+</html>
diff --git a/src/xwalk/test/android/data/request_focus_main.html b/src/xwalk/test/android/data/request_focus_main.html
new file mode 100644 (file)
index 0000000..77ad6ea
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script>
+document.get
+</script>
+</head>
+<frameset rows=50%,50%>
+    <frame src="request_focus_left_frame.html" name="LeftFrame" />
+    <frame src="request_focus_right_frame.html" name="RightFrame" />
+</frameset>
+</html>
diff --git a/src/xwalk/test/android/data/request_focus_right_frame.html b/src/xwalk/test/android/data/request_focus_right_frame.html
new file mode 100644 (file)
index 0000000..88d601c
--- /dev/null
@@ -0,0 +1 @@
+right frame
diff --git a/src/xwalk/test/android/data/request_focus_right_frame1.html b/src/xwalk/test/android/data/request_focus_right_frame1.html
new file mode 100644 (file)
index 0000000..3a33a0a
--- /dev/null
@@ -0,0 +1 @@
+another right frame
diff --git a/src/xwalk/test/android/runtime/javatests/AndroidManifest.xml b/src/xwalk/test/android/runtime/javatests/AndroidManifest.xml
deleted file mode 100644 (file)
index 2219412..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--  Copyright (c) 2013 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.xwalk.runtime.test">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <provider android:name="org.xwalk.runtime.client.test.TestContentProvider"
-            android:authorities="org.xwalk.runtime.test.TestContentProvider" />
-    </application>
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="org.xwalk.runtime.shell"
-        android:label="Test for org.xwalk.runtime" />
-    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
-    <uses-permission android:name="android.permission.INJECT_EVENTS" />
-    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.READ_LOGS"/>
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-</manifest>
diff --git a/src/xwalk/test/android/runtime/javatests/src/org/xwalk/runtime/test/XWalkRuntimeTestBase.java b/src/xwalk/test/android/runtime/javatests/src/org/xwalk/runtime/test/XWalkRuntimeTestBase.java
deleted file mode 100644 (file)
index 65c3279..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Copyright (c) 2013 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.runtime.test;
-
-import android.test.ActivityInstrumentationTestCase2;
-
-public class XWalkRuntimeTestBase
-       extends ActivityInstrumentationTestCase2<XWalkRuntimeTestRunnerActivity> {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public XWalkRuntimeTestBase() {
-        super(XWalkRuntimeTestRunnerActivity.class);
-    }
-}
index b75a2c2..cdb3d0c 100644 (file)
@@ -8,7 +8,6 @@ package org.xwalk.runtime.client.test;
 import android.app.Activity;
 import android.test.ActivityInstrumentationTestCase2;
 
-import org.xwalk.app.runtime.XWalkRuntimeClient;
 import org.xwalk.runtime.client.shell.XWalkRuntimeClientShellActivity;
 import org.xwalk.test.util.XWalkRuntimeClientTestGeneric;
 import org.xwalk.test.util.XWalkRuntimeClientTestUtilBase;
index fdac60b..507ddf7 100644 (file)
@@ -8,7 +8,6 @@ package org.xwalk.runtime.client.embedded.test;
 import android.app.Activity;
 import android.test.ActivityInstrumentationTestCase2;
 
-import org.xwalk.app.runtime.XWalkRuntimeClient;
 import org.xwalk.runtime.client.embedded.shell.XWalkRuntimeClientEmbeddedShellActivity;
 import org.xwalk.test.util.XWalkRuntimeClientTestGeneric;
 import org.xwalk.test.util.XWalkRuntimeClientTestUtilBase;
index 3f20c7a..ab873ef 100644 (file)
@@ -9,13 +9,13 @@ import android.app.Activity;
 import android.content.Context;
 import android.test.ActivityInstrumentationTestCase2;
 
-import org.xwalk.app.runtime.XWalkRuntimeClient;
+import org.xwalk.app.runtime.XWalkRuntimeView;
 import org.xwalk.app.XWalkRuntimeActivityBase;
 import org.xwalk.test.util.XWalkRuntimeClientTestUtilBase.PageStatusCallback;
 
 public class XWalkRuntimeClientTestGeneric<T extends XWalkRuntimeActivityBase>
         extends ActivityInstrumentationTestCase2<T> {
-    private XWalkRuntimeClient mRuntimeView;
+    private XWalkRuntimeView mRuntimeView;
     XWalkRuntimeClientTestUtilBase mTestUtil;
 
     @Override
@@ -26,7 +26,7 @@ public class XWalkRuntimeClientTestGeneric<T extends XWalkRuntimeActivityBase>
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                if (mRuntimeView == null || mRuntimeView.get() == null) {
+                if (mRuntimeView == null) {
                     mRuntimeView = activity.getRuntimeView();
                 }
                 mTestUtil = new XWalkRuntimeClientTestUtilBase(mRuntimeView,
index 40608a7..487ee5a 100644 (file)
@@ -14,9 +14,9 @@ import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
 import org.chromium.content.browser.test.util.CallbackHelper;
-import org.xwalk.app.runtime.XWalkRuntimeClient;
+import org.xwalk.app.runtime.XWalkRuntimeView;
 
-public class XWalkRuntimeClientTestUtilBase extends XWalkTestUtilBase<XWalkRuntimeClient> {
+public class XWalkRuntimeClientTestUtilBase extends XWalkTestUtilBase<XWalkRuntimeView> {
     public class PageStatusCallback {
         public void onPageStarted(String url) {
             mCallbackHelpers.onPageStarted(url);
@@ -35,7 +35,7 @@ public class XWalkRuntimeClientTestUtilBase extends XWalkTestUtilBase<XWalkRunti
         }
     }
 
-    public XWalkRuntimeClientTestUtilBase(XWalkRuntimeClient runtimeView,
+    public XWalkRuntimeClientTestUtilBase(XWalkRuntimeView runtimeView,
             Instrumentation instrumentation) {
         super(runtimeView, instrumentation);
     }
diff --git a/src/xwalk/tizen/browser/audio_session_manager.cc b/src/xwalk/tizen/browser/audio_session_manager.cc
deleted file mode 100644 (file)
index 82e4645..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2013 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/tizen/browser/audio_session_manager.h"
-
-#include "base/logging.h"
-#include "xwalk/tizen/browser/browser_mediaplayer_manager.h"
-
-namespace tizen {
-
-AudioSessionManager::AudioSessionManager(
-    BrowserMediaPlayerManager* manager,
-    MediaPlayerID player_id,
-    int process_id)
-    : event_type_(ASM_EVENT_NONE),
-      manager_(manager),
-      handle_(-1),
-      process_id_(process_id),
-      player_id_(player_id) {
-}
-
-AudioSessionManager::~AudioSessionManager() {
-  UnregisterAudioSessionManager();
-}
-
-bool AudioSessionManager::RegisterAudioSessionManager(
-    ASM_sound_events_t event_type,
-    ASM_sound_cb_t notify_callback,
-    void* callback_data) {
-  int error = 0;
-  event_type_ = event_type;
-
-  if (!ASM_register_sound(process_id_, &handle_,
-      event_type_, ASM_STATE_NONE,
-      notify_callback, callback_data,
-      ASM_RESOURCE_NONE, &error)) {
-    LOG(ERROR) << "Register audio session manager failed. errcode=" << error;
-    return false;
-  }
-
-  return true;
-}
-
-bool AudioSessionManager::UnregisterAudioSessionManager() {
-  int error = 0;
-  if (!ASM_unregister_sound(handle_, event_type_, &error)) {
-    LOG(ERROR) << "Unregister audio session manager failed. errcode=" << error;
-    return false;
-  }
-
-  return true;
-}
-
-bool AudioSessionManager::SetSoundState(ASM_sound_states_t state) {
-  int error = 0;
-  if (!ASM_set_sound_state(handle_, event_type_, state,
-      ASM_RESOURCE_NONE, &error)) {
-    LOG(ERROR) << "Set sound state =" << state << "failed. errcode=" << error;
-    return false;
-  }
-
-  return true;
-}
-
-}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/audio_session_manager.h b/src/xwalk/tizen/browser/audio_session_manager.h
deleted file mode 100644 (file)
index 4a1fc18..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2013 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_TIZEN_BROWSER_AUDIO_SESSION_MANAGER_H_
-#define XWALK_TIZEN_BROWSER_AUDIO_SESSION_MANAGER_H_
-
-#include <audio-session-manager.h>
-#include "base/basictypes.h"
-
-namespace tizen {
-class BrowserMediaPlayerManager;
-
-typedef int MediaPlayerID;
-
-// This class manages communication between MediaPlayer and Audio
-// Session Manager. It also defines Media Session policy and update
-// the sound state to ASM server.
-class AudioSessionManager {
- public:
-  AudioSessionManager(
-      BrowserMediaPlayerManager* manager,
-      MediaPlayerID player_id,
-      int process_id);
-  ~AudioSessionManager();
-
-  //  Register to ASM server
-  bool RegisterAudioSessionManager(ASM_sound_events_t, ASM_sound_cb_t, void*);
-  //  Unregister to ASM server
-  bool UnregisterAudioSessionManager();
-
-  bool SetSoundState(ASM_sound_states_t);
-  MediaPlayerID player_id() const { return player_id_; }
-
-  BrowserMediaPlayerManager* media_player_manager() {
-    return manager_;
-  }
-
- private:
-  ASM_sound_events_t event_type_;
-  BrowserMediaPlayerManager*  manager_;
-  int handle_;
-  int process_id_;
-  MediaPlayerID player_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioSessionManager);
-};
-
-}  // namespace tizen
-
-#endif  // XWALK_TIZEN_BROWSER_AUDIO_SESSION_MANAGER_H_
diff --git a/src/xwalk/tizen/browser/audio_session_manager.sigs b/src/xwalk/tizen/browser/audio_session_manager.sigs
deleted file mode 100644 (file)
index 5324cc5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2013 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.
-
-#------------------------------------------------
-# Functions from audio-session-manager used in Crosswalk code.
-#------------------------------------------------
-bool ASM_register_sound(const int application_pid, int *asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_sound_cb_t callback, void* cb_data, ASM_resource_t mm_resource, int *error_code);
-bool ASM_unregister_sound(const int asm_handle, ASM_sound_events_t sound_event, int *error_code);
-bool ASM_set_sound_state(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_resource_t mm_resource, int *error_code);
diff --git a/src/xwalk/tizen/browser/audio_session_manager_init.cc b/src/xwalk/tizen/browser/audio_session_manager_init.cc
deleted file mode 100644 (file)
index 93885ae..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Copyright (c) 2013 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/tizen/browser/audio_session_manager_init.h"
-
-#include "base/files/file_path.h"
-#include "base/lazy_instance.h"
-#include "xwalk/tizen/browser/audio_session_manager_stubs.h"
-
-using xwalk_tizen_browser::kModuleAudio_session_manager;
-using xwalk_tizen_browser::InitializeStubs;
-using xwalk_tizen_browser::StubPathMap;
-
-namespace tizen {
-
-static const base::FilePath::CharType kAsmModuleLib[] =
-    FILE_PATH_LITERAL("libaudio-session-mgr.so.0");
-
-// Audio session manager must only be initialized once, so use a
-// LazyInstance to ensure this.
-class AudioSessionManagerInitializer {
- public:
-  bool Initialize() {
-    if (!tried_initialize_) {
-      tried_initialize_ = true;
-      StubPathMap paths;
-
-      paths[kModuleAudio_session_manager].push_back(kAsmModuleLib);
-      initialized_ = InitializeStubs(paths);
-    }
-    return initialized_;
-  }
-
- private:
-  friend struct base::DefaultLazyInstanceTraits<AudioSessionManagerInitializer>;
-
-  AudioSessionManagerInitializer()
-      : initialized_(false),
-        tried_initialize_(false) {
-  }
-
-  bool initialized_;
-  bool tried_initialize_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioSessionManagerInitializer);
-};
-
-static base::LazyInstance<AudioSessionManagerInitializer>::Leaky g_asm_library =
-    LAZY_INSTANCE_INITIALIZER;
-
-bool InitializeAudioSessionManager() {
-  return g_asm_library.Get().Initialize();
-}
-
-}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/audio_session_manager_init.h b/src/xwalk/tizen/browser/audio_session_manager_init.h
deleted file mode 100644 (file)
index 15cece3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Copyright (c) 2013 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.
-
-// Contains code that should be used for initializing the
-// audio session manager library as a whole.
-
-#ifndef XWALK_TIZEN_BROWSER_AUDIO_SESSION_MANAGER_INIT_H_
-#define XWALK_TIZEN_BROWSER_AUDIO_SESSION_MANAGER_INIT_H_
-
-#include "content/common/content_export.h"
-
-namespace tizen {
-
-// Attempts to initialize the audio session manager library.
-// Returns true if everything was successfully initialized, false otherwise.
-CONTENT_EXPORT bool InitializeAudioSessionManager();
-
-}  // namespace tizen
-
-#endif  // XWALK_TIZEN_BROWSER_AUDIO_SESSION_MANAGER_INIT_H_
diff --git a/src/xwalk/tizen/browser/audio_session_manager_stub_headers.fragment b/src/xwalk/tizen/browser/audio_session_manager_stub_headers.fragment
deleted file mode 100644 (file)
index 55a4ad7..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// The extra include header needed in the generated stub file for defining
-// various audio session manager types.
-
-extern "C" {
-
-#include <audio-session-manager.h>
-
-}
diff --git a/src/xwalk/tizen/browser/browser_mediaplayer_manager.cc b/src/xwalk/tizen/browser/browser_mediaplayer_manager.cc
deleted file mode 100644 (file)
index cd25d5c..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Copyright (c) 2013 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/tizen/browser/browser_mediaplayer_manager.h"
-
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-#include "xwalk/tizen/browser/audio_session_manager_init.h"
-#include "xwalk/tizen/common/media_player_messages.h"
-
-namespace tizen {
-
-BrowserMediaPlayerManager::BrowserMediaPlayerManager(
-    content::RenderViewHost* render_view_host)
-    : WebContentsObserver(content::WebContents::FromRenderViewHost(
-          render_view_host)) {
-}
-
-BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {}
-
-BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
-    content::RenderViewHost* render_view_host) {
-  return new BrowserMediaPlayerManager(render_view_host);
-}
-
-bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(BrowserMediaPlayerManager, msg)
-    IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerInitialize, OnInitialize)
-    IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerStarted, OnStart)
-    IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaPlayerPaused, OnPause)
-    IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer)
-    IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers,
-                        OnDestroyAllMediaPlayers)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-
-  return handled;
-}
-
-AudioSessionManager* BrowserMediaPlayerManager::GetAudioSessionManager(
-    MediaPlayerID player_id) {
-  for (ScopedVector<AudioSessionManager>::iterator it =
-      audio_session_managers_.begin(); it != audio_session_managers_.end();
-      ++it) {
-    if ((*it)->player_id() == player_id)
-      return *it;
-  }
-
-  return NULL;
-}
-
-ASM_cb_result_t BrowserMediaPlayerManager::AudioSessionEventPause(
-    ASM_event_sources_t event_source,
-    MediaPlayerID player_id) {
-  switch (event_source) {
-    case ASM_EVENT_SOURCE_CALL_START:
-    case ASM_EVENT_SOURCE_ALARM_START:
-    case ASM_EVENT_SOURCE_MEDIA:
-    case ASM_EVENT_SOURCE_EMERGENCY_START:
-    case ASM_EVENT_SOURCE_OTHER_PLAYER_APP:
-    case ASM_EVENT_SOURCE_RESOURCE_CONFLICT:
-      Send(new MediaPlayerMsg_MediaPlayerPause(routing_id(), player_id));
-      return ASM_CB_RES_PAUSE;
-    default:
-      return ASM_CB_RES_NONE;
-    }
-}
-
-ASM_cb_result_t BrowserMediaPlayerManager::AudioSessionEventPlay(
-    ASM_event_sources_t event_source,
-    MediaPlayerID player_id) {
-  switch (event_source) {
-    case ASM_EVENT_SOURCE_ALARM_END:
-      Send(new MediaPlayerMsg_MediaPlayerPlay(routing_id(), player_id));
-      return ASM_CB_RES_PLAYING;
-    default:
-      return ASM_CB_RES_NONE;
-  }
-}
-
-static ASM_cb_result_t AudioSessionNotifyCallback(
-    int handle,
-    ASM_event_sources_t event_source,
-    ASM_sound_commands_t command,
-    unsigned int sound_status,
-    void* callback_data) {
-  AudioSessionManager* data =
-      static_cast<AudioSessionManager*>(callback_data);
-
-  BrowserMediaPlayerManager* manager = data->media_player_manager();
-  if (command == ASM_COMMAND_STOP || command == ASM_COMMAND_PAUSE)
-    return manager->AudioSessionEventPause(event_source, data->player_id());
-  if (command == ASM_COMMAND_PLAY || command == ASM_COMMAND_RESUME)
-    return manager->AudioSessionEventPlay(event_source, data->player_id());
-
-  return ASM_CB_RES_NONE;
-}
-
-void BrowserMediaPlayerManager::OnInitialize(
-    MediaPlayerID player_id,
-    int process_id,
-    const GURL& url) {
-
-  // Initialize the audio session manager library.
-  if (!InitializeAudioSessionManager()) {
-    DLOG(WARNING) << "Failed on loading the audio session manager library";
-    return;
-  }
-
-  RemoveAudioSessionManager(player_id);
-  AudioSessionManager* session_manager =
-      new AudioSessionManager(this, player_id, process_id);
-
-  session_manager->RegisterAudioSessionManager(
-      ASM_EVENT_SHARE_MMPLAYER,
-      AudioSessionNotifyCallback,
-      session_manager);
-  session_manager->SetSoundState(ASM_STATE_PAUSE);
-
-  AddAudioSessionManager(session_manager);
-}
-
-void BrowserMediaPlayerManager::OnDestroyAllMediaPlayers() {
-  audio_session_managers_.clear();
-}
-
-void BrowserMediaPlayerManager::OnDestroyPlayer(MediaPlayerID player_id) {
-  RemoveAudioSessionManager(player_id);
-}
-
-void BrowserMediaPlayerManager::OnPause(MediaPlayerID player_id) {
-  AudioSessionManager* session_manager = GetAudioSessionManager(player_id);
-  if (session_manager)
-    session_manager->SetSoundState(ASM_STATE_PAUSE);
-}
-
-void BrowserMediaPlayerManager::OnStart(MediaPlayerID player_id) {
-  AudioSessionManager* session_manager = GetAudioSessionManager(player_id);
-  if (session_manager)
-    session_manager->SetSoundState(ASM_STATE_PLAYING);
-}
-
-void BrowserMediaPlayerManager::AddAudioSessionManager(
-    AudioSessionManager* session_manager) {
-  DCHECK(!GetAudioSessionManager(session_manager->player_id()));
-  audio_session_managers_.push_back(session_manager);
-}
-
-void BrowserMediaPlayerManager::RemoveAudioSessionManager(
-    MediaPlayerID player_id) {
-  for (ScopedVector<AudioSessionManager>::iterator it =
-      audio_session_managers_.begin(); it != audio_session_managers_.end();
-      ++it) {
-    if ((*it)->player_id() == player_id) {
-      audio_session_managers_.erase(it);
-      break;
-    }
-  }
-}
-
-}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/browser_mediaplayer_manager.h b/src/xwalk/tizen/browser/browser_mediaplayer_manager.h
deleted file mode 100644 (file)
index 41fb838..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Copyright (c) 2013 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_TIZEN_BROWSER_BROWSER_MEDIAPLAYER_MANAGER_H_
-#define XWALK_TIZEN_BROWSER_BROWSER_MEDIAPLAYER_MANAGER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
-#include "content/public/browser/web_contents_observer.h"
-#include "url/gurl.h"
-#include "xwalk/tizen/browser/audio_session_manager.h"
-
-namespace tizen {
-
-// This class manages all AudioSessionManager objects in the browser
-// process. It receives control operations from the render process, and
-// forwards them to corresponding AudioSessionManager object. Callbacks
-// from AudioSessionManager objects are converted to IPCs and then sent
-// to the render process.
-class CONTENT_EXPORT BrowserMediaPlayerManager
-    : public content::WebContentsObserver {
- public:
-  virtual ~BrowserMediaPlayerManager();
-
-  // Returns a new instance.
-  static BrowserMediaPlayerManager* Create(
-      content::RenderViewHost* render_view_host);
-
-  // WebContentsObserver overrides.
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual AudioSessionManager* GetAudioSessionManager(
-      MediaPlayerID player_id) OVERRIDE;
-
-  ASM_cb_result_t AudioSessionEventPause(
-      ASM_event_sources_t eventSource, MediaPlayerID player_id);
-  ASM_cb_result_t AudioSessionEventPlay(
-      ASM_event_sources_t eventSource, MediaPlayerID player_id);
-
- protected:
-  explicit BrowserMediaPlayerManager(content::RenderViewHost* render_view_host);
-
- private:
-  virtual void OnInitialize(MediaPlayerID player_id,
-      int process_id, const GURL& url);
-  virtual void OnDestroyAllMediaPlayers();
-  virtual void OnDestroyPlayer(MediaPlayerID player_id);
-  virtual void OnPause(MediaPlayerID player_id);
-  virtual void OnStart(MediaPlayerID player_id);
-
-  // Adds a audio session manager for the given player to the list.
-  void AddAudioSessionManager(AudioSessionManager* session_manager);
-
-  // Removes the audio session manager of given |player_id|.
-  void RemoveAudioSessionManager(MediaPlayerID player_id);
-
-  ScopedVector<AudioSessionManager> audio_session_managers_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserMediaPlayerManager);
-};
-
-}  // namespace tizen
-
-#endif  // XWALK_TIZEN_BROWSER_BROWSER_MEDIAPLAYER_MANAGER_H_
diff --git a/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc b/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.cc
new file mode 100644 (file)
index 0000000..b5b4253
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 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/tizen/browser/media/browser_mediaplayer_manager.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"
+
+namespace tizen {
+
+BrowserMediaPlayerManager::BrowserMediaPlayerManager(
+    content::RenderFrameHost* render_frame_host,
+    MurphyResourceManager* resource_manager)
+    : render_frame_host_(render_frame_host),
+      resource_manager_(resource_manager) {
+}
+
+BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {}
+
+BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
+    content::RenderFrameHost* render_frame_host,
+    MurphyResourceManager* resource_manager) {
+  return new BrowserMediaPlayerManager(render_frame_host, resource_manager);
+}
+
+MurphyResource* BrowserMediaPlayerManager::GetMurphyResource(
+    MediaPlayerID player_id) {
+  for (ScopedVector<MurphyResource>::iterator it =
+      murphy_resources_.begin(); it != murphy_resources_.end();
+      ++it) {
+    if ((*it)->player_id() == player_id)
+      return *it;
+  }
+
+  return NULL;
+}
+
+int BrowserMediaPlayerManager::RoutingID() {
+  return render_frame_host_->GetRoutingID();
+}
+
+bool BrowserMediaPlayerManager::Send(IPC::Message* msg) {
+  return render_frame_host_->Send(msg);
+}
+
+void BrowserMediaPlayerManager::ResourceNotifyCallback(
+    mrp_res_resource_state_t state,
+    MediaPlayerID player_id) {
+
+  MurphyResource* resource = GetMurphyResource(player_id);
+
+  mrp_res_resource_state_t prev_state = resource->GetResourceState();
+
+  // Received a resource event from Murphy
+  switch (state) {
+    case MRP_RES_RESOURCE_AVAILABLE:
+      if (prev_state == MRP_RES_RESOURCE_ACQUIRED)
+        Send(new MediaPlayerMsg_MediaPlayerPause(RoutingID(), player_id));
+    case MRP_RES_RESOURCE_LOST:
+      if (prev_state == MRP_RES_RESOURCE_ACQUIRED ||
+          prev_state == MRP_RES_RESOURCE_LOST)
+        Send(new MediaPlayerMsg_MediaPlayerPause(RoutingID(), player_id));
+      break;
+    case MRP_RES_RESOURCE_ACQUIRED:
+      if (prev_state == MRP_RES_RESOURCE_LOST)
+        Send(new MediaPlayerMsg_MediaPlayerPlay(RoutingID(), player_id));
+      break;
+    case MRP_RES_RESOURCE_PENDING:
+      break;
+    default:
+      NOTREACHED();
+      break;
+    }
+}
+
+void BrowserMediaPlayerManager::OnInitialize(
+    MediaPlayerID player_id,
+    int process_id,
+    const GURL& url) {
+  // Create murphy resource for the given player id.
+  if (resource_manager_ && resource_manager_->IsConnected()) {
+    MurphyResource* resource = new MurphyResource(this,
+        player_id, resource_manager_);
+    RemoveMurphyResource(player_id);
+    AddMurphyResource(resource);
+  }
+}
+
+void BrowserMediaPlayerManager::OnDestroyPlayer(MediaPlayerID player_id) {
+  RemoveMurphyResource(player_id);
+}
+
+void BrowserMediaPlayerManager::OnPause(MediaPlayerID player_id) {
+  if (MurphyResource* resource = GetMurphyResource(player_id))
+    resource->ReleaseResource();
+}
+
+void BrowserMediaPlayerManager::OnStart(MediaPlayerID player_id) {
+  if (MurphyResource* resource = GetMurphyResource(player_id))
+    resource->AcquireResource();
+}
+
+void BrowserMediaPlayerManager::AddMurphyResource(
+    MurphyResource* resource) {
+  DCHECK(!GetMurphyResource(resource->player_id()));
+  murphy_resources_.push_back(resource);
+}
+
+void BrowserMediaPlayerManager::RemoveMurphyResource(
+    MediaPlayerID player_id) {
+  for (ScopedVector<MurphyResource>::iterator it =
+      murphy_resources_.begin(); it != murphy_resources_.end();
+      ++it) {
+    if ((*it)->player_id() == player_id) {
+      murphy_resources_.erase(it);
+      break;
+    }
+  }
+}
+
+}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.h b/src/xwalk/tizen/browser/media/browser_mediaplayer_manager.h
new file mode 100644 (file)
index 0000000..7eb8632
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 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_TIZEN_BROWSER_MEDIA_BROWSER_MEDIAPLAYER_MANAGER_H_
+#define XWALK_TIZEN_BROWSER_MEDIA_BROWSER_MEDIAPLAYER_MANAGER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "url/gurl.h"
+#include "xwalk/tizen/browser/media/murphy_resource_manager.h"
+#include "xwalk/tizen/browser/media/murphy_resource.h"
+
+namespace tizen {
+
+// This class manages all MurphyResource objects in the browser process. It
+// receives control operations from the render process, and forwards them to
+// corresponding MurphyResource object. Callbacks from MurphyResource objects
+// are converted to IPCs and then sent to the render process.
+class CONTENT_EXPORT BrowserMediaPlayerManager {
+ public:
+  virtual ~BrowserMediaPlayerManager();
+
+  // Returns a new instance.
+  static BrowserMediaPlayerManager* Create(
+      content::RenderFrameHost* render_frame_host,
+      MurphyResourceManager* resource_manager);
+
+  virtual MurphyResource* GetMurphyResource(
+      MediaPlayerID player_id);
+
+  void ResourceNotifyCallback(mrp_res_resource_state_t state,
+      MediaPlayerID player_id);
+
+  int RoutingID();
+
+  // Helper function to send messages to RenderFrameObserver.
+  bool Send(IPC::Message* msg);
+
+  // Message handlers.
+  virtual void OnInitialize(MediaPlayerID player_id,
+      int process_id, const GURL& url);
+  virtual void OnDestroyPlayer(MediaPlayerID player_id);
+  virtual void OnPause(MediaPlayerID player_id);
+  virtual void OnStart(MediaPlayerID player_id);
+
+ protected:
+  explicit BrowserMediaPlayerManager(
+      content::RenderFrameHost* render_frame_host,
+      MurphyResourceManager* resource_manager);
+
+ private:
+  // Adds a murphy resource for the given player to the list.
+  void AddMurphyResource(MurphyResource* resource);
+
+  // Removes the murphy resource of given |player_id|.
+  void RemoveMurphyResource(MediaPlayerID player_id);
+
+  content::RenderFrameHost* const render_frame_host_;
+
+  MurphyResourceManager* resource_manager_;
+  ScopedVector<MurphyResource> murphy_resources_;
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserMediaPlayerManager);
+};
+
+}  // namespace tizen
+
+#endif  // XWALK_TIZEN_BROWSER_MEDIA_BROWSER_MEDIAPLAYER_MANAGER_H_
diff --git a/src/xwalk/tizen/browser/media/media_webcontents_observer.cc b/src/xwalk/tizen/browser/media/media_webcontents_observer.cc
new file mode 100644 (file)
index 0000000..486db9b
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 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/tizen/browser/media/media_webcontents_observer.h"
+
+#include "content/public/browser/web_contents.h"
+#include "xwalk/tizen/browser/media/browser_mediaplayer_manager.h"
+#include "xwalk/tizen/browser/media/murphy_resource_manager.h"
+#include "xwalk/tizen/common/media/media_player_messages.h"
+
+namespace tizen {
+
+MediaWebContentsObserver::MediaWebContentsObserver(
+    content::RenderViewHost* render_view_host)
+    : WebContentsObserver(content::WebContents::FromRenderViewHost(
+          render_view_host)) {
+  resource_manager_.reset(new MurphyResourceManager());
+}
+
+MediaWebContentsObserver::~MediaWebContentsObserver() {}
+
+void MediaWebContentsObserver::RenderFrameDeleted(
+    content::RenderFrameHost* render_frame_host) {
+  uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
+  media_player_managers_.erase(key);
+}
+
+bool MediaWebContentsObserver::OnMessageReceived(
+    const IPC::Message& msg,
+    content::RenderFrameHost* render_frame_host) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg)
+    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_MediaPlayerInitialize,
+                        GetMediaPlayerManager(render_frame_host),
+                        BrowserMediaPlayerManager::OnInitialize)
+    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_MediaPlayerStarted,
+                        GetMediaPlayerManager(render_frame_host),
+                        BrowserMediaPlayerManager::OnStart)
+    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_MediaPlayerPaused,
+                        GetMediaPlayerManager(render_frame_host),
+                        BrowserMediaPlayerManager::OnPause)
+    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer,
+                        GetMediaPlayerManager(render_frame_host),
+                        BrowserMediaPlayerManager::OnDestroyPlayer)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+
+  return handled;
+}
+
+BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager(
+    content::RenderFrameHost* render_frame_host) {
+  uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
+  if (!media_player_managers_.contains(key)) {
+    media_player_managers_.set(
+        key,
+        make_scoped_ptr(BrowserMediaPlayerManager::Create(render_frame_host,
+            resource_manager_.get())));
+  }
+
+  return media_player_managers_.get(key);
+}
+
+}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/media/media_webcontents_observer.h b/src/xwalk/tizen/browser/media/media_webcontents_observer.h
new file mode 100644 (file)
index 0000000..ec3b87c
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2012 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_TIZEN_BROWSER_MEDIA_MEDIA_WEBCONTENTS_OBSERVER_H_
+#define XWALK_TIZEN_BROWSER_MEDIA_MEDIA_WEBCONTENTS_OBSERVER_H_
+
+#include "base/compiler_specific.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "xwalk/tizen/browser/media/murphy_resource_manager.h"
+
+namespace tizen {
+
+class BrowserMediaPlayerManager;
+class RenderViewHost;
+
+// This class manages all RenderFrame based media related managers at the
+// browser side. It receives IPC messages from media RenderFrameObservers and
+// forwards them to the corresponding managers. The managers are responsible
+// for sending IPCs back to the RenderFrameObservers at the render side.
+class CONTENT_EXPORT MediaWebContentsObserver :
+    public content::WebContentsObserver {
+ public:
+  explicit MediaWebContentsObserver(content::RenderViewHost* render_view_host);
+  virtual ~MediaWebContentsObserver();
+
+  // WebContentsObserver implementations.
+  virtual void RenderFrameDeleted(
+      content::RenderFrameHost* render_frame_host) OVERRIDE;
+  virtual bool OnMessageReceived(const IPC::Message& message,
+      content::RenderFrameHost* render_frame_host) OVERRIDE;
+
+  // Gets the media player manager associated with |render_frame_host|. Creates
+  // a new one if it doesn't exist. The caller doesn't own the returned pointer.
+  BrowserMediaPlayerManager* GetMediaPlayerManager(
+      content::RenderFrameHost* render_frame_host);
+
+ private:
+  // Map from RenderFrameHost* to BrowserMediaPlayerManager.
+  typedef base::ScopedPtrHashMap<uintptr_t, BrowserMediaPlayerManager>
+      MediaPlayerManagerMap;
+  MediaPlayerManagerMap media_player_managers_;
+
+  scoped_ptr<MurphyResourceManager> resource_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserver);
+};
+
+}  // namespace tizen
+
+#endif  // XWALK_TIZEN_BROWSER_MEDIA_MEDIA_WEBCONTENTS_OBSERVER_H_
diff --git a/src/xwalk/tizen/browser/media/murphy_mainloop.cc b/src/xwalk/tizen/browser/media/murphy_mainloop.cc
new file mode 100644 (file)
index 0000000..d84d488
--- /dev/null
@@ -0,0 +1,708 @@
+// 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/tizen/browser/media/murphy_mainloop.h"
+
+#include <errno.h>
+#include <murphy/common/macros.h>
+#include <murphy/common/log.h>
+#include <murphy/common/mm.h>
+#include <sys/socket.h>
+
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_libevent.h"
+#include "content/public/browser/browser_thread.h"
+
+//
+// The Murphy resource libraries don't have interfaces that would allow one
+// to take externally care of the IPC necessary for communicating with the
+// server (the policy decision making entity). Instead these libraries always
+// operate within the context of a Murphy mainloop abstraction which by design
+// can be set up to be pumped by an external event loop. The MurphyMainloop
+// class below creates a Murphy mainloop and takes care of the details of
+// adapting it to be pumped by the local MessageLoop infrastructure.
+//
+// The Murphy mainloop needs abstractions for I/O watches, timers, and deferred
+// callbacks from the hosting environment. If necessary it can get along with
+// just I/O watches and timers and emulate deferred callbacks by low-delay
+// timers. Murphy needs timers to be both cancellable and modifiable and it
+// deferred callbacks that can be disabled and re-enabled.
+//
+// The available infrastructure here offers the basic building blocks for all of
+// these but none of them are a perfect fit. Here is the summary of the tweaks
+// we need (in the hope) to get the Murphy mainloop running:
+//
+// 1) You can only do async I/O in the content::BrowserThread::IO thread.
+//
+//    We're running in content::BrowserThread::UI so we can't manipulate
+//    FileDescriptorWatchers there. To overcome this we need to relay all
+//    operations on FileDescriptorWatchers to content::BrowserThread::IO
+//    by PostTask. This will result in getting all the I/O events delivered
+//    to content::BrowserThread::IO. However, since we don't want to set up
+//    a (potentially) complex locking scheme to protect access to the mainloop
+//    we also relay FileDescriptorWatcher notifications back to the UI thread
+//    for processing. Finally to make sure there are no pending events in
+//    flight by the time we destroy an I/O watch we essentially drive the
+//    destructor through a full UI -> IO -> UI thread relay.
+//
+// 2) FileDescriptorWatchers don't have HUP events.
+//
+//    As a POSIX-specific hack we MSG_PEEK and generate a syntetic HUP event
+//    if we got 0 bytes.
+//
+// 3) You can't cancel a PostTask'd or PostDelayedTask'd task.
+//
+//    This prevents us from having a straightforward mapping of deferred
+//    callbacks and timers to these. To overcome this we use a 'timeout finger-
+//    print' which is used to ignore timeout callbacks that should have been
+//    cancelled if only there was a mechanism for it. The fingerprint in simply
+//    a monotonically increasing integer which is stored in the timer and also
+//    associated with a pending timeout. Whenever the timer is reconfigured
+//    (delay updated, or timer disabled) the fingerpring is updated. Timeout
+//    callbacks with mismatching fingerprints are ignored.
+//
+// Originally we simply scheduled a task from the I/O thread to the UI thread
+// for reading the pending epoll events there. But since poll/select is level-
+// triggered by default this caused a large amount of messages before the
+// scheduler got around to run the UI thread an read the events. Therefore now
+// the Murphy mainloop has been opened up for doing the actual event retrieval
+// externally to better support pumping it from xwalk. This now starts to be
+// hairier than I'm comfortable with... I think it'd be a better idea to run
+// the mainloop fully in the I/O thread, have the resource sets live in the I/O
+// thread also and have proxy object for them attached to the media backend
+// obejcts which would send requests and receive notifications to/from the
+// resource sets. We could avoid most of the threading related compliations
+// for pumping the mainloop...
+//
+// Additionally to the basic mainloop adaptation we also set up the Murphy
+// debugging and logging infrastructure to use the native logging infra as
+// a backend. You can control the Murphy logging and debugging by two
+// environment variables:
+//
+//    XWALK_MURPHY_LOG:
+//        A comma separated list of log levels, defaults to 'info,warning,error'
+//
+//    XWALK_MURPHY_DEBUG:
+//        A comma-separated list of Murphy debug sites, for instance
+//        '@mainloop.c,@resource.c,mrp_resource_set_create'. Setting this to
+//        '*' will turn all debug sites on.
+//
+
+
+// Environment variable names to used to control debugging and logging
+#define ENVVAR_DBG "XWALK_MURPHY_DEBUG"
+#define ENVVAR_LOG "XWALK_MURPHY_LOG"
+
+namespace {
+
+static void xwalklogger(void* data, mrp_log_level_t level, const char* file,
+    int line, const char* func, const char* format,
+    va_list ap) {
+  va_list cp;
+  char msg[1024], locbuf[1024];
+  const char* loc;
+
+  MRP_UNUSED(data);
+  MRP_UNUSED(file);
+  MRP_UNUSED(line);
+
+  va_copy(cp, ap);
+
+  if (level != MRP_LOG_DEBUG) {
+    loc = "";
+  } else {
+    snprintf(locbuf, sizeof(locbuf), "[%s] ", func ? func : "<unknown>");
+    loc = locbuf;
+  }
+
+  if (vsnprintf(msg, sizeof(msg), format, cp) < (ssize_t)sizeof(msg)) {
+    switch (level) {
+      case MRP_LOG_INFO:    LOG(INFO)    << loc << msg; break;
+      case MRP_LOG_WARNING: LOG(WARNING) << loc << msg; break;
+      case MRP_LOG_ERROR:   LOG(ERROR)   << loc << msg; break;
+      case MRP_LOG_DEBUG:  DLOG(INFO)    << loc << msg; break;
+      default:                                          break;
+    }
+  }
+
+  va_end(cp);
+}
+
+// Helper function to check if we have a pending HUP on an fd.
+static int pending_hup(int fd) {
+  char buf;
+  int  len, saved_errno;
+
+  saved_errno = errno;
+  len = recv(fd, &buf, 1, MSG_PEEK);
+  errno = saved_errno;
+
+  return len == 0;
+}
+
+}  // namespace
+
+namespace tizen {
+
+// An I/O watch abstraction for Murphy mainloop integration.
+//
+// As stated above, FileDescriptorWatcher's can only be manipulated
+// in BrowserThread::IO. As we execute in BrowserThread::UI we need
+// to relay watch manipulation operations to the I/O thread and
+// relay events back to the UI thread.
+class IoWatch : public base::MessagePumpLibevent::Watcher {
+ public:
+  // Constructor. Saves context and relays the watch setup to the I/O thread.
+  IoWatch(MurphyMainloop* mainloop, int fd, mrp_io_event_t events,
+      void (*cb)(void* glue_data, void* id, int fd, mrp_io_event_t events,
+      void* user_data), void* user_data)
+      : mainloop_(mainloop),
+        fd_(fd),
+        events_(events),
+        cb_(cb),
+        user_data_(user_data),
+        dead_(false) {
+    content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+        base::Bind(&IoWatch::StartWatch,
+        base::Unretained(this)));
+  }
+
+  // Request destruction. Mark dead, relay watch cleanup to the I/O thread.
+  // The destruction sequence is finished once StopWatch relays WatchStopped
+  // back to the UI thread.
+  void Delete() {
+    if (dead_)
+      return;
+    else
+      dead_ = true;
+
+    content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+        base::Bind(&IoWatch::StopWatch,
+        base::Unretained(this)));
+  }
+
+ private:
+  // Perform watch setup. Run in the I/O thread.
+  void StartWatch() {
+    base::MessageLoopForIO::Mode mode;
+
+    if (events_ & (MRP_IO_EVENT_IN | MRP_IO_EVENT_OUT))
+      mode = base::MessageLoopForIO::WATCH_READ_WRITE;
+    else if (events_ & MRP_IO_EVENT_IN)
+      mode = base::MessageLoopForIO::WATCH_READ;
+    else if (events_ & MRP_IO_EVENT_OUT)
+      mode = base::MessageLoopForIO::WATCH_WRITE;
+    else
+      mode = base::MessageLoopForIO::WATCH_READ;  // Hmm... not quite right.
+
+    const bool success = base::MessageLoopForIO::current()->WatchFileDescriptor(
+        fd_, true, mode, &w_, this);
+    CHECK(success) << "Failed to add I/O watch for fd " << fd_;
+  }
+
+  // Perform watch cleanup. Run in I/O thread.
+  void StopWatch() {
+    if (dead_)
+      return;
+    w_.StopWatchingFileDescriptor();
+
+    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+        base::Bind(&IoWatch::WatchStopped,
+        base::Unretained(this)));
+  }
+
+  // Finish the destruction sequence by self-deleting. Run in UI thread.
+  void WatchStopped() {
+    delete this;
+  }
+
+  // Watch readability event handler. Run in I/O thread. Relays dispatching
+  // to UI thread.
+  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
+    if (dead_)
+      return;
+
+    mainloop_->Poll(this);
+
+    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+        base::Bind(&IoWatch::DispatchReadable,
+        base::Unretained(this)));
+  }
+
+  // Watch writability event handler. Run in I/O thread. Relays dispatching
+  // to UI thread.
+  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
+    if (dead_)
+      return;
+
+    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+        base::Bind(&IoWatch::DispatchWritable,
+        base::Unretained(this)));
+  }
+
+  // Dispatch readability events the the mainloop.
+  void DispatchReadable() {
+    mrp_io_event_t events;
+    if (dead_)
+      return;
+
+    if ((events_ & MRP_IO_EVENT_HUP) && pending_hup(fd_))
+      events = MRP_IO_EVENT_HUP;
+    else
+      events = MRP_IO_EVENT_IN;
+
+    mrp_debug("dispatching crosswalk event 0x%x for fd %d", events, fd_);
+    cb_(reinterpret_cast<void*>(mainloop_), reinterpret_cast<void*>(this),
+        fd_, events, user_data_);
+  }
+
+  // Dispatch writability events the the mainloop.
+  void DispatchWritable() {
+    mrp_io_event_t events;
+    if (dead_)
+      return;
+
+    events = MRP_IO_EVENT_OUT;
+    mrp_debug("dispatching crosswalk event 0x%x for fd %d", events, fd_);
+    cb_(reinterpret_cast<void*>(mainloop_), reinterpret_cast<void*>(this),
+        fd_, events, user_data_);
+  }
+
+  // Associated mainloop data: fd, event mask, callback, and user data.
+  MurphyMainloop* mainloop_;
+  int fd_;
+  mrp_io_event_t events_;
+  void (*cb_)(void* glue_data, void* id, int fd, mrp_io_event_t events,
+      void* user_data);
+  void* user_data_;
+
+  // FileDescriptorWatcher we use for I/O monitoring
+  base::MessagePumpLibevent::FileDescriptorWatcher w_;
+
+  // flag used to mark initiated destruction sequence
+  bool dead_;
+
+  // A self-destructing object, so we have a private destructor
+  virtual ~IoWatch() {
+    mrp_debug("Destructing I/O watch");
+  }
+};
+
+// A Timer abstraction for Murphy mainloop integration.
+//
+// Since posted tasks cannot be cancelled, we use the stamped Timeout
+// object to filter out callbacks for timers that have been cancelled
+// (or reconfigured).
+class Timer;
+
+class Timeout : public base::RefCounted<Timeout> {
+ public:
+  explicit Timeout(Timer* t)
+      : timer_(t),
+        stamp_(0),
+        pending_(false) {
+    // Release upon timer destruction. We need to keep this object around
+    // until then.
+    AddRef();
+  }
+
+  // Clear Timeout for destruction. After this point all events are ignored.
+  // We're just waiting for the last reference to be Release()'d which is
+  // immediate if we have no pending timeouts. Otherwise it ought to happen
+  // once the last timeout has expired.
+  void Delete() {
+    timer_ = NULL;
+    Release();
+  }
+
+  // Arm or rearm the timeout with the given delay.
+  void Arm(int delay) {
+    base::TimeDelta delta(base::TimeDelta::FromMilliseconds(delay));
+    InvalidatePending();
+    content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
+        FROM_HERE,
+        base::Bind(&Timeout::Expired,
+        this, stamp_), delta);
+
+    pending_ = true;
+  }
+
+  // Disable timeouts.
+  void Disable() {
+    InvalidatePending();
+  }
+
+ private:
+  // Invalidate any possible pending Timeouts.
+  inline void InvalidatePending() {
+    if (pending_)
+      stamp_++;
+  }
+
+  // Timeout handler callback. Filter cancelled timeouts, deliver valid
+  // timeouts to the parent Timer.
+  void Expired(unsigned int stamp);
+
+  ~Timeout() {
+    mrp_debug("destructing Timeout %p", this);
+  }
+
+  // We're refcounted and have a private destructor...
+  friend class base::RefCounted<Timeout>;
+
+  // Timer we're serving.
+  Timer* timer_;
+
+  // Fingerprint stamp.
+  unsigned int stamp_;
+
+  // Flag to mark if we have pending timeouts.
+  bool pending_;
+};
+
+class Timer {
+ public:
+  Timer(MurphyMainloop* mainloop, int delay,
+      void (*cb)(void* glue_data, void* id, void* user_data),
+      void* user_data)
+      : mainloop_(mainloop),
+        cb_(cb),
+        user_data_(user_data),
+        delay_(delay),
+        enabled_(true),
+        timeout_(NULL) {
+    timeout_ = new Timeout(this);
+    ReArm();
+  }
+
+  // Upon timer destruction, initiate timeout destruction sequence and release
+  // its initial reference.
+  ~Timer() {
+    timeout_->Delete();
+  }
+
+  // Change timer delay.
+  void SetDelay(int delay) {
+    delay_ = delay;
+    ReArm();
+  }
+
+  // Enable timer.
+  void Enable() {
+    if (!enabled_) {
+      enabled_ = true;
+      ReArm();
+    }
+  }
+
+  // Disable timer.
+  void Disable() {
+    enabled_ = false;
+    timeout_->Disable();
+  }
+
+ private:
+  // Re-arm the timer with the current delay if it is enabled.
+  void ReArm() {
+    if (!enabled_ || delay_ == -1)
+      return;
+
+    mrp_debug("rearming timer %p (delay %d)", this, delay_);
+
+    timeout_->Arm(delay_);
+  }
+
+  // Timeout handler callback.
+  void DispatchTimer() {
+    if (enabled_) {
+      mrp_debug("dispatching crosswalk timeout event %p", this);
+      cb_(reinterpret_cast<void*>(mainloop_), reinterpret_cast<void*>(this),
+          user_data_);
+    }
+
+    if (enabled_)
+      ReArm();
+  }
+
+ private:
+  // Let Timeout invoke DispatchTimer.
+  friend class Timeout;
+
+  // Associated mainloop data: timer callback and user data.
+  MurphyMainloop* mainloop_;
+  void (*cb_)(void* glue_data, void* id, void* user_data);
+  void* user_data_;
+
+  // Our timeout in milliseconds.
+  int delay_;
+
+  // Whether we're enabled.
+  bool enabled_;
+
+  // Our associated timeout.
+  Timeout* timeout_;
+};
+
+void Timeout::Expired(unsigned int stamp) {
+  if (timer_ == NULL || stamp != stamp_)
+    return;
+
+  pending_ = false;
+
+  timer_->DispatchTimer();
+}
+
+MurphyMainloop::MurphyMainloop(const char* log, const char* debug)
+    : mainloop_(NULL),
+      poll_id_(NULL) {
+  mrp_list_init(&poll_q_);
+  setupLogger(log, debug);
+
+  CHECK(setupMainloop());
+}
+
+MurphyMainloop::~MurphyMainloop() {
+  mrp_debug("destroying MurphyMainloop");
+  mrp_mainloop_destroy(mainloop_);
+}
+
+
+// Crosswalk mainloop abstraction operations
+void* MurphyMainloop::AddIo(void* glue_data, int fd, mrp_io_event_t events,
+    void (*cb)(void* glue_data, void* id, int fd, mrp_io_event_t events,
+    void* user_data), void* user_data) {
+
+  MurphyMainloop* self = static_cast<MurphyMainloop*>(glue_data);
+
+  CHECK(self->poll_id_ == NULL);
+
+  self->poll_id_ = new IoWatch(self, fd, events, cb, user_data);
+
+  mrp_debug("added I/O Watch %p for fd %d (glue_data: %p)", self->poll_id_, fd,
+            glue_data);
+
+  return self->poll_id_;
+}
+
+// static
+void MurphyMainloop::DelIo(void* glue_data, void* id) {
+  IoWatch* w = static_cast<IoWatch*>(id);
+
+  mrp_debug("deleting I/O Watch %p", id);
+  w->Delete();
+}
+
+
+extern "C" {
+  typedef struct {
+    mrp_list_hook_t hook;
+    void* buf;
+    size_t size;
+  } pollq_data_t;
+}
+
+
+void MurphyMainloop::Poll(void* id) {
+  pollq_data_t* item;
+
+  mrp_debug("polling pending epoll events for the mainloop (id: %p)", id);
+
+#if 0
+  CHECK(poll_id_ == id);
+  CHECK(poll_events_);
+#else
+  if (poll_id_ != id || !poll_events_)
+    return;
+#endif
+
+  item = reinterpret_cast<pollq_data_t *>(mrp_allocz(sizeof(*item)));
+
+  if (item == NULL)
+    return;
+
+  mrp_list_init(&item->hook);
+  item->size = poll_events_(id, mainloop_, &item->buf);
+
+  poll_lock_.Acquire();
+  mrp_list_append(&poll_q_, &item->hook);
+  poll_lock_.Release();
+}
+
+
+// static
+size_t MurphyMainloop::PollIo(void* glue_data,
+    void* id, void* buf, size_t size) {
+  MurphyMainloop* self = static_cast<MurphyMainloop*>(glue_data);
+  pollq_data_t* item;
+
+  mrp_debug("dispatching epoll events to the mainloop (id: %p)", id);
+
+#if 0
+  CHECK(self->poll_id_ == id);
+#else
+  if (self->poll_id_ != id)
+    return 0;
+#endif
+
+  self->poll_lock_.Acquire();
+  if (!mrp_list_empty(&self->poll_q_)) {
+    item = mrp_list_entry(self->poll_q_.next, pollq_data_t, hook);
+    mrp_list_delete(&item->hook);
+  } else {
+    item = NULL;
+  }
+
+  self->poll_lock_.Release();
+
+  if (item != NULL) {
+    CHECK(size >= item->size);
+
+    size = item->size;
+    memcpy(buf, item->buf, size);
+
+    mrp_free(item);
+  } else {
+    size = 0;
+  }
+
+  return size;
+}
+
+// static
+void* MurphyMainloop::AddTimer(void* glue_data, unsigned int msecs,
+    void (*cb)(void* glue_data, void* id, void* user_data),
+    void* user_data) {
+  MurphyMainloop* self = static_cast<MurphyMainloop*>(glue_data);
+  mrp_debug("adding Timer with %u msecs, %p user data", msecs, user_data);
+
+  return new Timer(self, static_cast<int>(msecs), cb, user_data);
+}
+
+// static
+void MurphyMainloop::DelTimer(void* glue_data, void* id) {
+  Timer* t = reinterpret_cast<Timer*>(id);
+  MRP_UNUSED(glue_data);
+
+  mrp_debug("deleting Timer %p", id);
+  delete t;
+}
+
+// static
+void MurphyMainloop::ModTimer(void* glue_data, void* id, unsigned int msecs) {
+  Timer* t = reinterpret_cast<Timer*>(id);
+  MRP_UNUSED(glue_data);
+
+  mrp_debug("modifying Timer %p to %u msecs", t, msecs);
+  t->SetDelay(msecs);
+}
+
+// static
+void* MurphyMainloop::AddDefer(void* glue_data,
+    void (*cb)(void* glue_data, void* id, void* user_data),
+    void* user_data) {
+  mrp_debug("adding deferred callback (cb:%p, user data:%p)", cb, user_data);
+  return AddTimer(glue_data, 0, cb, user_data);
+}
+
+// static
+void MurphyMainloop::DelDefer(void* glue_data, void* id) {
+  MRP_UNUSED(glue_data);
+
+  mrp_debug("deleting deferred callback %p", id);
+
+  DelTimer(glue_data, id);
+}
+
+// static
+void MurphyMainloop::ModDefer(void* glue_data, void* id, int enabled) {
+  MRP_UNUSED(glue_data);
+  Timer* t = reinterpret_cast<Timer*>(id);
+
+  mrp_debug("%sabling deferred callback %p", enabled ? "en" : "dis", id);
+
+  if (enabled)
+    t->Enable();
+  else
+    t->Disable();
+}
+
+// static
+void MurphyMainloop::Unregister(void* data) {
+  MRP_UNUSED(data);
+
+  mrp_debug("unrgistering mainloop with data %p", data);
+}
+
+bool MurphyMainloop::setupMainloop() {
+  mainloop_ = mrp_mainloop_create();
+  mrp_set_io_event_mode(mainloop_, MRP_IO_TRIGGER_EDGE);
+
+  static mrp_superloop_ops_t ops = {
+    &MurphyMainloop::AddIo,
+    &MurphyMainloop::DelIo,
+    &MurphyMainloop::AddTimer,
+    &MurphyMainloop::DelTimer,
+    &MurphyMainloop::ModTimer,
+    &MurphyMainloop::AddDefer,
+    &MurphyMainloop::DelDefer,
+    &MurphyMainloop::ModDefer,
+    &MurphyMainloop::Unregister,
+    NULL,
+    &MurphyMainloop::PollIo,
+  };
+
+  if (mrp_set_superloop(mainloop_, &ops, this)) {
+    poll_events_ = ops.poll_events;
+    return true;
+  } else {
+    mrp_log_error("Failed to set up superloop.");
+    return false;
+  }
+}
+
+// Murphy crosswalk logging backend
+void MurphyMainloop::setupLogger(const char* logcfg, const char* dbgcfg) {
+  static bool registered = false;
+  const char *dbg, *log, *p, *n;
+  char        site[1024];
+  size_t      l;
+
+  if (registered)
+    return;
+
+  if (mrp_log_register_target("xwalk", xwalklogger, NULL))
+    mrp_log_set_target("xwalk");
+
+  // configure logging, environment variable overrides argument
+  if ((log = getenv(ENVVAR_LOG)) == NULL)
+    log = "none";
+
+  mrp_log_enable(mrp_log_parse_levels(log));
+
+  // configure debugging, environment variable overrides argument
+  if ((dbg = getenv(ENVVAR_DBG)) == NULL)
+    dbg = dbgcfg ? dbgcfg : "off";
+
+  if (strcmp(dbg, "off")) {
+    mrp_log_info("Enabling Murphy debugging (%s).", dbg);
+    mrp_debug_enable(true);
+
+    p = dbg;
+    while (p != NULL) {
+      n = strchr(p, ',');
+      l = n ? n - p : strlen(p);
+
+      if (l < sizeof(site) - 1) {
+        strncpy(site, p, l);
+        site[l] = '\0';
+        mrp_log_info("Enabling Murphy debug site '%s'.", site);
+        mrp_debug_set_config(site);
+      }
+      p = n ? n + 1 : NULL;
+    }
+  }
+  registered = true;
+}
+
+}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/media/murphy_mainloop.h b/src/xwalk/tizen/browser/media/murphy_mainloop.h
new file mode 100644 (file)
index 0000000..d229a1b
--- /dev/null
@@ -0,0 +1,67 @@
+// 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_TIZEN_BROWSER_MEDIA_MURPHY_MAINLOOP_H_
+#define XWALK_TIZEN_BROWSER_MEDIA_MURPHY_MAINLOOP_H_
+
+#include <murphy/common/mainloop.h>
+#include <murphy/common/list.h>
+
+#include "base/logging.h"
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/synchronization/lock.h"
+
+namespace tizen {
+
+class MurphyMainloop {
+ public:
+  explicit MurphyMainloop(const char* log = NULL, const char* debug = NULL);
+  virtual ~MurphyMainloop();
+  void Poll(void* id);
+
+  mrp_mainloop_t* getMainloop() {
+    return mainloop_;
+  }
+
+ private:
+  mrp_mainloop_t* mainloop_;
+  base::Lock poll_lock_;
+  size_t (*poll_events_)(void *id, mrp_mainloop_t *ml, void **events);
+  void* poll_id_;
+  mrp_list_hook_t poll_q_;
+
+  // set up Murphy logging to bridge to the native logging infra
+  static void setupLogger(const char* log, const char* debug);
+
+  // create and set up Murphy mainloop
+  bool setupMainloop();
+
+  // crosswalk mainloop abstraction operations
+  static void* AddIo(void* glue_data, int fd, mrp_io_event_t events,
+                     void (*cb)(void* glue_data, void* id, int fd,
+                                mrp_io_event_t events, void* user_data),
+                     void* user_data);
+  static void  DelIo(void* glue_data, void* id);
+  static size_t PollIo(void* glue_data, void* id, void* buf, size_t size);
+
+  static void* AddTimer(void* glue_data, unsigned int msecs,
+                        void (*cb)(void* glue_data, void* id, void* user_data),
+                        void* user_data);
+  static void  DelTimer(void* glue_data, void* id);
+  static void  ModTimer(void* glue_data, void* id, unsigned int msecs);
+
+  static void* AddDefer(void* glue_data,
+                        void (*cb)(void* glue_data, void* id, void* user_data),
+                        void* user_data);
+  static void  DelDefer(void* glue_data, void* id);
+  static void  ModDefer(void* glue_data, void* id, int enabled);
+
+  static void Unregister(void* data);
+};
+
+}  // namespace tizen
+
+#endif  // XWALK_TIZEN_BROWSER_MEDIA_MURPHY_MAINLOOP_H_
diff --git a/src/xwalk/tizen/browser/media/murphy_resource.cc b/src/xwalk/tizen/browser/media/murphy_resource.cc
new file mode 100644 (file)
index 0000000..711c02a
--- /dev/null
@@ -0,0 +1,86 @@
+// 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/tizen/browser/media/murphy_resource.h"
+
+#include "xwalk/tizen/browser/media/browser_mediaplayer_manager.h"
+
+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,
+    void* callback_data) {
+  tizen::MurphyResource* resource =
+    static_cast<tizen::MurphyResource*> (callback_data);
+  tizen::BrowserMediaPlayerManager* manager = resource->media_player_manager();
+  if (!manager)
+    return;
+
+  manager->ResourceNotifyCallback(resource_set->state, resource->player_id());
+  resource->SetResourceState(resource_set->state);
+}
+
+}  // namespace
+
+namespace tizen {
+
+MurphyResource::MurphyResource(
+    BrowserMediaPlayerManager* manager,
+    MediaPlayerID player_id,
+    MurphyResourceManager* resource_manager)
+    : manager_(manager),
+      player_id_(player_id),
+      resource_manager_(resource_manager),
+      resource_state_(MRP_RES_RESOURCE_PENDING) {
+  mrp_res_context_t* context = resource_manager_->GetContext();
+  if (!context)
+    return;
+
+  resource_set_ = mrp_res_create_resource_set(context,
+      kMediaApplicationClass, 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");
+  if (attr)
+    mrp_res_set_attribute_string(attr, kMediaRole);
+
+  mrp_res_release_resource_set(resource_set_);
+}
+
+void MurphyResource::AcquireResource() {
+  if (!resource_manager_ || !resource_set_)
+    return;
+
+  // Call acquire
+  mrp_res_acquire_resource_set(resource_set_);
+}
+
+void MurphyResource::ReleaseResource() {
+  if (!resource_manager_ || !resource_set_)
+    return;
+
+  // Call release
+  mrp_res_release_resource_set(resource_set_);
+}
+
+MurphyResource::~MurphyResource() {
+  ReleaseResource();
+
+  if (!resource_manager_ || !resource_set_)
+    return;
+
+  // Delete resource set (and the resource inside it)
+  mrp_res_delete_resource_set(resource_set_);
+}
+
+}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/media/murphy_resource.h b/src/xwalk/tizen/browser/media/murphy_resource.h
new file mode 100644 (file)
index 0000000..895810d
--- /dev/null
@@ -0,0 +1,45 @@
+// 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_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_H_
+#define XWALK_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_H_
+
+#include "xwalk/tizen/browser/media/murphy_resource_manager.h"
+
+namespace tizen {
+
+typedef int MediaPlayerID;
+
+class MurphyResource {
+ public:
+  MurphyResource(BrowserMediaPlayerManager* manager,
+      MediaPlayerID player_id,
+      MurphyResourceManager* resource_manager);
+  ~MurphyResource();
+
+  void AcquireResource();
+  void ReleaseResource();
+
+  mrp_res_resource_state_t GetResourceState() const { return resource_state_; }
+  void SetResourceState(mrp_res_resource_state_t state) {
+    resource_state_ = state;
+  }
+
+  MediaPlayerID player_id() const { return player_id_; }
+  BrowserMediaPlayerManager* media_player_manager() {
+    return manager_;
+  }
+
+ private:
+  BrowserMediaPlayerManager* manager_;
+  MediaPlayerID player_id_;
+  MurphyResourceManager* resource_manager_;
+
+  mrp_res_resource_set_t* resource_set_;
+  mrp_res_resource_state_t resource_state_;
+};
+
+}  // namespace tizen
+
+#endif  // XWALK_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_H_
diff --git a/src/xwalk/tizen/browser/media/murphy_resource_manager.cc b/src/xwalk/tizen/browser/media/murphy_resource_manager.cc
new file mode 100644 (file)
index 0000000..4475ff6
--- /dev/null
@@ -0,0 +1,71 @@
+// 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/tizen/browser/media/murphy_resource_manager.h"
+
+#include "base/logging.h"
+
+namespace {
+
+static void NotifyCallback(mrp_res_context_t* context,
+    mrp_res_error_t error, void* callback_data) {
+  if (error != MRP_RES_ERROR_NONE) {
+    LOG(ERROR) << "Error message received from Murphy. errcode=" << error;
+    return;
+  }
+
+  if (context->state == MRP_RES_DISCONNECTED) {
+    tizen::MurphyResourceManager* resource =
+      static_cast<tizen::MurphyResourceManager*> (callback_data);
+    if (resource)
+      resource->DisconnectFromMurphy();
+  }
+}
+
+}  // namespace
+
+namespace tizen {
+
+MurphyResourceManager::MurphyResourceManager()
+    : murphy_context_(NULL),
+      murphy_mainloop_(new MurphyMainloop()),
+      mainloop_(murphy_mainloop_->getMainloop()) {
+  // Connect to murphy.
+  ConnectToMurphy();
+}
+
+MurphyResourceManager::~MurphyResourceManager() {
+  DisconnectFromMurphy();
+}
+
+void MurphyResourceManager::ConnectToMurphy() {
+  if (murphy_context_) {
+    mrp_res_destroy(murphy_context_);
+    murphy_context_ = NULL;
+  }
+
+  if (!murphy_context_)
+    murphy_context_ = mrp_res_create(mainloop_, NotifyCallback, this);
+}
+
+bool MurphyResourceManager::IsConnected() const {
+  if (!murphy_context_)
+    return false;
+
+  return murphy_context_->state == MRP_RES_CONNECTED;
+}
+
+void MurphyResourceManager::DisconnectFromMurphy() {
+  if (!murphy_context_)
+    return;
+
+  mrp_res_destroy(murphy_context_);
+  murphy_context_ = NULL;
+}
+
+mrp_res_context_t* MurphyResourceManager::GetContext() {
+  return murphy_context_;
+}
+
+}  // namespace tizen
diff --git a/src/xwalk/tizen/browser/media/murphy_resource_manager.h b/src/xwalk/tizen/browser/media/murphy_resource_manager.h
new file mode 100644 (file)
index 0000000..0f4e310
--- /dev/null
@@ -0,0 +1,35 @@
+// 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_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_MANAGER_H_
+#define XWALK_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_MANAGER_H_
+
+#include <murphy/plugins/resource-native/libmurphy-resource/resource-api.h>
+
+#include "base/memory/scoped_ptr.h"
+#include "xwalk/tizen/browser/media/murphy_mainloop.h"
+
+namespace tizen {
+class BrowserMediaPlayerManager;
+
+class MurphyResourceManager {
+ public:
+  MurphyResourceManager();
+  ~MurphyResourceManager();
+
+  void ConnectToMurphy();
+  void DisconnectFromMurphy();
+  bool IsConnected() const;
+
+  mrp_res_context_t* GetContext();
+
+ private:
+  mrp_res_context_t* murphy_context_;
+  scoped_ptr<MurphyMainloop> murphy_mainloop_;
+  mrp_mainloop_t* mainloop_;
+};
+
+}  // namespace tizen
+
+#endif  // XWALK_TIZEN_BROWSER_MEDIA_MURPHY_RESOURCE_MANAGER_H_
@@ -32,9 +32,6 @@ IPC_MESSAGE_ROUTED1(MediaPlayerMsg_MediaPlayerPause,  // NOLINT(*)
 IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_DestroyMediaPlayer,  // NOLINT(*)
                     int /* player_id */)
 
-// Destroy all the players.
-IPC_MESSAGE_ROUTED0(MediaPlayerHostMsg_DestroyAllMediaPlayers)  // NOLINT(*)
-
 // Initialize a media player object with the given player_id.
 IPC_MESSAGE_ROUTED3(MediaPlayerHostMsg_MediaPlayerInitialize,  // NOLINT(*)
                     int /* player_id */,
@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/tizen/renderer/mediaplayer_impl.h"
+#include "xwalk/tizen/renderer/media/mediaplayer_impl.h"
 
 #include "content/public/renderer/render_view.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 namespace tizen {
 
 MediaPlayerImpl::MediaPlayerImpl(
-    blink::WebFrame* frame,
+    blink::WebLocalFrame* frame,
     blink::WebMediaPlayerClient* client,
     base::WeakPtr<content::WebMediaPlayerDelegate> delegate,
     RendererMediaPlayerManager* manager,
     const content::WebMediaPlayerParams& params)
     : WebMediaPlayerImpl(frame, client, delegate, params),
+      client_(client),
       manager_(manager) {
   DCHECK(manager_);
 
@@ -30,12 +31,6 @@ MediaPlayerImpl::~MediaPlayerImpl() {
   }
 }
 
-void MediaPlayerImpl::WillDestroyCurrentMessageLoop() {
-  if (manager_)
-    manager_->UnregisterMediaPlayer(player_id_);
-  Detach();
-}
-
 void MediaPlayerImpl::Detach() {
   manager_ = NULL;
 }
@@ -63,4 +58,14 @@ void MediaPlayerImpl::pause() {
   WebMediaPlayerImpl::pause();
 }
 
+void MediaPlayerImpl::OnMediaPlayerPlay() {
+  WebMediaPlayerImpl::play();
+  client_->playbackStateChanged();
+}
+
+void MediaPlayerImpl::OnMediaPlayerPause() {
+  WebMediaPlayerImpl::pause();
+  client_->playbackStateChanged();
+}
+
 }  // namespace tizen
@@ -4,13 +4,13 @@
 // found in the LICENSE file.
 
 
-#ifndef XWALK_TIZEN_RENDERER_MEDIAPLAYER_IMPL_H_
-#define XWALK_TIZEN_RENDERER_MEDIAPLAYER_IMPL_H_
+#ifndef XWALK_TIZEN_RENDERER_MEDIA_MEDIAPLAYER_IMPL_H_
+#define XWALK_TIZEN_RENDERER_MEDIA_MEDIAPLAYER_IMPL_H_
 
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/renderer/media/webmediaplayer_impl.h"
-#include "xwalk/tizen/renderer/renderer_mediaplayer_manager.h"
+#include "xwalk/tizen/renderer/media/renderer_mediaplayer_manager.h"
 
 namespace tizen {
 
@@ -18,7 +18,7 @@ namespace tizen {
 class MediaPlayerImpl : public content::WebMediaPlayerImpl {
  public:
   MediaPlayerImpl(
-      blink::WebFrame* frame,
+      blink::WebLocalFrame* frame,
       blink::WebMediaPlayerClient* client,
       base::WeakPtr<content::WebMediaPlayerDelegate> delegate,
       RendererMediaPlayerManager* manager,
@@ -34,17 +34,18 @@ class MediaPlayerImpl : public content::WebMediaPlayerImpl {
   virtual void play();
   virtual void pause();
 
-  // As we are closing the app, |main_loop_| is destroyed even before
-  // this object gets destructed, so we need to know when |main_loop_|
-  // is being destroyed and we can stop posting playback controls.
-  virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
-
   // Detach the player from its manager.
   void Detach();
 
+  // Functions called when media player status changes.
+  void OnMediaPlayerPlay();
+  void OnMediaPlayerPause();
+
  private:
   void InitializeMediaPlayer(const blink::WebURL& url);
 
+  blink::WebMediaPlayerClient* client_;
+
   // Manager for managing this object and for delegating method calls on
   // Render Thread.
   RendererMediaPlayerManager* manager_;
@@ -57,4 +58,4 @@ class MediaPlayerImpl : public content::WebMediaPlayerImpl {
 
 }  // namespace tizen
 
-#endif  // XWALK_TIZEN_RENDERER_MEDIAPLAYER_IMPL_H_
+#endif  // XWALK_TIZEN_RENDERER_MEDIA_MEDIAPLAYER_IMPL_H_
@@ -3,16 +3,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "xwalk/tizen/renderer/renderer_mediaplayer_manager.h"
+#include "xwalk/tizen/renderer/media/renderer_mediaplayer_manager.h"
 
-#include "xwalk/tizen/common/media_player_messages.h"
-#include "xwalk/tizen/renderer/mediaplayer_impl.h"
+#include "xwalk/tizen/common/media/media_player_messages.h"
+#include "xwalk/tizen/renderer/media/mediaplayer_impl.h"
 
 namespace tizen {
 
 RendererMediaPlayerManager::RendererMediaPlayerManager(
-    content::RenderView* render_view)
-    : content::RenderViewObserver(render_view),
+    content::RenderFrame* render_frame)
+    : content::RenderFrameObserver(render_frame),
       next_media_player_id_(0) {
 }
 
@@ -23,8 +23,6 @@ RendererMediaPlayerManager::~RendererMediaPlayerManager() {
     MediaPlayerImpl* player = player_it->second;
     player->Detach();
   }
-
-  Send(new MediaPlayerHostMsg_DestroyAllMediaPlayers(routing_id()));
 }
 
 bool RendererMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
@@ -81,12 +79,12 @@ MediaPlayerImpl* RendererMediaPlayerManager::GetMediaPlayer(
 
 void RendererMediaPlayerManager::OnPlayerPlay(MediaPlayerID player_id) {
   if (MediaPlayerImpl* player = GetMediaPlayer(player_id))
-    player->play();
+    player->OnMediaPlayerPlay();
 }
 
 void RendererMediaPlayerManager::OnPlayerPause(MediaPlayerID player_id) {
   if (MediaPlayerImpl* player = GetMediaPlayer(player_id))
-    player->pause();
+    player->OnMediaPlayerPause();
 }
 
 }  // namespace tizen
@@ -3,13 +3,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef XWALK_TIZEN_RENDERER_RENDERER_MEDIAPLAYER_MANAGER_H_
-#define XWALK_TIZEN_RENDERER_RENDERER_MEDIAPLAYER_MANAGER_H_
+#ifndef XWALK_TIZEN_RENDERER_MEDIA_RENDERER_MEDIAPLAYER_MANAGER_H_
+#define XWALK_TIZEN_RENDERER_MEDIA_RENDERER_MEDIAPLAYER_MANAGER_H_
 
 #include <map>
 
 #include "base/basictypes.h"
-#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_frame_observer.h"
 #include "url/gurl.h"
 
 namespace tizen {
@@ -19,10 +19,10 @@ typedef int MediaPlayerID;
 
 // Class for managing all the MediaPlayerImpl objects in the same
 // RenderView.
-class RendererMediaPlayerManager : public content::RenderViewObserver {
+class RendererMediaPlayerManager : public content::RenderFrameObserver {
  public:
   // Constructs a RendererMediaPlayerManager object for the |render_view|.
-  explicit RendererMediaPlayerManager(content::RenderView* render_view);
+  explicit RendererMediaPlayerManager(content::RenderFrame* render_frame);
   virtual ~RendererMediaPlayerManager();
 
   // RenderViewObserver overrides.
@@ -67,4 +67,4 @@ class RendererMediaPlayerManager : public content::RenderViewObserver {
 
 }  // namespace tizen
 
-#endif  // XWALK_TIZEN_RENDERER_RENDERER_MEDIAPLAYER_MANAGER_H_
+#endif  // XWALK_TIZEN_RENDERER_MEDIA_RENDERER_MEDIAPLAYER_MANAGER_H_
index b7c403e..b8e5494 100755 (executable)
@@ -28,9 +28,18 @@ CLASSES_TO_BE_PROCESS = [
 ]
 
 
-def PerformSerialize(output_path, generator):
+WRAPPER_PACKAGE = 'org.xwalk.core'
+BRIDGE_PACKAGE = 'org.xwalk.core.internal'
+
+
+def FormatPackagePath(folder, package):
+  return os.path.join(folder, os.path.sep.join(package.split('.')))
+
+
+def PerformSerialize(output_path, generator, package):
   # Serialize the code.
-  file_name = os.path.join(output_path, generator.GetGeneratedClassFileName())
+  file_name = os.path.join(FormatPackagePath(output_path, package),
+                           generator.GetGeneratedClassFileName())
   if not os.path.isdir(os.path.dirname(file_name)):
     os.makedirs(os.path.dirname(file_name))
   file_handle = open(file_name, 'w')
@@ -44,17 +53,17 @@ def GenerateBindingForJavaClass(
   if java_data.class_type == 'interface':
     interface_generator = InterfaceGenerator(java_data, class_loader)
     interface_generator.RunTask()
-    PerformSerialize(wrap_output, interface_generator)
+    PerformSerialize(wrap_output, interface_generator, WRAPPER_PACKAGE)
   else:
     # Generate Bridge code.
     bridge_generator = BridgeGenerator(java_data, class_loader)
     bridge_generator.RunTask()
     # Serialize.
-    PerformSerialize(bridge_output, bridge_generator)
+    PerformSerialize(bridge_output, bridge_generator, BRIDGE_PACKAGE)
     # Generate Wrapper code.
     wrapper_generator = WrapperGenerator(java_data, class_loader)
     wrapper_generator.RunTask()
-    PerformSerialize(wrap_output, wrapper_generator)
+    PerformSerialize(wrap_output, wrapper_generator, WRAPPER_PACKAGE)
 
 
 def GenerateBindingForJavaDirectory(input_dir, bridge_output, wrap_output):
@@ -73,7 +82,8 @@ def CopyReflectionHelperJava(helper_class, wrap_output):
   if helper_class is None:
     return
   f = open(helper_class, 'r')
-  output = os.path.join(wrap_output, os.path.basename(helper_class))
+  output = os.path.join(FormatPackagePath(wrap_output, WRAPPER_PACKAGE),
+                        os.path.basename(helper_class))
   if not os.path.isdir(os.path.dirname(output)):
     os.makedirs(os.path.dirname(output))
   fo = open(output, 'w')
@@ -81,7 +91,10 @@ def CopyReflectionHelperJava(helper_class, wrap_output):
     if line.startswith('package '):
       fo.write('package org.xwalk.core;\n')
     else:
-      fo.write(line + '\n')
+      if 'Wrapper Only' in line:
+        pass
+      else:
+        fo.write(line + '\n')
   fo.close()
   f.close()
 
index 7545549..467e20d 100644 (file)
                     '../components/nacl.gyp:nacl_helper',
                     '../components/nacl.gyp:nacl_linux',
                     '../native_client/src/trusted/service_runtime/linux/nacl_bootstrap.gyp:nacl_helper_bootstrap',
+                    '../ppapi/native_client/src/trusted/plugin/plugin.gyp:nacl_trusted_plugin',
                   ],
                 }],
             ],
             'xwalk_core_internal_test_apk',
             'xwalk_core_shell_apk',
             'xwalk_core_test_apk',
-            'xwalk_runtime_shell_apk',
             'xwalk_runtime_client_embedded_shell_apk',
             'xwalk_runtime_client_embedded_test_apk',
             'xwalk_runtime_client_shell_apk',
index 563b022..0b1124d 100644 (file)
       ],
     },
     {
-      'target_name': 'xwalk_core_internal_java',
-      'type': 'none',
-      'dependencies': [
-        '../components/components.gyp:navigation_interception_java',
-        '../components/components.gyp:web_contents_delegate_android_java',
-        '../content/content.gyp:content_java',
-        '../ui/android/ui_android.gyp:ui_java',
-        'xwalk_core_extensions_java',
-        'xwalk_core_strings',
-      ],
-      'variables': {
-        'java_in_dir': 'runtime/android/core_internal',
-        'has_java_resources': 1,
-        'R_package': 'org.xwalk.core.internal',
-        'R_package_relpath': 'org/xwalk/core/internal',
-      },
-      'includes': ['../build/java.gypi'],
-    },
-    {
       'target_name': 'xwalk_core_strings',
       'type': 'none',
       'variables': {
       'type': 'none',
       'variables': {
         'timestamp': '<(reflection_java_dir)/gen.timestamp',
+        'internal_src': 'runtime/android/core_internal/src/org/xwalk/core/internal',
+        'internal_java_sources': [
+          '>!@(find <(internal_src) -name "*.java")'
+        ],
       },
       'all_dependent_settings': {
         'variables': {
             'tools/reflection_generator/java_method.py',
             'tools/reflection_generator/reflection_generator.py',
             'tools/reflection_generator/wrapper_generator.py',
-            '<(PRODUCT_DIR)/gen/xwalk_core_internal_java/xwalk_core_internal_java.jar',
+            '>@(internal_java_sources)',
           ],
           'outputs': [
             '<(timestamp)',
           ],
           'action': [
             'python', 'tools/reflection_generator/reflection_generator.py',
-            '--input_dir', 'runtime/android/core_internal/src/org/xwalk/core/internal',
+            '--input_dir', '<(internal_src)',
             '--bridge_output', '<(reflection_java_dir)/bridge',
             '--wrap_output', '<(reflection_java_dir)/wrapper',
             '--helper_class', 'runtime/android/core_internal/src/org/xwalk/core/internal/ReflectionHelper.java',
       ],
     },
     {
-      #TODO(wang16): split it into internal and core.
-      'target_name': 'xwalk_core_java',
+      'target_name': 'xwalk_core_internal_java',
       'type': 'none',
       'dependencies': [
-        'xwalk_core_internal_java',
+        '../components/components.gyp:navigation_interception_java',
+        '../components/components.gyp:web_contents_delegate_android_java',
+        '../content/content.gyp:content_java',
+        '../ui/android/ui_android.gyp:ui_java',
+        'xwalk_core_extensions_java',
+        'xwalk_core_strings',
         'xwalk_core_reflection_layer_java_gen',
       ],
       'variables': {
-        'java_in_dir': 'runtime/android/core',
-        'additional_input_paths': [ '>(reflection_layer_gen_timestamp)' ],
+        'java_in_dir': 'runtime/android/core_internal',
+        'has_java_resources': 1,
+        'R_package': 'org.xwalk.core.internal',
+        'R_package_relpath': 'org/xwalk/core/internal',
         'generated_src_dirs': [
           '<(reflection_java_dir)/bridge',
-          '<(reflection_java_dir)/wrapper',
         ],
       },
-      'includes': ['../build/java.gypi']
+      'includes': ['../build/java.gypi'],
     },
     {
-      'target_name': 'xwalk_runtime_java',
+      'target_name': 'xwalk_core_java',
       'type': 'none',
       'dependencies': [
-        'xwalk_core_java',
+        'xwalk_core_reflection_layer_java_gen',
       ],
       'variables': {
-        'java_in_dir': 'runtime/android/runtime',
-        'has_java_resources': 0,
+        'java_in_dir': 'runtime/android/core',
+        'additional_input_paths': [ '>(reflection_layer_gen_timestamp)' ],
+        'generated_src_dirs': [
+          '<(reflection_java_dir)/wrapper',
+        ],
       },
-      'includes': ['../build/java.gypi'],
+      'includes': ['../build/java.gypi']
     },
     {
       'target_name': 'xwalk_core_jar_jni',
       'type': 'none',
       'dependencies': [
         'libxwalkcore',
-        'xwalk_core_extensions_java',
-        'xwalk_runtime_java',
+        'xwalk_core_internal_java',
         'xwalk_runtime_lib_apk_extension',
         'xwalk_runtime_lib_apk_pak',
       ],
index 26bdee7..1bb200e 100644 (file)
       ],
     },
     {
-      'target_name': 'xwalk_app_runtime_client_java',
-      'type': 'none',
-      'dependencies': [
-        'generate_xwalk_runtime_client_version',
-      ],
-      'variables': {
-        'java_in_dir': 'app/android/runtime_client',
-        'generated_src_dirs': [ '<(SHARED_INTERMEDIATE_DIR)/version_java' ],
-      },
-      'includes': ['../build/java.gypi'],
-    },
-    {
-      'target_name': 'xwalk_app_runtime_activity_java',
-      'type': 'none',
-      'dependencies': [
-        'xwalk_app_runtime_client_java',
-      ],
-      'variables': {
-        'java_in_dir': 'app/android/runtime_activity',
-      },
-      'includes': ['../build/java.gypi'],
-    },
-    {
       'target_name': 'xwalk_app_hello_world_apk',
       'type': 'none',
       'dependencies': [
-        'xwalk_app_runtime_activity_java',
+        'xwalk_app_runtime_java',
       ],
       'variables': {
         'apk_name': 'XWalkAppHelloWorld',
@@ -84,7 +61,7 @@
       'target_name': 'xwalk_app_template_apk',
       'type': 'none',
       'dependencies': [
-        'xwalk_app_runtime_activity_java',
+        'xwalk_app_runtime_java',
       ],
       'variables': {
         'apk_name': 'XWalkAppTemplate',
       'type': 'none',
       'dependencies': [
         'generate_xwalk_runtime_client_version',
+        'xwalk_core_java',
       ],
       'variables': {
         'java_in_dir': 'app/android/runtime_activity',
       'type': 'none',
       'dependencies': [
         'xwalk_app_runtime_java',
-        'xwalk_runtime_java',
+        'xwalk_app_template_apk',
         'xwalk_core_library',
       ],
       'actions': [
index ee43528..254db6f 100644 (file)
@@ -18,8 +18,7 @@
       'type': 'none',
       'dependencies': [
         'xwalk_test_util_java',
-        'xwalk_app_runtime_client_java',
-        'xwalk_app_runtime_activity_java',
+        'xwalk_app_runtime_java',
       ],
       'variables': {
         'java_in_dir': 'test/android/util/runtime_client',
@@ -33,6 +32,7 @@
         '../third_party/android_tools/android_tools.gyp:android_support_v13_javalib',
         'libxwalkcore',
         'xwalk_core_extensions_java',
+        'xwalk_core_internal_java',
         'xwalk_core_java',
         'xwalk_core_shell_apk_pak',
       ],
         'native_lib_target': 'libxwalkcore',
         'additional_input_paths': [
           '<(PRODUCT_DIR)/xwalk_xwview/assets/www/index.html',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/www/request_focus_left_frame.html',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/www/request_focus_main.html',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/www/request_focus_right_frame.html',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/www/request_focus_right_frame1.html',
           '<(PRODUCT_DIR)/xwalk_xwview/assets/xwalk.pak',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/jsapi/contacts_api.js',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/jsapi/device_capabilities_api.js',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/jsapi/launch_screen_api.js',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/jsapi/messaging_api.js',
+          '<(PRODUCT_DIR)/xwalk_xwview/assets/jsapi/presentation_api.js',
         ],
         'conditions': [
           ['icu_use_data_file_flag==1', {
           'destination': '<(PRODUCT_DIR)/xwalk_xwview/assets/www',
           'files': [
             'test/android/data/index.html',
+            'test/android/data/request_focus_left_frame.html',
+            'test/android/data/request_focus_main.html',
+            'test/android/data/request_focus_right_frame.html',
+            'test/android/data/request_focus_right_frame1.html',
           ],
-        }
+        },
+        {
+          'destination': '<(PRODUCT_DIR)/xwalk_xwview/assets/jsapi',
+          'files': [
+            'experimental/launch_screen/launch_screen_api.js',
+            'experimental/presentation/presentation_api.js',
+            'runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/contacts/contacts_api.js',
+            'runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/device_capabilities/device_capabilities_api.js',
+            'runtime/android/core_internal/src/org/xwalk/core/internal/extension/api/messaging/messaging_api.js',
+          ],
+        },
       ],
       'includes': [ '../build/java_apk.gypi' ],
     },
         'is_test_apk': 1,
         'additional_input_paths': [
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/add_js_interface.html',
-          '<(PRODUCT_DIR)/xwalk_internal_xwview_test/assets/echo.html',
-          '<(PRODUCT_DIR)/xwalk_internal_xwview_test/assets/echoSync.html',
-          '<(PRODUCT_DIR)/xwalk_internal_xwview_test/assets/framesEcho.html',
+          '<(PRODUCT_DIR)/xwalk_xwview_test/assets/echo.html',
+          '<(PRODUCT_DIR)/xwalk_xwview_test/assets/echoSync.html',
+          '<(PRODUCT_DIR)/xwalk_xwview_test/assets/framesEcho.html',
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/fullscreen_enter_exit.html',
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/index.html',
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/scale_changed.html',
       'includes': [ '../build/apk_test.gypi' ],
     },
     {
-      'target_name': 'xwalk_runtime_shell_apk',
-      'type': 'none',
-      'dependencies': [
-        'libxwalkcore',
-        # Runtime code is also built by this target.
-        'xwalk_runtime_java',
-        'xwalk_runtime_shell_apk_pak',
-      ],
-      'variables': {
-        'apk_name': 'XWalkRuntimeShell',
-        'java_in_dir': 'runtime/android/runtime_shell',
-        'resource_dir': 'runtime/android/runtime_shell/res',
-        'native_lib_target': 'libxwalkcore',
-        'additional_input_paths': [
-          '<(PRODUCT_DIR)/xwalk_runtime/assets/xwalk.pak',
-        ],
-        'conditions': [
-          ['icu_use_data_file_flag==1', {
-            'additional_input_paths': [
-              '<(PRODUCT_DIR)/xwalk_runtime/assets/icudtl.dat',
-            ],
-          }],
-        ],
-        'asset_location': '<(PRODUCT_DIR)/xwalk_runtime/assets',
-      },
-      'includes': [ '../build/java_apk.gypi' ],
-    },
-    {
-      'target_name': 'xwalk_runtime_shell_apk_pak',
-      'type': 'none',
-      'dependencies': [
-        'xwalk_pak',
-      ],
-      'copies': [
-        {
-          'destination': '<(PRODUCT_DIR)/xwalk_runtime/assets',
-          'files': [
-            '<(PRODUCT_DIR)/xwalk.pak',
-          ],
-          'conditions': [
-            ['icu_use_data_file_flag==1', {
-              'files': [
-                '<(PRODUCT_DIR)/icudtl.dat',
-              ],
-            }],
-          ],
-        },
-      ],
-    },
-    {
-      'target_name': 'xwalk_runtime_shell_apk_java',
-      'type': 'none',
-      'dependencies': [
-        'xwalk_runtime_shell_apk',
-      ],
-      'includes': [ '../build/apk_fake_jar.gypi' ],
-    },
-    {
       'target_name': 'xwalk_runtime_client_shell_apk',
       'type': 'none',
       'dependencies': [
-        'xwalk_app_runtime_client_java',
-        'xwalk_app_runtime_activity_java',
+        'xwalk_app_runtime_java',
         'xwalk_runtime_client_test_utils_java',
       ],
       'variables': {
       'type': 'none',
       'dependencies': [
         'libxwalkcore',
-        'xwalk_app_runtime_client_java',
-        'xwalk_app_runtime_activity_java',
-        'xwalk_runtime_java',
+        'xwalk_app_runtime_java',
+        'xwalk_core_internal_java',
         'xwalk_runtime_client_embedded_shell_apk_pak',
         'xwalk_runtime_client_test_utils_java',
       ],
       ],
     },
     {
-      'target_name': 'xwalk_runtime_test_apk',
-      'type': 'none',
-      'dependencies': [
-        '../base/base.gyp:base_java_test_support',
-        '../content/content_shell_and_tests.gyp:content_java_test_support',
-        '../net/net.gyp:net_java_test_support',
-        '../tools/android/forwarder2/forwarder.gyp:forwarder2',
-        '../tools/android/md5sum/md5sum.gyp:md5sum',
-        'xwalk_runtime_shell_apk_java',
-      ],
-      'variables': {
-        'apk_name': 'XWalkRuntimeTest',
-        'java_in_dir': 'test/android/runtime/javatests',
-        'is_test_apk': 1,
-      },
-      'includes': [ '../build/java_apk.gypi' ],
-    },
-    {
       'target_name': 'xwalk_runtime_client_test_apk',
       'type': 'none',
       'dependencies': [
       'dependencies': [
         'libxwalkcore',
         'xwalk_core_extensions_java',
+        'xwalk_core_internal_java',
         'xwalk_core_java',
         'xwalk_core_shell_apk_pak',
       ],
index 83d86e8..b83e615 100644 (file)
       'variables': {
         'api_files': [
           '<(DEPTH)/xwalk/runtime/android/core/src/org/xwalk/core/JavascriptInterface.java',
-          '>(reflection_gen_dir)/wrapper/XWalkExtension.java',
-          '>(reflection_gen_dir)/wrapper/XWalkJavascriptResult.java',
-          '>(reflection_gen_dir)/wrapper/XWalkNavigationHistory.java',
-          '>(reflection_gen_dir)/wrapper/XWalkNavigationItem.java',
-          '>(reflection_gen_dir)/wrapper/XWalkPreferences.java',
-          '>(reflection_gen_dir)/wrapper/XWalkResourceClient.java',
-          '>(reflection_gen_dir)/wrapper/XWalkUIClient.java',
-          '>(reflection_gen_dir)/wrapper/XWalkView.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkExtension.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkJavascriptResult.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkNavigationHistory.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkNavigationItem.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkPreferences.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkResourceClient.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkUIClient.java',
+          '>(reflection_gen_dir)/wrapper/org/xwalk/core/XWalkView.java',
         ],
         'docs': '<(PRODUCT_DIR)/xwalk_core_library_docs',
       },
@@ -77,6 +77,7 @@
       'type': 'none',
       'dependencies': [
         'libxwalkcore',
+        'xwalk_core_internal_java',
         'xwalk_core_java',
       ],
       'variables': {
       'target_name': 'xwalk_core_library_java',
       'type': 'none',
       'dependencies': [
+        'xwalk_core_internal_java',
         'xwalk_core_java',
         'xwalk_core_library_empty_embedder_apk',
       ],
           ],
           'action': [
             'python', '<(DEPTH)/xwalk/build/android/generate_xwalk_core_library_aar.py',
-            '-s',  '<(DEPTH)',
             '-t', '<(PRODUCT_DIR)',
           ],
         },
index c6c955a..da0e20a 100644 (file)
@@ -34,7 +34,7 @@
       ],
       'sources': [
         'application/common/application_storage_impl_unittest.cc',
-        'application/common/installer/package_unittest.cc',
+        'application/common/package/package_unittest.cc',
         'application/common/application_unittest.cc',
         'application/common/application_file_util_unittest.cc',
         'application/common/id_util_unittest.cc',