Upstream version 11.39.264.0 89/32089/1
authorEurogiciel-BOT <eurogiciel.tizen@gmail.com>
Mon, 15 Dec 2014 13:21:46 +0000 (13:21 +0000)
committerEurogiciel-BOT <eurogiciel.tizen@gmail.com>
Mon, 15 Dec 2014 13:21:46 +0000 (13:21 +0000)
Upstream commit-id 0019cd573cdef4fa4fd00ecd9cda8d1846b07026

Change-Id: Iaf0768bf962735e1e8405ce98921cc663d6cb269
Signed-off-by: Eurogiciel-BOT <eurogiciel.tizen@gmail.com>
113 files changed:
packaging/crosswalk.png
packaging/crosswalk.spec
src/.DEPS.git
src/DEPS
src/build/android/pylib/gtest/setup.py
src/build/util/LASTCHANGE
src/build/util/LASTCHANGE.blink
src/chrome/VERSION
src/chrome/app/generated_resources.grd
src/chrome/browser/about_flags.cc
src/chrome/browser/chromeos/login/oobe_browsertest.cc
src/chrome/browser/defaults.cc
src/chrome/browser/defaults.h
src/chrome/browser/renderer_preferences_util.cc
src/chrome/browser/sync/test/integration/enable_disable_test.cc
src/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
src/components/sync_driver/sync_prefs.cc
src/components/sync_driver/sync_prefs_unittest.cc
src/content/browser/renderer_host/render_process_host_impl.cc
src/content/content_tests.gypi
src/content/content_unittests.isolate
src/content/renderer/media/media_stream_audio_processor.cc
src/content/renderer/media/media_stream_audio_processor_options.cc
src/content/renderer/render_view_impl.cc
src/third_party/WebKit/Source/web/LinkHighlight.cpp
src/third_party/WebKit/Source/web/LinkHighlight.h
src/third_party/libjingle/BUILD.gn
src/third_party/libjingle/libjingle.gyp
src/third_party/libjingle/overrides/init_webrtc.cc
src/third_party/libjingle/overrides/init_webrtc.h
src/third_party/libjingle/overrides/initialize_module.cc
src/tools/metrics/histograms/histograms.xml
src/ui/base/ui_base_switches.cc
src/ui/base/ui_base_switches.h
src/ui/base/ui_base_switches_util.cc
src/ui/base/ui_base_switches_util.h
src/xwalk/DEPS.xwalk
src/xwalk/VERSION
src/xwalk/app/android/app_hello_world/res/drawable-hdpi/crosswalk.png
src/xwalk/app/android/app_hello_world/res/drawable-ldpi/crosswalk.png
src/xwalk/app/android/app_hello_world/res/drawable-mdpi/crosswalk.png
src/xwalk/app/android/app_hello_world/res/drawable-xhdpi/crosswalk.png
src/xwalk/app/android/app_template/res/drawable-hdpi/crosswalk.png
src/xwalk/app/android/app_template/res/drawable-ldpi/crosswalk.png
src/xwalk/app/android/app_template/res/drawable-mdpi/crosswalk.png
src/xwalk/app/android/app_template/res/drawable-xhdpi/crosswalk.png
src/xwalk/app/tools/android/test_data/manifest/icons/icon_144.png
src/xwalk/app/tools/android/test_data/manifest/icons/icon_48.png
src/xwalk/app/tools/android/test_data/manifest/icons/icon_72.png
src/xwalk/app/tools/android/test_data/manifest/icons/icon_96.png
src/xwalk/application/browser/application_service.cc
src/xwalk/application/browser/application_system_linux.cc
src/xwalk/application/common/manifest_handlers/csp_handler_unittest.cc
src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler.cc
src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler_unittest.cc [new file with mode: 0644]
src/xwalk/application/common/manifest_handlers/unittest_util.cc
src/xwalk/application/common/manifest_handlers/unittest_util.h
src/xwalk/application/common/manifest_handlers/widget_handler.cc
src/xwalk/application/common/manifest_handlers/widget_handler_unittest.cc
src/xwalk/application/common/package/xpk_package.cc
src/xwalk/application/extension/application_widget_api.js
src/xwalk/application/extension/application_widget_extension.cc
src/xwalk/application/extension/application_widget_extension.h
src/xwalk/application/extension/application_widget_storage.cc
src/xwalk/application/extension/application_widget_storage.h
src/xwalk/application/tools/linux/dbus_connection.cc [deleted file]
src/xwalk/application/tools/linux/dbus_connection.h [deleted file]
src/xwalk/application/tools/linux/dbus_object_manager.cc [new file with mode: 0644]
src/xwalk/application/tools/linux/dbus_object_manager.h [new file with mode: 0644]
src/xwalk/application/tools/linux/xwalk_application_tools.gyp
src/xwalk/application/tools/linux/xwalk_launcher.cc [new file with mode: 0644]
src/xwalk/application/tools/linux/xwalk_launcher.h [new file with mode: 0644]
src/xwalk/application/tools/linux/xwalk_launcher_main.cc
src/xwalk/application/tools/linux/xwalk_launcher_tizen.cc
src/xwalk/application/tools/linux/xwalk_launcher_tizen.h
src/xwalk/application/tools/tizen/xwalk_backend.cc
src/xwalk/application/tools/tizen/xwalk_tizen_tools.gyp
src/xwalk/build/common.gypi
src/xwalk/dbus/object_manager_adaptor.cc
src/xwalk/extensions/browser/xwalk_extension_function_handler.h
src/xwalk/extensions/browser/xwalk_extension_process_host.cc
src/xwalk/extensions/common/xwalk_external_instance.cc
src/xwalk/packaging/crosswalk.png
src/xwalk/packaging/crosswalk.spec
src/xwalk/runtime/android/runtime_lib/res/drawable-hdpi/crosswalk.png
src/xwalk/runtime/android/runtime_lib/res/drawable-ldpi/crosswalk.png
src/xwalk/runtime/android/runtime_lib/res/drawable-mdpi/crosswalk.png
src/xwalk/runtime/android/runtime_lib/res/drawable-xhdpi/crosswalk.png
src/xwalk/runtime/android/sample/res/drawable-hdpi/crosswalk.png
src/xwalk/runtime/android/sample/res/drawable-ldpi/crosswalk.png
src/xwalk/runtime/android/sample/res/drawable-mdpi/crosswalk.png
src/xwalk/runtime/android/sample/res/drawable-xhdpi/crosswalk.png
src/xwalk/runtime/browser/android/xwalk_settings.cc
src/xwalk/runtime/browser/runtime_file_select_helper.h
src/xwalk/runtime/browser/runtime_javascript_dialog_manager.h
src/xwalk/runtime/browser/runtime_url_request_context_getter.cc
src/xwalk/runtime/browser/xwalk_browser_main_parts.cc
src/xwalk/runtime/browser/xwalk_runner.cc
src/xwalk/runtime/browser/xwalk_runner.h
src/xwalk/runtime/browser/xwalk_runner_tizen.cc
src/xwalk/runtime/common/xwalk_paths.cc
src/xwalk/runtime/common/xwalk_switches.cc
src/xwalk/runtime/common/xwalk_switches.h
src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.cc
src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h
src/xwalk/runtime/resources/icons/crosswalk.ico
src/xwalk/runtime/resources/icons/crosswalk_144x144.png
src/xwalk/runtime/resources/icons/crosswalk_48x48.png
src/xwalk/runtime/resources/icons/crosswalk_72x72.png
src/xwalk/runtime/resources/icons/crosswalk_96x96.png
src/xwalk/sysapps/device_capabilities/device_capabilities_extension.h
src/xwalk/sysapps/raw_socket/raw_socket_extension.h
src/xwalk/xwalk_tests.gypi

index f693816..9aeeff7 100644 (file)
Binary files a/packaging/crosswalk.png and b/packaging/crosswalk.png differ
index 8e9c587..4850150 100644 (file)
@@ -24,7 +24,7 @@
 %define _binary_payload w3.gzdio
 
 Name:           crosswalk
-Version:        11.39.260.0
+Version:        11.39.264.0
 Release:        0
 Summary:        Chromium-based app runtime
 License:        (BSD-3-Clause and LGPL-2.1+)
@@ -237,7 +237,6 @@ ${GYP_EXTRA_FLAGS} \
 -Duse_system_libexif=1 \
 -Duse_system_libxml=1 \
 -Duse_system_yasm=1 \
--Dshared_process_mode=1 \
 -Denable_hidpi=1
 
 ninja %{?_smp_mflags} -C src/out/Release xwalk xwalk_launcher xwalk_application_tools
index 5725bbd..4d0fba8 100644 (file)
@@ -7,7 +7,7 @@ vars = {
     'eyes-free':
          'http://eyes-free.googlecode.com/svn',
     'webkit_rev':
-         '@46701e45dce4e844a0a1d14d69a91a509587aba1',
+         '@e17a1818a3674776f83cb20461e90763d28bf1c9',
     'blink':
          'http://src.chromium.org/blink',
     'skia':
index da8bfd6..ce6db00 100644 (file)
--- a/src/DEPS
+++ b/src/DEPS
@@ -156,12 +156,10 @@ deps_os = {
     'src/third_party/bidichecker': None,\r
     'src/third_party/libc++/trunk': None,\r
     'src/tools/page_cycler/acid3': None,\r
-    'src/third_party/nss':\r
-      (Var("git.chromium.org")) + '/chromium/deps/nss.git@87b96db4268293187d7cf741907a6d5d1d8080e0',\r
     'src/chrome/test/data/perf/canvas_bench': None,\r
     'src/third_party/libexif/sources': None,\r
     'src/build/util/support': None,\r
-    'src/third_party/libc++abi/trunk': None,\r
+    'src/third_party/libsrtp': None,\r
     'src/third_party/WebKit/LayoutTests/w3c/csswg-test': None,\r
     'src/third_party/pymox/src': None,\r
     'src/media/cdm/ppapi/api': None,\r
@@ -171,7 +169,9 @@ deps_os = {
     'src/third_party/openmax_dl': None,\r
     'src/third_party/google_toolbox_for_mac/src':\r
       (Var("git.chromium.org")) + '/external/google-toolbox-for-mac.git@a09526298f9dd1ec49d3b3ac5608d2a257b94cef',\r
+    'src/third_party/webgl': None,\r
     'src/third_party/WebKit/LayoutTests/w3c/web-platform-tests': None,\r
+    'src/third_party/scons-2.0.1': None,\r
     'src/chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin': None,\r
     'src/third_party/opus/src': None,\r
     'src/third_party/webpagereplay': None,\r
@@ -179,79 +179,79 @@ deps_os = {
     'src/native_client': None,\r
     'src/third_party/usrsctp/usrsctplib': None,\r
     'src/third_party/brotli/src': None,\r
-    'src/third_party/webgl': None,\r
+    'src/third_party/libc++abi/trunk': None,\r
     'src/third_party/yasm/source/patched-yasm': None,\r
     'src/testing/iossim/third_party/class-dump':\r
       (Var("git.chromium.org")) + '/chromium/deps/class-dump.git@89bd40883c767584240b4dade8b74e6f57b9bdab',\r
-    'src/third_party/libjpeg_turbo': None,\r
     'src/third_party/cld_2/src': None,\r
-    'src/third_party/libsrtp': None,\r
+    'src/third_party/libjpeg_turbo': None,\r
     'src/third_party/ots': None,\r
     'src/third_party/ffmpeg': None,\r
     'src/third_party/hunspell': None,\r
     'src/third_party/swig/Lib': None,\r
-    'src/third_party/scons-2.0.1': None\r
-    },\r
-    'unix': {\r
-      'src/third_party/fontconfig/src':\r
-        (Var("git.chromium.org")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1',\r
-      'build/third_party/cbuildbot_chromite':\r
-        (Var("git.chromium.org")) + '/chromiumos/chromite.git@1e95b44e033daa6b48e2e9702c5b08a9410f11d8',\r
-      'src/third_party/cros_system_api':\r
-        (Var("git.chromium.org")) + '/chromiumos/platform/system_api.git@f0fc55329fa536195861778a2ddc6115b4a977bc',\r
-      'src/third_party/pyelftools':\r
-        (Var("git.chromium.org")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e',\r
-      'src/third_party/chromite':\r
-        (Var("git.chromium.org")) + '/chromiumos/chromite.git@8e92d5c24da7967e27ab2498abc2d2f7ac6ec65a',\r
-      'build/third_party/xvfb':\r
-        '/trunk/tools/third_party/xvfb@125214',\r
-      'src/third_party/xdg-utils':\r
-        (Var("git.chromium.org")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d',\r
-      'src/third_party/undoview':\r
-        (Var("git.chromium.org")) + '/chromium/deps/undoview.git@3ba503e248f3cdbd81b78325a24ece0984637559',\r
-      'src/chrome/tools/test/reference_build/chrome_linux':\r
-        (Var("git.chromium.org")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36',\r
-      'src/third_party/swig/linux':\r
-        (Var("git.chromium.org")) + '/chromium/deps/swig/linux.git@866b8e0e0e0cfe99ebe608260030916ca0c3f92d',\r
-      'src/third_party/liblouis/src':\r
-        (Var("git.chromium.org")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2',\r
-      'src/third_party/freetype2/src':\r
-        (Var("git.chromium.org")) + '/chromium/src/third_party/freetype2.git@d699c2994ecc178c4ed05ac2086061b2034c2178',\r
-      'src/third_party/lss':\r
-        (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb'\r
-    },\r
-    'android': {\r
-      'src/third_party/android_webview_glue/src':\r
-        (Var("git.chromium.org")) + '/external/android_webview_glue.git@a1b0248c80f239e2f6476b9f395b27d0ba1eb3cd',\r
-      'src/third_party/jarjar':\r
-        (Var("git.chromium.org")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920',\r
-      'src/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille':\r
-        (Var("git.chromium.org")) + '/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git@77bf6edb0138e3a38a2772248696f130dab45e34',\r
-      'src/third_party/freetype':\r
-        (Var("git.chromium.org")) + '/chromium/src/third_party/freetype.git@a2b9955b49034a51dfbc8bf9f4e9d312149cecac',\r
-      'src/third_party/apache-mime4j':\r
-        (Var("git.chromium.org")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',\r
-      'src/third_party/elfutils/src':\r
-        (Var("git.chromium.org")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7',\r
-      'src/pdf': None,\r
-      'src/third_party/junit/src':\r
-        (Var("git.chromium.org")) + '/external/junit.git@c62e2df8dbecccb1b434d4ba8843b59e90b03266',\r
-      'src/third_party/android_tools':\r
-        (Var("git.chromium.org")) + '/android_tools.git@d2b86205ff973a3844020feacb35ca6b1d82efbe',\r
-      'src/third_party/httpcomponents-client':\r
-        (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c',\r
-      'src/third_party/findbugs':\r
-        (Var("git.chromium.org")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12',\r
-      'src/third_party/lss':\r
-        (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb',\r
-      'src/third_party/android_protobuf/src':\r
-        (Var("git.chromium.org")) + '/external/android_protobuf.git@94f522f907e3f34f70d9e7816b947e62fddbb267',\r
-      'src/third_party/jsr-305/src':\r
-        (Var("git.chromium.org")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919',\r
-      'src/third_party/httpcomponents-core':\r
-        (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62'\r
-    }\r
+    'src/third_party/nss':\r
+      (Var("git.chromium.org")) + '/chromium/deps/nss.git@87b96db4268293187d7cf741907a6d5d1d8080e0'\r
+  },\r
+  'unix': {\r
+    'src/third_party/fontconfig/src':\r
+      (Var("git.chromium.org")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1',\r
+    'src/third_party/freetype2/src':\r
+      (Var("git.chromium.org")) + '/chromium/src/third_party/freetype2.git@d699c2994ecc178c4ed05ac2086061b2034c2178',\r
+    'src/third_party/pyelftools':\r
+      (Var("git.chromium.org")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e',\r
+    'src/third_party/chromite':\r
+      (Var("git.chromium.org")) + '/chromiumos/chromite.git@8e92d5c24da7967e27ab2498abc2d2f7ac6ec65a',\r
+    'build/third_party/xvfb':\r
+      '/trunk/tools/third_party/xvfb@125214',\r
+    'src/third_party/xdg-utils':\r
+      (Var("git.chromium.org")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d',\r
+    'src/third_party/undoview':\r
+      (Var("git.chromium.org")) + '/chromium/deps/undoview.git@3ba503e248f3cdbd81b78325a24ece0984637559',\r
+    'src/third_party/cros_system_api':\r
+      (Var("git.chromium.org")) + '/chromiumos/platform/system_api.git@f0fc55329fa536195861778a2ddc6115b4a977bc',\r
+    'src/chrome/tools/test/reference_build/chrome_linux':\r
+      (Var("git.chromium.org")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36',\r
+    'src/third_party/swig/linux':\r
+      (Var("git.chromium.org")) + '/chromium/deps/swig/linux.git@866b8e0e0e0cfe99ebe608260030916ca0c3f92d',\r
+    'src/third_party/liblouis/src':\r
+      (Var("git.chromium.org")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2',\r
+    'build/third_party/cbuildbot_chromite':\r
+      (Var("git.chromium.org")) + '/chromiumos/chromite.git@1e95b44e033daa6b48e2e9702c5b08a9410f11d8',\r
+    'src/third_party/lss':\r
+      (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb'\r
+  },\r
+  'android': {\r
+    'src/third_party/android_webview_glue/src':\r
+      (Var("git.chromium.org")) + '/external/android_webview_glue.git@a1b0248c80f239e2f6476b9f395b27d0ba1eb3cd',\r
+    'src/third_party/jarjar':\r
+      (Var("git.chromium.org")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920',\r
+    'src/third_party/android_tools':\r
+      (Var("git.chromium.org")) + '/android_tools.git@d2b86205ff973a3844020feacb35ca6b1d82efbe',\r
+    'src/pdf': None,\r
+    'src/third_party/apache-mime4j':\r
+      (Var("git.chromium.org")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',\r
+    'src/third_party/elfutils/src':\r
+      (Var("git.chromium.org")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7',\r
+    'src/third_party/freetype':\r
+      (Var("git.chromium.org")) + '/chromium/src/third_party/freetype.git@a2b9955b49034a51dfbc8bf9f4e9d312149cecac',\r
+    'src/third_party/junit/src':\r
+      (Var("git.chromium.org")) + '/external/junit.git@c62e2df8dbecccb1b434d4ba8843b59e90b03266',\r
+    'src/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille':\r
+      (Var("git.chromium.org")) + '/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git@77bf6edb0138e3a38a2772248696f130dab45e34',\r
+    'src/third_party/httpcomponents-client':\r
+      (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c',\r
+    'src/third_party/findbugs':\r
+      (Var("git.chromium.org")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12',\r
+    'src/third_party/lss':\r
+      (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb',\r
+    'src/third_party/android_protobuf/src':\r
+      (Var("git.chromium.org")) + '/external/android_protobuf.git@94f522f907e3f34f70d9e7816b947e62fddbb267',\r
+    'src/third_party/jsr-305/src':\r
+      (Var("git.chromium.org")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919',\r
+    'src/third_party/httpcomponents-core':\r
+      (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62'\r
   }\r
+}\r
 \r
 deps = {\r
   'depot_tools':\r
@@ -262,8 +262,6 @@ deps = {
     (Var("git.chromium.org")) + '/external/bidichecker/lib.git@97f2aa645b74c28c57eca56992235c79850fa9e0',\r
   'src/third_party/libc++/trunk':\r
     (Var("git.chromium.org")) + '/chromium/llvm-project/libcxx.git@48198f9110397fff47fe7c37cbfa296be7d44d3d',\r
-  'src/third_party/colorama/src':\r
-    (Var("git.chromium.org")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',\r
   'src/third_party/libwebm/source':\r
     (Var("git.chromium.org")) + '/webm/libwebm.git@0d4cb404ea4195e5e21d04db2c955615535ce62e',\r
   'src/third_party/usrsctp/usrsctplib':\r
@@ -374,20 +372,22 @@ deps = {
     (Var("git.chromium.org")) + '/chromium/deps/icu52.git@d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174',\r
   'src/third_party/opus/src':\r
     (Var("git.chromium.org")) + '/chromium/deps/opus.git@cae696156f1e60006e39821e79a1811ae1933c69',\r
-  'src/tools/grit':\r
-    (Var("git.chromium.org")) + '/external/grit-i18n.git@740badd5e3e44434a9a47b5d16749daac1e8ea80',\r
+  'src/third_party/colorama/src':\r
+    (Var("git.chromium.org")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',\r
   'src/third_party/snappy/src':\r
     (Var("git.chromium.org")) + '/external/snappy.git@762bb32f0c9d2f31ba4958c7c0933d22e80c20bf',\r
   'src/third_party/webpagereplay':\r
     (Var("git.chromium.org")) + '/external/web-page-replay.git@2f7b704b8b567983c040f555d3e46f9766db8e87',\r
   'src/third_party/WebKit':\r
-    (Var("git.chromium.org")) + '/chromium/blink.git@46701e45dce4e844a0a1d14d69a91a509587aba1',\r
+    (Var("git.chromium.org")) + '/chromium/blink.git@e17a1818a3674776f83cb20461e90763d28bf1c9',\r
   'src/breakpad/src':\r
     (Var("git.chromium.org")) + '/external/google-breakpad/src.git@35189355da4b65ed5e7692f790c240a9ab347731',\r
   'src/third_party/hunspell':\r
     (Var("git.chromium.org")) + '/chromium/deps/hunspell.git@c956c0e97af00ef789afb2f64d02c9a5a50e6eb1',\r
   'src/tools/deps2git':\r
     (Var("git.chromium.org")) + '/chromium/tools/deps2git.git@f04828eb0b5acd3e7ad983c024870f17f17b06d9',\r
+  'src/tools/grit':\r
+    (Var("git.chromium.org")) + '/external/grit-i18n.git@740badd5e3e44434a9a47b5d16749daac1e8ea80',\r
   'src/third_party/libjpeg_turbo':\r
     (Var("git.chromium.org")) + '/chromium/deps/libjpeg_turbo.git@034e9a9747e0983bc19808ea70e469bc8342081f',\r
   'src/testing/gtest':\r
index 2782859..6a9e65b 100644 (file)
@@ -118,7 +118,6 @@ def _GenerateDepsDirUsingIsolate(suite_name, isolate_file_path=None):
       '--config-variable', 'component', 'static_library',
       '--config-variable', 'fastbuild', '0',
       '--config-variable', 'icu_use_data_file_flag', '1',
-      '--config-variable', 'libpeer_target_type', 'static_library',
       # TODO(maruel): This may not be always true.
       '--config-variable', 'target_arch', 'arm',
       '--config-variable', 'use_openssl', '0',
index 207e3ce..e823590 100644 (file)
@@ -1 +1 @@
-LASTCHANGE=ea46c0b6279a60b0173a092f0e9f0403a2a047a9
+LASTCHANGE=0bbff352135bacf2e6a17b5ffebd387f3c2d085f
index 2fb81d9..9ed5759 100644 (file)
@@ -1 +1 @@
-LASTCHANGE=1620ccec09abbd0dae196999fbcd94505136b306
+LASTCHANGE=dc24b658e6b89accb1e21a14bc06dc72bfc00c41
index e93a31c..3f7bfc2 100644 (file)
@@ -1,4 +1,4 @@
 MAJOR=39
 MINOR=0
 BUILD=2171
-PATCH=62
+PATCH=71
index 56f7986..be03be6 100644 (file)
@@ -6525,6 +6525,14 @@ Keep your key file in a safe place. You will need it to create new versions of y
       <message name="IDS_FLAGS_ENABLE_TAB_AUDIO_MUTING_DESCRIPTION" desc="Description of the flag that enables the tab audio muting UI experiment in chrome://extensions.">
         When enabled, the audio indicators in the tab strip double as tab audio mute controls.  This also adds commands in the tab context menu for quickly muting multiple selected tabs.
       </message>
+      <if expr="toolkit_views">
+        <message name="IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_NAME" desc="Title for the flag to enable the Link Disambiguation Popup, a bubble that appears over the web content screen when the user uses a touchscreen to touch a link but accidentally touches more than one link in a single gesture. The bubble appears with a zoomed-in view of the area around their touch, allowing them to more easily select the element they wanted.">
+          Enable Link Disambiguation Popup.
+        </message>
+        <message name="IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_DESCRIPTION" desc="Description for the flag to enable the Link Disambiguation Popup, a feature on touchscreens that when enabled will cause a small zoomed popup to appear over a group of links the user has touched, allowing for selection of links on pages not yet optimized for touch input.">
+          Enable the zoomed bubble that appears on touchscreens when accidentally touching more than one link at a time.
+        </message>
+      </if>
 
       <!-- Crashes -->
       <message name="IDS_CRASHES_TITLE" desc="Title for the chrome://crashes page.">
index 6004fab..0d9d667 100644 (file)
@@ -1569,6 +1569,13 @@ const Experiment kExperiments[] = {
     kOsCrOS | kOsWin | kOsLinux,
     SINGLE_VALUE_TYPE(views::switches::kDisableViewsRectBasedTargeting)
   },
+  {
+    "enable-link-disambiguation-popup",
+    IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_NAME,
+    IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_DESCRIPTION,
+    kOsCrOS | kOsWin,
+    SINGLE_VALUE_TYPE(switches::kEnableLinkDisambiguationPopup)
+  },
 #endif
 #if defined(ENABLE_EXTENSIONS)
   {
index 9241cbd..53b218a 100644 (file)
@@ -8,16 +8,12 @@
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
-#include "chrome/browser/defaults.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chromeos/chromeos_switches.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/renderer_preferences.h"
 #include "content/public/test/test_utils.h"
 #include "google_apis/gaia/fake_gaia.h"
 #include "google_apis/gaia/gaia_switches.h"
@@ -125,30 +121,4 @@ IN_PROC_BROWSER_TEST_F(OobeTest, Accelerator) {
   OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_ENROLLMENT).Wait();
 }
 
-IN_PROC_BROWSER_TEST_F(OobeTest, LinkDisambiguationDefaultRespected) {
-  chromeos::LoginDisplayHostImpl* display_host =
-      static_cast<chromeos::LoginDisplayHostImpl*>(
-          chromeos::LoginDisplayHostImpl::default_host());
-  ASSERT_TRUE(display_host);
-  chromeos::WebUILoginView* login_view = display_host->GetWebUILoginView();
-  ASSERT_TRUE(login_view);
-  content::WebContents* web_contents = login_view->GetWebContents();
-  ASSERT_TRUE(web_contents);
-  content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
-  ASSERT_TRUE(prefs);
-  // Per crbug/431163 the WiFi selection dropdown doesn't support the link
-  // disambiguation popup for gesture events, and this feature is disabled
-  // within ChromeOS. Ensure that the web preferences reflect the default.
-  if (browser_defaults::kShowLinkDisambiguationPopup) {
-    EXPECT_EQ(
-        content::TapMultipleTargetsStrategy::
-            TAP_MULTIPLE_TARGETS_STRATEGY_POPUP,
-        prefs->tap_multiple_targets_strategy);
-  } else {
-    EXPECT_EQ(
-        content::TapMultipleTargetsStrategy::TAP_MULTIPLE_TARGETS_STRATEGY_NONE,
-        prefs->tap_multiple_targets_strategy);
-  }
-}
-
 }  // namespace chromeos
index ff39b1d..6d6b6b6 100644 (file)
@@ -16,14 +16,6 @@ const bool kCanToggleSystemTitleBar = true;
 
 const int kOmniboxFontPixelSize = 16;
 
-#if defined(TOOLKIT_VIEWS)
-#if defined(OS_WIN)
-const bool kShowLinkDisambiguationPopup = true;
-#else
-const bool kShowLinkDisambiguationPopup = false;
-#endif
-#endif
-
 #if defined(OS_CHROMEOS) || defined(OS_MACOSX)
 const bool kBrowserAliveWithNoWindows = true;
 const bool kShowExitMenuItem = false;
index 157d561..41b16d6 100644 (file)
@@ -33,12 +33,6 @@ const int kMiniTabWidth = 64;
 const int kMiniTabWidth = 56;
 #endif
 
-#if defined(TOOLKIT_VIEWS)
-// Whether to show a Link Disambiguation Popup Bubble if the browser detects an
-// ambiguous touch event.
-extern const bool kShowLinkDisambiguationPopup;
-#endif
-
 // Can the browser be alive without any browser windows?
 extern const bool kBrowserAliveWithNoWindows;
 
index 7f67482..519e63b 100644 (file)
@@ -16,7 +16,6 @@
 #endif
 
 #if defined(TOOLKIT_VIEWS)
-#include "chrome/browser/defaults.h"
 #include "ui/views/controls/textfield/textfield.h"
 #endif
 
@@ -50,14 +49,6 @@ void UpdateFromSystemSettings(
 
 #if defined(TOOLKIT_VIEWS)
   prefs->caret_blink_interval = views::Textfield::GetCaretBlinkMs() / 1000.0;
-  if (browser_defaults::kShowLinkDisambiguationPopup) {
-    prefs->tap_multiple_targets_strategy =
-        content::TapMultipleTargetsStrategy::
-            TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
-  } else {
-    prefs->tap_multiple_targets_strategy =
-        content::TapMultipleTargetsStrategy::TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
-  }
 #endif
 
 #if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
index fdb7f57..957720e 100644 (file)
@@ -111,6 +111,10 @@ IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, DisableOneAtATime) {
         it.Get() == syncer::SYNCED_NOTIFICATION_APP_INFO)
       continue;
 
+    // Device info cannot be disabled.
+    if (it.Get() == syncer::DEVICE_INFO)
+      continue;
+
     ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(it.Get()));
 
     // AUTOFILL_PROFILE is lumped together with AUTOFILL.
index 55176d2..d2a1970 100644 (file)
@@ -178,9 +178,6 @@ void ChromeWebContentsViewDelegateViews::ShowDisambiguationPopup(
     const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
     const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
 #if defined(USE_AURA)
-  if (!browser_defaults::kShowLinkDisambiguationPopup)
-    return;
-
   link_disambiguation_popup_.reset(new LinkDisambiguationPopup);
   link_disambiguation_popup_->Show(
       zoomed_bitmap, target_rect, content, gesture_cb, mouse_cb);
index cc7914d..fd5ffb2 100644 (file)
@@ -66,9 +66,11 @@ void SyncPrefs::RegisterProfilePrefs(
   // although they don't have sync representations.
   user_types.PutAll(syncer::ProxyTypes());
 
-  // Treat bookmarks specially.
+  // Treat bookmarks and device info specially.
   RegisterDataTypePreferredPref(registry, syncer::BOOKMARKS, true);
+  RegisterDataTypePreferredPref(registry, syncer::DEVICE_INFO, true);
   user_types.Remove(syncer::BOOKMARKS);
+  user_types.Remove(syncer::DEVICE_INFO);
 
   // These two prefs are set from sync experiment to enable enhanced bookmarks.
   registry->RegisterIntegerPref(
@@ -346,7 +348,7 @@ const char* SyncPrefs::GetPrefNameForDataType(syncer::ModelType data_type) {
     default:
       break;
   }
-  NOTREACHED();
+  NOTREACHED() << "Type is " << data_type;
   return NULL;
 }
 
@@ -451,6 +453,11 @@ bool SyncPrefs::GetDataTypePreferred(syncer::ModelType type) const {
     NOTREACHED();
     return false;
   }
+
+  // Device info is always enabled.
+  if (pref_name == prefs::kSyncDeviceInfo)
+    return true;
+
   if (type == syncer::PROXY_TABS &&
       pref_service_->GetUserPrefValue(pref_name) == NULL &&
       pref_service_->IsUserModifiablePreference(pref_name)) {
@@ -470,6 +477,11 @@ void SyncPrefs::SetDataTypePreferred(syncer::ModelType type,
     NOTREACHED();
     return;
   }
+
+  // Device info is always preferred.
+  if (type == syncer::DEVICE_INFO)
+    return;
+
   pref_service_->SetBoolean(pref_name, is_preferred);
 }
 
index 683d55a..fb8dddb 100644 (file)
@@ -68,10 +68,11 @@ TEST_F(SyncPrefsTest, DefaultTypes) {
   SyncPrefs sync_prefs(&pref_service_);
   sync_prefs.SetKeepEverythingSynced(false);
 
-  // Only bookmarks are enabled by default.
+  // Only bookmarks and device info are enabled by default.
+  syncer::ModelTypeSet expected(syncer::BOOKMARKS, syncer::DEVICE_INFO);
   syncer::ModelTypeSet preferred_types =
       sync_prefs.GetPreferredDataTypes(syncer::UserTypes());
-  EXPECT_TRUE(preferred_types.Equals(syncer::ModelTypeSet(syncer::BOOKMARKS)));
+  EXPECT_TRUE(preferred_types.Equals(expected));
 
   // Simulate an upgrade to delete directives + proxy tabs support. None of the
   // new types or their pref group types should be registering, ensuring they
@@ -164,6 +165,10 @@ TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) {
       expected_preferred_types.Put(syncer::FAVICON_IMAGES);
       expected_preferred_types.Put(syncer::FAVICON_TRACKING);
     }
+
+    // Device info is always preferred.
+    expected_preferred_types.Put(syncer::DEVICE_INFO);
+
     sync_prefs.SetPreferredDataTypes(user_types, preferred_types);
     EXPECT_TRUE(expected_preferred_types.Equals(
         sync_prefs.GetPreferredDataTypes(user_types)));
@@ -232,6 +237,19 @@ TEST_F(SyncPrefsTest, ClearPreferences) {
   EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty());
 }
 
+// Device info should always be enabled.
+TEST_F(SyncPrefsTest, DeviceInfo) {
+  SyncPrefs sync_prefs(&pref_service_);
+  EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes())
+                  .Has(syncer::DEVICE_INFO));
+  sync_prefs.SetKeepEverythingSynced(true);
+  EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes())
+                  .Has(syncer::DEVICE_INFO));
+  sync_prefs.SetKeepEverythingSynced(false);
+  EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes())
+                  .Has(syncer::DEVICE_INFO));
+}
+
 }  // namespace
 
 }  // namespace sync_driver
index 9e46f22..ef9570f 100644 (file)
@@ -1132,6 +1132,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
     switches::kEnableGPUClientLogging,
     switches::kEnableGpuClientTracing,
     switches::kEnableGPUServiceLogging,
+    switches::kEnableLinkDisambiguationPopup,
     switches::kEnableLowResTiling,
     switches::kEnableInbandTextTracks,
     switches::kEnableLCDText,
index ba9da06..e311974 100644 (file)
             '../third_party/webrtc/modules/modules.gyp:desktop_capture',
           ],
         }],
-        ['enable_webrtc==1 and OS=="mac"', {
-          'variables': {
-            'libpeer_target_type%': 'static_library',
-          },
-          'conditions': [
-            ['libpeer_target_type!="static_library"', {
-              'copies': [{
-                'destination': '<(PRODUCT_DIR)/Libraries',
-                'files': [
-                  '<(PRODUCT_DIR)/libpeerconnection.so',
-                ],
-              }],
-            }],
-          ],
-        }],
         ['enable_webrtc==1 and chromeos==1', {
           'sources': [
             'browser/media/capture/desktop_capture_device_aura_unittest.cc',
index 87a4ee9..7f4f9c4 100644 (file)
         ],
       },
     }],
-    ['OS=="linux" and libpeer_target_type=="loadable_module"', {
-      'variables': {
-        'isolate_dependency_tracked': [
-          '<(PRODUCT_DIR)/lib/libpeerconnection.so',
-        ],
-      },
-    }],
     ['OS=="mac"', {
       'variables': {
         'command': [
         ],
       },
     }],
-    ['OS=="win" and libpeer_target_type=="loadable_module"', {
-      'variables': {
-        'isolate_dependency_tracked': [
-          '<(PRODUCT_DIR)/libpeerconnection.dll',
-        ],
-      },
-    }],
   ],
   'includes': [
     '../base/base.isolate',
index ac41187..4efc507 100644 (file)
@@ -19,7 +19,6 @@
 #include "media/base/audio_fifo.h"
 #include "media/base/channel_layout.h"
 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
-#include "third_party/libjingle/overrides/init_webrtc.h"
 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h"
 #include "third_party/webrtc/modules/audio_processing/typing_detection.h"
 
@@ -424,7 +423,7 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
 #endif
 
   // Create and configure the webrtc::AudioProcessing.
-  audio_processing_.reset(CreateWebRtcAudioProcessing(config));
+  audio_processing_.reset(webrtc::AudioProcessing::Create(config));
 
   // Enable the audio processing components.
   if (echo_cancellation) {
index 8462a65..e386308 100644 (file)
@@ -251,10 +251,15 @@ void EnableTypingDetection(AudioProcessing* audio_processing,
 void StartEchoCancellationDump(AudioProcessing* audio_processing,
                                base::File aec_dump_file) {
   DCHECK(aec_dump_file.IsValid());
-  if (audio_processing->StartDebugRecordingForPlatformFile(
-      aec_dump_file.TakePlatformFile())) {
-    DLOG(ERROR) << "Fail to start AEC debug recording";
+
+  FILE* stream = base::FileToFILE(aec_dump_file.Pass(), "w");
+  if (!stream) {
+    LOG(ERROR) << "Failed to open AEC dump file";
+    return;
   }
+
+  if (audio_processing->StartDebugRecording(stream))
+    DLOG(ERROR) << "Fail to start AEC debug recording";
 }
 
 void StopEchoCancellationDump(AudioProcessing* audio_processing) {
index 453fffa..edb7ab5 100644 (file)
@@ -4031,6 +4031,9 @@ bool RenderViewImpl::didTapMultipleTargets(
     const WebSize& inner_viewport_offset,
     const WebRect& touch_rect,
     const WebVector<WebRect>& target_rects) {
+  if (!switches::IsLinkDisambiguationPopupEnabled())
+    return false;
+
   // Never show a disambiguation popup when accessibility is enabled,
   // as this interferes with "touch exploration".
   AccessibilityMode accessibility_mode =
index afaed96..611fa8a 100644 (file)
@@ -39,7 +39,6 @@
 #include "core/rendering/compositing/CompositedLayerMapping.h"
 #include "core/rendering/style/ShadowData.h"
 #include "platform/graphics/Color.h"
-#include "platform/graphics/DisplayList.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebCompositorAnimationCurve.h"
 #include "public/platform/WebCompositorSupport.h"
@@ -237,13 +236,6 @@ bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositin
     bool pathHasChanged = !(newPath == m_path);
     if (pathHasChanged) {
         m_path = newPath;
-
-        GraphicsContext gc(0);
-        gc.beginRecording(boundingRect);
-        gc.setFillColor(m_node->renderer()->style()->tapHighlightColor());
-        gc.fillPath(m_path);
-        m_displayList = gc.endRecording();
-
         m_contentLayer->layer()->setBounds(enclosingIntRect(boundingRect).size());
     }
 
@@ -260,8 +252,9 @@ void LinkHighlight::paintContents(WebCanvas* canvas, const WebRect& webClipRect,
     GraphicsContext gc(canvas,
         contextStatus == WebContentLayerClient::GraphicsContextEnabled ? GraphicsContext::NothingDisabled : GraphicsContext::FullyDisabled);
     IntRect clipRect(IntPoint(webClipRect.x, webClipRect.y), IntSize(webClipRect.width, webClipRect.height));
-    m_displayList->setClip(clipRect);
-    gc.drawDisplayList(m_displayList.get());
+    gc.clip(clipRect);
+    gc.setFillColor(m_node->renderer()->style()->tapHighlightColor());
+    gc.fillPath(m_path);
 }
 
 void LinkHighlight::startHighlightAnimationIfNeeded()
index cea39b0..47c203e 100644 (file)
@@ -39,7 +39,6 @@
 
 namespace blink {
 
-class DisplayList;
 class Node;
 class RenderLayer;
 class RenderObject;
@@ -86,7 +85,6 @@ private:
     OwnPtr<WebContentLayer> m_contentLayer;
     OwnPtr<WebLayer> m_clipLayer;
     Path m_path;
-    RefPtr<DisplayList> m_displayList;
 
     RefPtrWillBePersistent<Node> m_node;
     WebViewImpl* m_owningWebViewImpl;
index 69a744e..02c2bf9 100644 (file)
@@ -548,7 +548,6 @@ if (enable_webrtc) {
     deps = [
       ":libjingle_webrtc_common",
       "//third_party/webrtc",
-      "//third_party/webrtc/modules/audio_processing",
       "//third_party/webrtc/system_wrappers",
       "//third_party/webrtc/voice_engine",
     ]
index 63a5230..0eaf86c 100644 (file)
             '<(libjingle_source)/talk/media/webrtc/webrtcvoiceengine.h',
           ],
           'dependencies': [
-            '<(DEPTH)/third_party/webrtc/modules/modules.gyp:audio_processing',
             '<(DEPTH)/third_party/webrtc/system_wrappers/source/system_wrappers.gyp:system_wrappers',
             '<(DEPTH)/third_party/webrtc/voice_engine/voice_engine.gyp:voice_engine',
             '<(DEPTH)/third_party/webrtc/webrtc.gyp:webrtc',
index 0004d8e..ab89d58 100644 (file)
@@ -11,8 +11,6 @@
 #include "base/metrics/field_trial.h"
 #include "base/native_library.h"
 #include "base/path_service.h"
-#include "third_party/webrtc/common.h"
-#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/base/basictypes.h"
 #include "webrtc/base/logging.h"
 
@@ -55,13 +53,6 @@ bool InitializeWebRtcModule() {
   return true;
 }
 
-webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
-    const webrtc::Config& config) {
-  // libpeerconnection is being compiled as a static lib, use
-  // webrtc::AudioProcessing directly.
-  return webrtc::AudioProcessing::Create(config);
-}
-
 #else  // !LIBPEERCONNECTION_LIB
 
 // When being compiled as a shared library, we need to bridge the gap between
@@ -71,7 +62,6 @@ webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
 // Global function pointers to the factory functions in the shared library.
 CreateWebRtcMediaEngineFunction g_create_webrtc_media_engine = NULL;
 DestroyWebRtcMediaEngineFunction g_destroy_webrtc_media_engine = NULL;
-CreateWebRtcAudioProcessingFunction g_create_webrtc_audio_processing = NULL;
 
 // Returns the full or relative path to the libpeerconnection module depending
 // on what platform we're on.
@@ -145,8 +135,8 @@ bool InitializeWebRtcModule() {
                                    &AddTraceEvent,
                                    &g_create_webrtc_media_engine,
                                    &g_destroy_webrtc_media_engine,
-                                   &init_diagnostic_logging,
-                                   &g_create_webrtc_audio_processing);
+                                   &init_diagnostic_logging);
+
   if (init_ok)
     rtc::SetExtraLoggingInit(init_diagnostic_logging);
   return init_ok;
@@ -170,12 +160,4 @@ void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) {
   g_destroy_webrtc_media_engine(media_engine);
 }
 
-webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
-    const webrtc::Config& config) {
-  // The same as CreateWebRtcMediaEngine(), we call InitializeWebRtcModule here
-  // for convenience of tests.
-  InitializeWebRtcModule();
-  return g_create_webrtc_audio_processing(config);
-}
-
 #endif  // LIBPEERCONNECTION_LIB
index 4d06e9e..c5c190c 100644 (file)
@@ -23,8 +23,6 @@ class WebRtcVideoEncoderFactory;
 
 namespace webrtc {
 class AudioDeviceModule;
-class AudioProcessing;
-class Config;
 }  // namespace webrtc
 
 typedef std::string (*FieldTrialFindFullName)(const std::string& trial_name);
@@ -41,9 +39,6 @@ typedef void (*DestroyWebRtcMediaEngineFunction)(
 typedef void (*InitDiagnosticLoggingDelegateFunctionFunction)(
     void (*DelegateFunction)(const std::string&));
 
-typedef webrtc::AudioProcessing* (*CreateWebRtcAudioProcessingFunction)(
-    const webrtc::Config& config);
-
 // A typedef for the main initialize function in libpeerconnection.
 // This will initialize logging in the module with the proper arguments
 // as well as provide pointers back to a couple webrtc factory functions.
@@ -61,8 +56,7 @@ typedef bool (*InitializeModuleFunction)(
     webrtc::AddTraceEventPtr trace_add_trace_event,
     CreateWebRtcMediaEngineFunction* create_media_engine,
     DestroyWebRtcMediaEngineFunction* destroy_media_engine,
-    InitDiagnosticLoggingDelegateFunctionFunction* init_diagnostic_logging,
-    CreateWebRtcAudioProcessingFunction* create_audio_processing);
+    InitDiagnosticLoggingDelegateFunctionFunction* init_diagnostic_logging);
 
 #if !defined(LIBPEERCONNECTION_IMPLEMENTATION)
 // Load and initialize the shared WebRTC module (libpeerconnection).
@@ -71,11 +65,6 @@ typedef bool (*InitializeModuleFunction)(
 // If not called explicitly, this function will still be called from the main
 // CreateWebRtcMediaEngine factory function the first time it is called.
 bool InitializeWebRtcModule();
-
-// Return a webrtc::AudioProcessing object.
-webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
-    const webrtc::Config& config);
-
 #endif
 
 #endif // THIRD_PARTY_LIBJINGLE_OVERRIDES_INIT_WEBRTC_H_
index b84e2d8..ce11567 100644 (file)
@@ -8,7 +8,6 @@
 #include "base/logging.h"
 #include "init_webrtc.h"
 #include "talk/media/webrtc/webrtcmediaengine.h"
-#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/base/basictypes.h"
 #include "webrtc/base/logging.h"
 
@@ -72,9 +71,7 @@ bool InitializeModule(const CommandLine& command_line,
                       CreateWebRtcMediaEngineFunction* create_media_engine,
                       DestroyWebRtcMediaEngineFunction* destroy_media_engine,
                       InitDiagnosticLoggingDelegateFunctionFunction*
-                          init_diagnostic_logging,
-                      CreateWebRtcAudioProcessingFunction*
-                          create_audio_processing) {
+                          init_diagnostic_logging) {
 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
   g_alloc = alloc;
   g_dealloc = dealloc;
@@ -85,7 +82,6 @@ bool InitializeModule(const CommandLine& command_line,
   *create_media_engine = &CreateWebRtcMediaEngine;
   *destroy_media_engine = &DestroyWebRtcMediaEngine;
   *init_diagnostic_logging = &rtc::InitDiagnosticLoggingDelegateFunction;
-  *create_audio_processing = &webrtc::AudioProcessing::Create;
 
   if (CommandLine::Init(0, NULL)) {
 #if !defined(OS_WIN)
index ef70a5a..858a12d 100644 (file)
@@ -45643,6 +45643,7 @@ To add a new entry, add it with any value and run test to compute valid value.
   <int value="-1696366449" label="disable-permissions-bubbles"/>
   <int value="-1662447331" label="wake-on-packets"/>
   <int value="-1619757314" label="touch-scrolling-mode"/>
+  <int value="-1614912400" label="enable-link-disambiguation-popup"/>
   <int value="-1605567628" label="disable-overlay-scrollbar"/>
   <int value="-1596559650" label="max-tiles-for-interest-area"/>
   <int value="-1571841513" label="enable-devtools-experiments"/>
@@ -45799,6 +45800,7 @@ To add a new entry, add it with any value and run test to compute valid value.
   <int value="880510010" label="enable-permissions-bubbles"/>
   <int value="887011602" label="enable-spelling-auto-correct"/>
   <int value="909439558" label="disable-device-discovery"/>
+  <int value="929462705" label="disable-link-disambiguation-popup"/>
   <int value="1022992701" label="enable-origin-chip-always"/>
   <int value="1033597574" label="disable-layer-squashing"/>
   <int value="1050321458" label="new-profile-management"/>
index 3bf7de0..11416ee 100644 (file)
@@ -27,6 +27,10 @@ const char kDisableTouchDragDrop[] = "disable-touch-drag-drop";
 // Disables controls that support touch base text editing.
 const char kDisableTouchEditing[] = "disable-touch-editing";
 
+// Enables a zoomed popup bubble that allows the user to select a link.
+const char kEnableLinkDisambiguationPopup[] =
+    "enable-link-disambiguation-popup";
+
 // Enables an experimental focus manager to track text input clients.
 const char kEnableTextInputFocusManager[] = "enable-text-input-focus-manager";
 
index a23c920..ce267fb 100644 (file)
@@ -21,6 +21,7 @@ UI_BASE_EXPORT extern const char kDisableTextInputFocusManager[];
 UI_BASE_EXPORT extern const char kDisableTouchAdjustment[];
 UI_BASE_EXPORT extern const char kDisableTouchDragDrop[];
 UI_BASE_EXPORT extern const char kDisableTouchEditing[];
+UI_BASE_EXPORT extern const char kEnableLinkDisambiguationPopup[];
 UI_BASE_EXPORT extern const char kEnableTextInputFocusManager[];
 UI_BASE_EXPORT extern const char kEnableTouchDragDrop[];
 UI_BASE_EXPORT extern const char kEnableTouchEditing[];
index ba20e53..f562ea4 100644 (file)
@@ -9,6 +9,18 @@
 
 namespace switches {
 
+bool IsLinkDisambiguationPopupEnabled() {
+#if defined(OS_ANDROID)
+  return true;
+#else
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableLinkDisambiguationPopup)) {
+    return true;
+  }
+  return false;
+#endif
+}
+
 bool IsTextInputFocusManagerEnabled() {
   return CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kEnableTextInputFocusManager);
index 8dbc408..3988f6d 100644 (file)
@@ -9,6 +9,7 @@
 
 namespace switches {
 
+UI_BASE_EXPORT bool IsLinkDisambiguationPopupEnabled();
 UI_BASE_EXPORT bool IsTextInputFocusManagerEnabled();
 UI_BASE_EXPORT bool IsTouchDragDropEnabled();
 UI_BASE_EXPORT bool IsTouchEditingEnabled();
index e085009..66e32ed 100644 (file)
@@ -17,7 +17,7 @@
 # Edit these when rolling DEPS.xwalk.
 # -----------------------------------
 
-chromium_crosswalk_rev = 'ea46c0b6279a60b0173a092f0e9f0403a2a047a9'
+chromium_crosswalk_rev = '0bbff352135bacf2e6a17b5ffebd387f3c2d085f'
 v8_crosswalk_rev = '05d1cf41ef1b6e73079f69492d9e942ec19cc61a'
 ozone_wayland_rev = '6379cd118da098b55a5934ce1a90b377a177ed40'
 
@@ -27,8 +27,8 @@ ozone_wayland_rev = '6379cd118da098b55a5934ce1a90b377a177ed40'
 # the blink-crosswalk repository, so that the devtools code can use it to fetch
 # assets from Chromium's servers with a revision that exists there. We need an
 # SVN revision while Blink is still in SVN.
-blink_crosswalk_rev = '1620ccec09abbd0dae196999fbcd94505136b306'
-blink_upstream_rev = '185156'
+blink_crosswalk_rev = 'dc24b658e6b89accb1e21a14bc06dc72bfc00c41'
+blink_upstream_rev = '185310'
 
 crosswalk_git = 'https://github.com/crosswalk-project'
 ozone_wayland_git = 'https://github.com/01org'
index 0af64ea..3ef08e0 100644 (file)
@@ -1,4 +1,4 @@
 MAJOR=11
 MINOR=39
-BUILD=260
+BUILD=264
 PATCH=0
index 5989755..7632a2e 100644 (file)
Binary files a/src/xwalk/app/android/app_hello_world/res/drawable-hdpi/crosswalk.png and b/src/xwalk/app/android/app_hello_world/res/drawable-hdpi/crosswalk.png differ
index e87864a..dbbcb3d 100644 (file)
Binary files a/src/xwalk/app/android/app_hello_world/res/drawable-ldpi/crosswalk.png and b/src/xwalk/app/android/app_hello_world/res/drawable-ldpi/crosswalk.png differ
index fc19a3e..90c660e 100644 (file)
Binary files a/src/xwalk/app/android/app_hello_world/res/drawable-mdpi/crosswalk.png and b/src/xwalk/app/android/app_hello_world/res/drawable-mdpi/crosswalk.png differ
index b69b4e8..9aeeff7 100644 (file)
Binary files a/src/xwalk/app/android/app_hello_world/res/drawable-xhdpi/crosswalk.png and b/src/xwalk/app/android/app_hello_world/res/drawable-xhdpi/crosswalk.png differ
index 5989755..7632a2e 100644 (file)
Binary files a/src/xwalk/app/android/app_template/res/drawable-hdpi/crosswalk.png and b/src/xwalk/app/android/app_template/res/drawable-hdpi/crosswalk.png differ
index e87864a..dbbcb3d 100644 (file)
Binary files a/src/xwalk/app/android/app_template/res/drawable-ldpi/crosswalk.png and b/src/xwalk/app/android/app_template/res/drawable-ldpi/crosswalk.png differ
index fc19a3e..90c660e 100644 (file)
Binary files a/src/xwalk/app/android/app_template/res/drawable-mdpi/crosswalk.png and b/src/xwalk/app/android/app_template/res/drawable-mdpi/crosswalk.png differ
index b69b4e8..9aeeff7 100644 (file)
Binary files a/src/xwalk/app/android/app_template/res/drawable-xhdpi/crosswalk.png and b/src/xwalk/app/android/app_template/res/drawable-xhdpi/crosswalk.png differ
index b69b4e8..9aeeff7 100644 (file)
Binary files a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_144.png and b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_144.png differ
index e87864a..dbbcb3d 100644 (file)
Binary files a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_48.png and b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_48.png differ
index fc19a3e..90c660e 100644 (file)
Binary files a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_72.png and b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_72.png differ
index 5989755..7632a2e 100644 (file)
Binary files a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_96.png and b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_96.png differ
index 2dbc11d..4adb166 100644 (file)
@@ -24,6 +24,7 @@
 #include "xwalk/application/common/id_util.h"
 #include "xwalk/runtime/browser/runtime.h"
 #include "xwalk/runtime/browser/xwalk_browser_context.h"
+#include "xwalk/runtime/browser/xwalk_runner.h"
 #include "xwalk/runtime/common/xwalk_paths.h"
 
 #if defined(OS_TIZEN)
@@ -249,12 +250,12 @@ void ApplicationService::OnApplicationTerminated(
           base::Bind(&base::DoNothing));
   }
 
-#if !defined(SHARED_PROCESS_MODE)
-  if (applications_.empty()) {
-    base::MessageLoop::current()->PostTask(
+  if (!XWalkRunner::GetInstance()->shared_process_mode_enabled()) {
+    if (applications_.empty()) {
+      base::MessageLoop::current()->PostTask(
             FROM_HERE, base::MessageLoop::QuitClosure());
+    }
   }
-#endif
 }
 
 void ApplicationService::CheckAPIAccessControl(const std::string& app_id,
index e8f0130..339e093 100644 (file)
@@ -14,11 +14,11 @@ namespace application {
 
 ApplicationSystemLinux::ApplicationSystemLinux(XWalkBrowserContext* context)
     : ApplicationSystem(context) {
-#if defined(SHARED_PROCESS_MODE)
+  if (XWalkRunner::GetInstance()->shared_process_mode_enabled()) {
     service_provider_.reset(
         new ApplicationServiceProviderLinux(application_service(),
                                             dbus_manager().session_bus()));
-#endif
+  }
 }
 
 ApplicationSystemLinux::~ApplicationSystemLinux() {}
index 8829982..495c0ef 100644 (file)
@@ -1,11 +1,13 @@
 // Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd 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/manifest_handlers/csp_handler.h"
-
-#include "xwalk/application/common/application_manifest_constants.h"
+#include "base/memory/scoped_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "xwalk/application/common/application_manifest_constants.h"
+#include "xwalk/application/common/manifest_handlers/csp_handler.h"
+#include "xwalk/application/common/manifest_handlers/unittest_util.h"
 
 namespace xwalk {
 
@@ -14,51 +16,44 @@ namespace widget_keys = application_widget_keys;
 
 namespace application {
 
-class CSPHandlerTest: public testing::Test {
- public:
-  scoped_refptr<ApplicationData> CreateApplication() {
-    std::string error;
-    scoped_refptr<ApplicationData> app_data = ApplicationData::Create(
-        base::FilePath(), std::string(), ApplicationData::LOCAL_DIRECTORY,
-        make_scoped_ptr(new Manifest(make_scoped_ptr(manifest.DeepCopy()))),
-        &error);
-    return app_data;
-  }
+namespace {
+
+const CSPInfo* GetCSPInfo(
+    scoped_refptr<ApplicationData> application) {
+  const CSPInfo* info = static_cast<CSPInfo*>(
+      application->GetManifestData(GetCSPKey(application->manifest_type())));
+  return info;
+}
 
-  const CSPInfo* GetCSPInfo(
-      scoped_refptr<ApplicationData> application) {
-    const CSPInfo* info = static_cast<CSPInfo*>(
-        application->GetManifestData(GetCSPKey(application->manifest_type())));
-    return info;
-  }
+}  // namespace
 
-  base::DictionaryValue manifest;
+class CSPHandlerTest: public testing::Test {
 };
 
 // FIXME: the default CSP policy settings in CSP manifest handler
 // are temporally removed, since they had affected some tests and legacy apps.
 TEST_F(CSPHandlerTest, DISABLED_NoCSP) {
-  manifest.SetString(keys::kNameKey, "no name");
-  manifest.SetString(keys::kXWalkVersionKey, "0");
-  scoped_refptr<ApplicationData> application = CreateApplication();
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultManifestConfig();
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_MANIFEST, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_EQ(GetCSPInfo(application)->GetDirectives().size(), 2);
 }
 
 TEST_F(CSPHandlerTest, EmptyCSP) {
-  manifest.SetString(keys::kNameKey, "no name");
-  manifest.SetString(keys::kXWalkVersionKey, "0");
-  manifest.SetString(keys::kCSPKey, "");
-  scoped_refptr<ApplicationData> application = CreateApplication();
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultManifestConfig();
+  manifest->SetString(keys::kCSPKey, "");
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_MANIFEST, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_EQ(GetCSPInfo(application)->GetDirectives().size(), 0);
 }
 
 TEST_F(CSPHandlerTest, CSP) {
-  manifest.SetString(keys::kNameKey, "no name");
-  manifest.SetString(keys::kXWalkVersionKey, "0");
-  manifest.SetString(keys::kCSPKey, "default-src    'self'   ");
-  scoped_refptr<ApplicationData> application = CreateApplication();
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultManifestConfig();
+  manifest->SetString(keys::kCSPKey, "default-src    'self'   ");
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_MANIFEST, *manifest);
   EXPECT_TRUE(application.get());
   const std::map<std::string, std::vector<std::string> >& policies =
       GetCSPInfo(application)->GetDirectives();
@@ -72,20 +67,20 @@ TEST_F(CSPHandlerTest, CSP) {
 
 #if defined(OS_TIZEN)
 TEST_F(CSPHandlerTest, WGTEmptyCSP) {
-  manifest.SetString(widget_keys::kNameKey, "no name");
-  manifest.SetString(widget_keys::kVersionKey, "0");
-  manifest.SetString(widget_keys::kCSPKey, "");
-  scoped_refptr<ApplicationData> application = CreateApplication();
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+  manifest->SetString(widget_keys::kCSPKey, "");
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_TRUE(GetCSPInfo(application));
   EXPECT_EQ(GetCSPInfo(application)->GetDirectives().size(), 0);
 }
 
 TEST_F(CSPHandlerTest, WGTCSP) {
-  manifest.SetString(widget_keys::kNameKey, "no name");
-  manifest.SetString(widget_keys::kVersionKey, "0");
-  manifest.SetString(widget_keys::kCSPKey, "default-src    'self'   ");
-  scoped_refptr<ApplicationData> application = CreateApplication();
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+  manifest->SetString(widget_keys::kCSPKey, "default-src    'self'   ");
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_TRUE(GetCSPInfo(application));
   const std::map<std::string, std::vector<std::string> >& policies =
index 2edbd58..03d0d7a 100644 (file)
@@ -106,6 +106,7 @@ void SetError(const std::string& message,
 // parameter is specified, it is also filled with proper message.
 bool GetMandatoryDictionary(const Manifest& manifest, const std::string& key,
     const base::DictionaryValue** dict, base::string16* error) {
+  DCHECK(dict);
   if (!manifest.HasPath(key)) {
     SetError(kErrMsgNoMandatoryKey, key, error);
     return false;
@@ -174,13 +175,11 @@ template <typename ValueType>
 bool GetMandatoryValue(const base::DictionaryValue& dict,
     const std::string& key, ValueType* value, base::string16* error) {
   DCHECK(value);
-
   std::string tmp;
   if (!dict.GetString(key, &tmp)) {
     SetError(kErrMsgNoMandatoryKey, key, error);
     return false;
   }
-
   bool result = ConvertValue(tmp, value);
   if (!result)
     SetError(kErrMsgInvalidKeyValue, key, error);
@@ -197,13 +196,11 @@ bool GetOptionalValue(const base::DictionaryValue& dict,
     const std::string& key, ValueType default_value, ValueType* value,
     base::string16* error) {
   DCHECK(value);
-
   std::string tmp;
   if (!dict.GetString(key, &tmp)) {
     *value = default_value;
     return true;
   }
-
   bool result = ConvertValue(tmp, value);
   if (!result)
     SetError(kErrMsgInvalidKeyValue, key, error);
@@ -216,7 +213,6 @@ bool ParseEachInternal(const base::Value& value, const std::string& key,
     ParseSingleType parse_single, DataContainerType* data_container,
     base::string16* error) {
   DCHECK(data_container);
-
   const base::DictionaryValue* inner_dict;
   if (!value.GetAsDictionary(&inner_dict)) {
     SetError(kErrMsgInvalidDictionary, key, error);
@@ -224,7 +220,6 @@ bool ParseEachInternal(const base::Value& value, const std::string& key,
   }
   if (!parse_single(*inner_dict, key, data_container, error))
     return false;
-
   return true;
 }
 
diff --git a/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler_unittest.cc b/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler_unittest.cc
new file mode 100644 (file)
index 0000000..de42388
--- /dev/null
@@ -0,0 +1,864 @@
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <map>
+#include <string>
+#include <vector>
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "xwalk/application/common/application_manifest_constants.h"
+#include "xwalk/application/common/manifest.h"
+#include "xwalk/application/common/manifest_handlers/tizen_appwidget_handler.h"
+#include "xwalk/application/common/manifest_handlers/unittest_util.h"
+
+namespace xwalk {
+
+namespace keys = application_widget_keys;
+
+namespace application {
+
+namespace {
+
+// Extracts app-widget info object from application data object.
+const TizenAppWidgetInfo* GetInfo(scoped_refptr<ApplicationData> application) {
+  const TizenAppWidgetInfo* info = static_cast<TizenAppWidgetInfo*>(
+      application->GetManifestData(keys::kTizenAppWidgetFullKey));
+  return info;
+}
+
+// In specified dictionary sets a specified value under a specified key.
+// The value is set only if it is not empty.
+void SetNotEmptyString(const std::string& key, const std::string& value,
+    base::DictionaryValue* dictionary) {
+  CHECK(!key.empty());
+  CHECK(dictionary);
+  if (!value.empty())
+    dictionary->SetString(key, value);
+}
+
+// Creates a dictionary with namespace set to tizen.
+scoped_ptr<base::DictionaryValue> CreateTizenElement() {
+  scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
+  result->SetString(keys::kNamespaceKey, keys::kTizenNamespacePrefix);
+  return result.Pass();
+}
+
+// Creates a dictionary representing an app-widget element.
+scoped_ptr<base::DictionaryValue> CreateAppWidget(
+    const std::string& id, const std::string& primary,
+    const std::string& update_peroid = std::string(),
+    const std::string& auto_launch = std::string()) {
+  scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+  SetNotEmptyString(keys::kTizenAppWidgetIdKey, id, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetPrimaryKey, primary, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetUpdatePeriodKey,
+                    update_peroid, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetAutoLaunchKey,
+                    auto_launch, result.get());
+  return result.Pass();
+}
+
+// Creates a dictionary representing a box-label element.
+scoped_ptr<base::DictionaryValue> CreateBoxLabel(
+    const std::string& label, const std::string& lang = std::string()) {
+  scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+  SetNotEmptyString(keys::kTizenAppWidgetBoxLabelTextKey, label, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxLabelLangKey, lang, result.get());
+  return result.Pass();
+}
+
+// Creates a dictionary representing a box-icon element.
+scoped_ptr<base::DictionaryValue> CreateBoxIcon(const std::string& src) {
+  scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+  SetNotEmptyString(keys::kTizenAppWidgetBoxIconSrcKey, src, result.get());
+  return result.Pass();
+}
+
+// Creates a dictionary representing a box-content element.
+scoped_ptr<base::DictionaryValue> CreateBoxContent(
+    const std::string& src, const std::string& mouse_event = std::string(),
+    const std::string& touch_effect = std::string()) {
+  scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentSrcKey,
+                    src, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentMouseEventKey,
+                    mouse_event, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentTouchEffectKey,
+                    touch_effect, result.get());
+  return result.Pass();
+}
+
+// Creates a dictionary representing a box-size element.
+scoped_ptr<base::DictionaryValue> CreateBoxSize(
+    const std::string& type, const std::string& preview = std::string(),
+    const std::string& use_decoration = std::string()) {
+  scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentSizeTextKey,
+                    type, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentSizePreviewKey,
+                    preview, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentSizeUseDecorationKey,
+                    use_decoration, result.get());
+  return result.Pass();
+}
+
+// Creates a dictionary representing a pd element.
+scoped_ptr<base::DictionaryValue> CreateBoxDropView(
+    const std::string& src, const std::string& width,
+    const std::string& height) {
+  scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentDropViewSrcKey,
+                    src, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentDropViewWidthKey,
+                    width, result.get());
+  SetNotEmptyString(keys::kTizenAppWidgetBoxContentDropViewHeightKey,
+                    height, result.get());
+  return result.Pass();
+}
+
+// Creates an app-widget element id basing on values of default package id
+// and default application name.
+std::string CreateAppWidgetId(const std::string& name) {
+  std::vector<std::string> parts;
+  parts.push_back(kDefaultWidgetPackageId);
+  parts.push_back(kDefaultWidgetApplicationName);
+  parts.push_back(name);
+  return JoinString(parts, '.');
+}
+
+// Creates a dictionary representing an app-widget element with all required
+// fields and child elements set.
+scoped_ptr<base::DictionaryValue> CreateMinimalAppWidget(
+    const std::string& name, const std::string& primary) {
+  std::string id = CreateAppWidgetId(name);
+
+  scoped_ptr<base::DictionaryValue> result = CreateAppWidget(id, primary);
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey,
+      CreateBoxLabel("sample label"), result.get()));
+
+  scoped_ptr<base::DictionaryValue> box_content =
+      CreateBoxContent("index.html");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+      CreateBoxSize("1x1"), box_content.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentKey,
+      box_content.Pass(), result.get()));
+
+  return result.Pass();
+}
+
+// Creates a dictionary representing an app-widget element with all fields and
+// child elements set. Each optional field is set to something different than
+// its default value if specified.
+scoped_ptr<base::DictionaryValue> CreateFullAppWidget(
+    const std::string& name, const std::string& primary) {
+  std::string id = CreateAppWidgetId(name);
+
+  scoped_ptr<base::DictionaryValue> result =
+      CreateAppWidget(id, primary, "1800.0", "true");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey,
+      CreateBoxLabel("sample label"), result.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey,
+      CreateBoxLabel("sample en label", "en"), result.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxIconKey,
+      CreateBoxIcon("icon.png"), result.get()));
+
+  scoped_ptr<base::DictionaryValue> box_content =
+      CreateBoxContent("index.html", "true", "false");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+      CreateBoxSize("1x1"), box_content.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+      CreateBoxSize("2x1", "image.png"), box_content.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+      CreateBoxSize("2x2", "", "false"), box_content.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentDropViewKey,
+      CreateBoxDropView("index.html", "720", "150"), box_content.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentKey,
+      box_content.Pass(), result.get()));
+
+  return result.Pass();
+}
+
+// Tests wheter specified value type is a dictionary or a list.
+bool IsComplexValueType(base::Value::Type type) {
+  return type == base::Value::TYPE_DICTIONARY || type == base::Value::TYPE_LIST;
+}
+
+// Searches for a child value specified by name in specified root value and
+// if the child is found, fills child and parent arguments with the found child
+// and its parent. Both parent and child arguments are optional.
+bool GetParentAndChild(const std::string& name, base::Value* root,
+    base::DictionaryValue** parent, base::Value** child) {
+  CHECK(!name.empty());
+  CHECK(root);
+
+  base::DictionaryValue* tmp_parent = nullptr;
+  if (!root->GetAsDictionary(&tmp_parent))
+    return false;
+
+  base::Value* tmp_child;
+  if (!tmp_parent->Get(name, &tmp_child))
+    return false;
+
+  if (parent)
+    *parent = tmp_parent;
+  if (child)
+    *child = tmp_child;
+
+  return true;
+}
+
+// Searches for a child value specified by name and index in specified root
+// value and if the child is found, fills child and parent arguments with
+// the found child and its parent. Both parent and child arguments are optional.
+bool GetParentAndChild(const std::string& name, size_t index,
+    base::Value* root, base::ListValue** parent, base::Value** child) {
+  CHECK(!name.empty());
+  CHECK(root);
+
+  base::Value* first_level_child;
+  if (!GetParentAndChild(name, root, nullptr, &first_level_child))
+    return false;
+
+  base::ListValue* tmp_parent = nullptr;
+  if (!first_level_child->GetAsList(&tmp_parent))
+    return false;
+
+  base::Value* tmp_child;
+  if (!tmp_parent->Get(index, &tmp_child))
+    return false;
+
+  if (parent)
+    *parent = tmp_parent;
+  if (child)
+    *child = tmp_child;
+
+  return true;
+}
+
+// If the value argument is nullptr, the function removes the value specified by
+// path, otherwise it changes the value specified by path to the value argument.
+bool ChangeOrRemove(const std::string& path, base::Value * root,
+    const std::string* value = nullptr) {
+  CHECK(!path.empty());
+  CHECK(root);
+
+  base::Value* current = root;
+
+  std::vector<std::string> parts;
+  base::SplitString(path, '.', &parts);
+  for (size_t i = 0, count = parts.size(); i < count; ++i) {
+    const std::string& part = parts[i];
+
+    std::vector<std::string> name_and_index;
+    base::SplitString(part, ':', &name_and_index);
+    if (name_and_index.size() == 1) {  // current part refers to a dictionary
+      const std::string& name = name_and_index[0];
+
+      base::DictionaryValue* parent;
+      base::Value* child;
+      if (!GetParentAndChild(name, current, &parent, &child))
+        return false;
+
+      if (i == count - 1) {
+        if (value) {
+          if (IsComplexValueType(child->GetType()))
+            return false;
+          parent->SetString(name, *value);
+          return true;
+        }
+        return parent->Remove(name, nullptr);
+      }
+
+      current = child;
+    } else if (name_and_index.size() == 2) {  // current part refers to a list
+      const std::string& name = name_and_index[0];
+      unsigned index;
+      if (!base::StringToUint(name_and_index[1], &index))
+        return false;  // invalid path
+
+      base::ListValue* parent;
+      base::Value* child;
+      if (!GetParentAndChild(name, index, current, &parent, &child))
+        return false;
+
+      if (i == count - 1) {
+        if (value) {
+          if (IsComplexValueType(child->GetType()))
+            return false;
+          parent->Set(index, new base::StringValue(*value));
+          return true;
+        }
+        return parent->Remove(index, nullptr);
+      }
+
+      current = child;
+    } else {  // current part is invalid
+      return false;
+    }
+  }
+
+  return current;
+}
+
+// Creates a key representing a list value item. For example "box-size:2".
+std::string MakeListItemKey(const std::string& name, size_t index) {
+  return name + ':' + base::UintToString(index);
+}
+
+// Makes a path to widget.app-widget.element.
+std::string MakeAppWidgetPath(const std::string& element) {
+  return MakeElementPath(keys::kTizenAppWidgetFullKey, element);
+}
+
+// Makes a path to widget.app-widget.box-label:index.element.
+std::string MakeBoxLabelPath(size_t index, const std::string& element) {
+  const std::string& label =
+      MakeListItemKey(keys::kTizenAppWidgetBoxLabelKey, index);
+  return MakeElementPath(MakeAppWidgetPath(label), element);
+}
+
+// Makes a path to widget.app-widget.box-icon.element.
+std::string MakeBoxIconPath(const std::string& element) {
+  return MakeElementPath(
+      MakeAppWidgetPath(keys::kTizenAppWidgetBoxIconKey), element);
+}
+
+// Makes a path to widget.app-widget.box-content.element.
+std::string MakeBoxContentPath(const std::string& element) {
+  return MakeElementPath(
+      MakeAppWidgetPath(keys::kTizenAppWidgetBoxContentKey), element);
+}
+
+// Makes a path to widget.app-widget.box-content.box-size:index.element.
+std::string MakeSizePath(size_t index, const std::string& element) {
+  const std::string& size =
+      MakeListItemKey(keys::kTizenAppWidgetBoxContentSizeKey, index);
+  return MakeElementPath(MakeBoxContentPath(size), element);
+}
+
+// Makes a path to widget.app-widget.box-content.pd.element.
+std::string MakeDropViewPath(const std::string& element) {
+  return MakeElementPath(
+      MakeBoxContentPath(keys::kTizenAppWidgetBoxContentDropViewKey), element);
+}
+
+}  // namespace
+
+class TizenAppWidgetHandlerTest: public testing::Test {
+ public:
+  void ChangedOrRemovedFieldTest(const std::string& path,
+                                 const std::string* value = nullptr) {
+    scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+    scoped_ptr<base::DictionaryValue> app_widget =
+        CreateFullAppWidget("first", "true");
+
+    CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+        app_widget.Pass(), manifest.get()));
+
+    CHECK(ChangeOrRemove(path, manifest.get(), value));
+
+    scoped_refptr<ApplicationData> application =
+        CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+    EXPECT_EQ(nullptr, application.get());
+  }
+
+  // Defines a test in which a field specified by path is removed from
+  // manifest created by CreateDefaultWidgetConfig and complemented by
+  // app-widget element created by CreateFullAppWidget.
+  // Can be used when path is precise (there is no dictionary list in the way).
+  void MissingFieldTest(const std::string& path) {
+    ChangedOrRemovedFieldTest(path);
+  }
+
+  // Defines a test in which a field specified by path is changed in
+  // manifest created by CreateDefaultWidgetConfig and complemented by
+  // app-widget element created by CreateFullAppWidget.
+  // Can be used when path is precise (there is no dictionary list in the way).
+  void InvalidFieldValueTest(const std::string& path,
+                             const std::string& value) {
+    ChangedOrRemovedFieldTest(path, &value);
+  }
+};
+
+// Test case for no app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, NoAppWidget) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_NE(nullptr, application.get());
+  EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+  const TizenAppWidgetInfo* info = GetInfo(application);
+  EXPECT_EQ(nullptr, info);
+}
+
+// Test case for one app-widget element with only required attributes and child
+// elements set.
+TEST_F(TizenAppWidgetHandlerTest, OneMinimalAppWidget) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_ptr<base::DictionaryValue> app_widget =
+      CreateMinimalAppWidget("first", "true");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_NE(nullptr, application.get());
+  EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+  const TizenAppWidgetInfo* info = GetInfo(application);
+  EXPECT_NE(nullptr, info);
+
+  const TizenAppWidgetVector& app_widgets = info->app_widgets();
+  EXPECT_EQ(1, app_widgets.size());
+
+  const TizenAppWidget& element = app_widgets[0];
+
+  std::vector<std::string> id_parts;
+  base::SplitString(element.id, '.', &id_parts);
+  EXPECT_EQ(3, id_parts.size());
+  EXPECT_EQ("first", id_parts[2]);
+  EXPECT_TRUE(element.primary);
+  EXPECT_EQ(0, element.update_period.size());
+  EXPECT_FALSE(element.auto_launch);
+  EXPECT_EQ("sample label", element.label.default_value);
+  EXPECT_EQ(0, element.label.lang_value_map.size());
+  EXPECT_TRUE(element.icon_src.empty());
+  EXPECT_EQ("index.html", element.content_src);
+  EXPECT_FALSE(element.content_mouse_event);
+  EXPECT_TRUE(element.content_touch_effect);
+  EXPECT_EQ(1, element.content_size.size());
+  EXPECT_EQ(TizenAppWidgetSizeType::k1x1, element.content_size[0].type);
+  EXPECT_TRUE(element.content_size[0].preview.empty());
+  EXPECT_TRUE(element.content_size[0].use_decoration);
+  EXPECT_EQ(0, element.content_drop_view.size());
+}
+
+// Test case for two app-widget elements with only required attributes and child
+// elements set.
+TEST_F(TizenAppWidgetHandlerTest, TwoMinimalAppWidgets) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_ptr<base::DictionaryValue> app_widget =
+      CreateMinimalAppWidget("first", "true");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  app_widget = CreateMinimalAppWidget("second", "false");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_NE(nullptr, application.get());
+  EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+  const TizenAppWidgetInfo* info = GetInfo(application);
+  EXPECT_NE(nullptr, info);
+
+  const TizenAppWidgetVector& app_widgets = info->app_widgets();
+  EXPECT_EQ(2, app_widgets.size());
+
+  std::vector<std::string> id_parts;
+  base::SplitString(app_widgets[0].id, '.', &id_parts);
+  EXPECT_EQ(3, id_parts.size());
+  EXPECT_EQ("first", id_parts[2]);
+  EXPECT_TRUE(app_widgets[0].primary);
+
+  base::SplitString(app_widgets[1].id, '.', &id_parts);
+  EXPECT_EQ(3, id_parts.size());
+  EXPECT_EQ("second", id_parts[2]);
+  EXPECT_FALSE(app_widgets[1].primary);
+
+  for (const TizenAppWidget& element : app_widgets) {
+    EXPECT_EQ(0, element.update_period.size());
+    EXPECT_FALSE(element.auto_launch);
+    EXPECT_EQ("sample label", element.label.default_value);
+    EXPECT_EQ(0, element.label.lang_value_map.size());
+    EXPECT_TRUE(element.icon_src.empty());
+    EXPECT_EQ("index.html", element.content_src);
+    EXPECT_FALSE(element.content_mouse_event);
+    EXPECT_TRUE(element.content_touch_effect);
+    EXPECT_EQ(1, element.content_size.size());
+    EXPECT_EQ(TizenAppWidgetSizeType::k1x1, element.content_size[0].type);
+    EXPECT_TRUE(element.content_size[0].preview.empty());
+    EXPECT_TRUE(element.content_size[0].use_decoration);
+    EXPECT_EQ(0, element.content_drop_view.size());
+  }
+}
+
+// Test case for one app-widget element with all posible attributes and child
+// elements set.
+TEST_F(TizenAppWidgetHandlerTest, OneFullAppWidget) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_ptr<base::DictionaryValue> app_widget =
+      CreateFullAppWidget("first", "true");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_NE(nullptr, application.get());
+  EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+  const TizenAppWidgetInfo* info = GetInfo(application);
+  EXPECT_NE(nullptr, info);
+
+  const TizenAppWidgetVector& app_widgets = info->app_widgets();
+  EXPECT_EQ(1, app_widgets.size());
+
+  const TizenAppWidget& element = app_widgets[0];
+
+  std::vector<std::string> id_parts;
+  base::SplitString(element.id, '.', &id_parts);
+  EXPECT_EQ(3, id_parts.size());
+  EXPECT_EQ("first", id_parts[2]);
+  EXPECT_TRUE(element.primary);
+  EXPECT_EQ(1, element.update_period.size());
+  EXPECT_EQ(1800, element.update_period[0]);
+  EXPECT_TRUE(element.auto_launch);
+  EXPECT_EQ("sample label", element.label.default_value);
+  EXPECT_EQ(1, element.label.lang_value_map.size());
+  EXPECT_EQ("sample en label", element.label.lang_value_map.at("en"));
+  EXPECT_EQ("icon.png", element.icon_src);
+  EXPECT_EQ("index.html", element.content_src);
+  EXPECT_TRUE(element.content_mouse_event);
+  EXPECT_FALSE(element.content_touch_effect);
+  EXPECT_EQ(3, element.content_size.size());
+  EXPECT_EQ(TizenAppWidgetSizeType::k1x1, element.content_size[0].type);
+  EXPECT_TRUE(element.content_size[0].preview.empty());
+  EXPECT_TRUE(element.content_size[0].use_decoration);
+  EXPECT_EQ(TizenAppWidgetSizeType::k2x1, element.content_size[1].type);
+  EXPECT_EQ("image.png", element.content_size[1].preview);
+  EXPECT_TRUE(element.content_size[1].use_decoration);
+  EXPECT_EQ(TizenAppWidgetSizeType::k2x2, element.content_size[2].type);
+  EXPECT_TRUE(element.content_size[2].preview.empty());
+  EXPECT_FALSE(element.content_size[2].use_decoration);
+  EXPECT_EQ(1, element.content_drop_view.size());
+  EXPECT_EQ("index.html", element.content_drop_view[0].src);
+  EXPECT_EQ(720, element.content_drop_view[0].width);
+  EXPECT_EQ(150, element.content_drop_view[0].height);
+}
+
+// Test case for missing namespace attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingAppWidgetNamespace) {
+  MissingFieldTest(MakeAppWidgetPath(keys::kNamespaceKey));
+}
+
+// Test case for missing id attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingId) {
+  MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetIdKey));
+}
+
+// Test case for missing primary attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingPrimary) {
+  MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetPrimaryKey));
+}
+
+// Test case for missing box-label element in app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingLabel) {
+  MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetBoxLabelKey));
+}
+
+// Test case for missing namespace attribute of box-label element.
+TEST_F(TizenAppWidgetHandlerTest, MissingLabelNamespace) {
+  MissingFieldTest(MakeBoxLabelPath(0, keys::kNamespaceKey));
+}
+
+// Test case for missing namespace attribute of box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, MissingIconNamespace) {
+  MissingFieldTest(MakeBoxIconPath(keys::kNamespaceKey));
+}
+
+// Test case for missing src attribute of box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, MissingIconSrc) {
+  MissingFieldTest(MakeBoxIconPath(keys::kTizenAppWidgetBoxIconSrcKey));
+}
+
+// Test case for missing box-content element in app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingContent) {
+  MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetBoxContentKey));
+}
+
+// Test case for missing namespace attribute of box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingContentNamespace) {
+  MissingFieldTest(MakeBoxContentPath(keys::kNamespaceKey));
+}
+
+// Test case for missing src attribute of box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingContentSrc) {
+  MissingFieldTest(MakeBoxContentPath(keys::kTizenAppWidgetBoxContentSrcKey));
+}
+
+// Test case for missing box-size element in box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingSize) {
+  MissingFieldTest(MakeBoxContentPath(keys::kTizenAppWidgetBoxContentSizeKey));
+}
+
+// Test case for missing namespace attribute of box-size element.
+TEST_F(TizenAppWidgetHandlerTest, MissingSizeNamespace) {
+  MissingFieldTest(MakeSizePath(0, keys::kNamespaceKey));
+}
+
+// Test case for missing box-size element with 1x1 value in box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingSize1x1) {
+  MissingFieldTest(MakeBoxContentPath(MakeListItemKey(
+      keys::kTizenAppWidgetBoxContentSizeKey, 0)));
+}
+
+// Test case for missing namespace attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingDropViewNamespace) {
+  MissingFieldTest(MakeDropViewPath(keys::kNamespaceKey));
+}
+
+// Test case for missing src attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingDropViewSrc) {
+  MissingFieldTest(MakeDropViewPath(
+      keys::kTizenAppWidgetBoxContentDropViewSrcKey));
+}
+
+// Test case for missing width attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingWidth) {
+  MissingFieldTest(MakeDropViewPath(
+      keys::kTizenAppWidgetBoxContentDropViewWidthKey));
+}
+
+// Test case for missing height attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingHeight) {
+  MissingFieldTest(MakeDropViewPath(
+      keys::kTizenAppWidgetBoxContentDropViewHeightKey));
+}
+
+// Test case for invalid namespace attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidAppWidgetNamespace) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kNamespaceKey),
+      "not_a_tizen_namespace");
+}
+
+// Test case for invalid id attribute of app-widget element.
+// The id must start with application id.
+TEST_F(TizenAppWidgetHandlerTest, InvalidIdNotStartedWithAppId) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kTizenAppWidgetIdKey),
+      "invalid_id");
+}
+
+// Test case for invalid id attribute of app-widget element.
+// The id must consist of 0-9a-zA-Z.
+TEST_F(TizenAppWidgetHandlerTest, InvalidIdInvalidCharInNamePart) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kTizenAppWidgetIdKey),
+      CreateAppWidgetId("the-first"));
+}
+
+// Test case for invalid primary attribute of app-widget element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidPrimary) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kTizenAppWidgetPrimaryKey),
+      "not_true_nor_false");
+}
+
+// Test case for invalid update-period attribute of app-widget element.
+// The value must be integer.
+TEST_F(TizenAppWidgetHandlerTest, InvalidUpdatePeriod) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kTizenAppWidgetUpdatePeriodKey),
+      "not_a_number");
+}
+
+// Test case for invalid update-period attribute of app-widget element.
+// The value must be not less than 1800.
+TEST_F(TizenAppWidgetHandlerTest, InvalidUpdatePeriodOutOfDomain) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kTizenAppWidgetUpdatePeriodKey),
+      "1799");
+}
+
+// Test case for invalid auto-launch attribute of app-widget element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidAutoLaunch) {
+  InvalidFieldValueTest(
+      MakeAppWidgetPath(keys::kTizenAppWidgetAutoLaunchKey),
+      "not_true_nor_false");
+}
+
+// Test case for invalid namespace attribute of box-label element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidLabelNamespace) {
+  InvalidFieldValueTest(
+      MakeBoxLabelPath(0, keys::kNamespaceKey),
+      "not_a_tizen_namespace");
+}
+
+// Test case for invalid namespace attribute of box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidIconNamespace) {
+  InvalidFieldValueTest(
+      MakeBoxIconPath(keys::kNamespaceKey),
+      "not_a_tizen_namespace");
+}
+
+// Test case for invalid namespace attribute of box-content element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidContentNamespace) {
+  InvalidFieldValueTest(
+      MakeBoxContentPath(keys::kNamespaceKey),
+      "not_a_tizen_namespace");
+}
+
+// Test case for invalid mouse-event attribute of box-content element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidMouseEvent) {
+  InvalidFieldValueTest(
+      MakeBoxContentPath(keys::kTizenAppWidgetBoxContentMouseEventKey),
+      "not_true_nor_false");
+}
+
+// Test case for invalid touch-effect attribute of box-content element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidTouchEffect) {
+  InvalidFieldValueTest(
+      MakeBoxContentPath(keys::kTizenAppWidgetBoxContentTouchEffectKey),
+      "not_true_nor_false");
+}
+
+// Test case for invalid namespace attribute of box-size element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidSizeNamespace) {
+  InvalidFieldValueTest(
+      MakeSizePath(0, keys::kNamespaceKey),
+      "not_a_tizen_namespace");
+}
+
+// Test case for invalid text value of box-size element.
+// The value must be one of these: 1x1, 2x1, 2x2.
+TEST_F(TizenAppWidgetHandlerTest, InvalidSize) {
+  InvalidFieldValueTest(
+      MakeSizePath(0, keys::kTizenAppWidgetBoxContentSizeTextKey),
+      "AxB");
+}
+
+// Test case for invalid use-decoration attribute of box-size element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidUseDecoration) {
+  InvalidFieldValueTest(
+      MakeSizePath(2, keys::kTizenAppWidgetBoxContentSizeUseDecorationKey),
+      "not_true_nor_false");
+}
+
+// Test case for invalid namespace attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidDropViewNamespace) {
+  InvalidFieldValueTest(
+      MakeDropViewPath(keys::kNamespaceKey),
+      "not_a_tizen_namespace");
+}
+
+// Test case for invalid width attribute of pd element.
+// The value must be integer.
+TEST_F(TizenAppWidgetHandlerTest, InvalidWidth) {
+  InvalidFieldValueTest(
+      MakeDropViewPath(keys::kTizenAppWidgetBoxContentDropViewWidthKey),
+      "not_a_number");
+}
+
+// Test case for invalid height attribute of pd element.
+// The value must be integer.
+TEST_F(TizenAppWidgetHandlerTest, InvalidHeight) {
+  InvalidFieldValueTest(
+      MakeDropViewPath(keys::kTizenAppWidgetBoxContentDropViewHeightKey),
+      "not_a_number");
+}
+
+// Test case for invalid height attribute of pd element.
+// The value must be in a range of [1, 380].
+TEST_F(TizenAppWidgetHandlerTest, InvalidHeightOutOfDomain) {
+  InvalidFieldValueTest(
+      MakeDropViewPath(keys::kTizenAppWidgetBoxContentDropViewHeightKey),
+      "381");
+}
+
+// Test case for more than one box-content element.
+TEST_F(TizenAppWidgetHandlerTest, TwoContents) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_ptr<base::DictionaryValue> app_widget =
+      CreateFullAppWidget("first", "true");
+
+  scoped_ptr<base::DictionaryValue> box_content =
+      CreateBoxContent("index.html");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+      CreateBoxSize("1x1"), box_content.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentKey,
+      box_content.Pass(), app_widget.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_EQ(nullptr, application.get());
+}
+
+// Test case for more than one box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, TwoIcons) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_ptr<base::DictionaryValue> app_widget =
+      CreateFullAppWidget("first", "true");
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetBoxIconKey,
+      CreateBoxIcon("icon.png"), app_widget.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_EQ(nullptr, application.get());
+}
+
+// Test case for more than one pd element.
+TEST_F(TizenAppWidgetHandlerTest, TwoDropViews) {
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+  scoped_ptr<base::DictionaryValue> app_widget =
+      CreateFullAppWidget("first", "true");
+
+  CHECK(AddDictionary(
+      MakeElementPath(keys::kTizenAppWidgetBoxContentKey,
+          keys::kTizenAppWidgetBoxContentDropViewKey),
+      CreateBoxDropView("index.html", "720", "150"), app_widget.get()));
+
+  CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+      app_widget.Pass(), manifest.get()));
+
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+  EXPECT_EQ(nullptr, application.get());
+}
+
+}  // namespace application
+}  // namespace xwalk
index 64c6171..6401d10 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "xwalk/application/common/manifest_handlers/unittest_util.h"
 
-#include <string>
+#include "base/strings/string_util.h"
 #include "xwalk/application/common/application_manifest_constants.h"
 
 namespace xwalk {
@@ -16,28 +16,49 @@ namespace application {
 
 namespace {
 
-const char kDefaultVersion[] = "0";
-const char kDefaultName[] = "no name";
+// Makes a path to widget.element.
+std::string MakeWidgetPath(const std::string& element) {
+  return MakeElementPath(widget_keys::kWidgetKey, element);
+}
 
 #if defined(OS_TIZEN)
 
-const char kDefaultPackageId[] = "abcdefghij";
-const char kDefaultApplicationName[] = "noname";
-const char kDefaultRequiredVersion[] = "0";
-
-#endif  // defined(OS_TIZEN)
+// Makes a path to widget.application.element.
+std::string MakeApplicationPath(const std::string& element) {
+  return MakeElementPath(widget_keys::kTizenApplicationKey, element);
+}
 
-std::string DotConnect(const std::string& first, const std::string& second) {
-  return first + '.' + second;
+// Creates an app-widget element id basing on values of default package id
+// and default application name.
+std::string GetDefaultApplicationId() {
+  std::vector<std::string> parts;
+  parts.push_back(kDefaultWidgetPackageId);
+  parts.push_back(kDefaultWidgetApplicationName);
+  return JoinString(parts, '.');
 }
 
+#endif  // defined(OS_TIZEN)
+
 }  // namespace
 
+const char kDefaultManifestName[] = "no name";
+const char kDefaultManifestVersion[] = "0";
+const char kDefaultWidgetName[] = "no name";
+const char kDefaultWidgetVersion[] = "0";
+
+#if defined(OS_TIZEN)
+
+const char kDefaultWidgetPackageId[] = "abcdefghij";
+const char kDefaultWidgetApplicationName[] = "noname";
+const char kDefaultWidgetRequiredVersion[] = "0";
+
+#endif  // defined(OS_TIZEN)
+
 scoped_ptr<base::DictionaryValue> CreateDefaultManifestConfig() {
   scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue());
 
-  manifest->SetString(manifest_keys::kXWalkVersionKey, kDefaultVersion);
-  manifest->SetString(manifest_keys::kNameKey, kDefaultName);
+  manifest->SetString(manifest_keys::kXWalkVersionKey, kDefaultManifestVersion);
+  manifest->SetString(manifest_keys::kNameKey, kDefaultManifestName);
 
   return manifest.Pass();
 }
@@ -47,32 +68,27 @@ scoped_ptr<base::DictionaryValue> CreateDefaultWidgetConfig() {
 
   // widget attributes
 
-  manifest->SetString(
-      DotConnect(widget_keys::kWidgetKey, widget_keys::kNamespaceKey),
-      widget_keys::kWidgetNamespacePrefix);
-  manifest->SetString(widget_keys::kVersionKey, kDefaultVersion);
-  manifest->SetString(widget_keys::kNameKey, kDefaultName);
+  manifest->SetString(MakeWidgetPath(widget_keys::kNamespaceKey),
+                      widget_keys::kWidgetNamespacePrefix);
+  manifest->SetString(widget_keys::kVersionKey, kDefaultWidgetVersion);
+  manifest->SetString(widget_keys::kNameKey, kDefaultWidgetName);
 
 #if defined(OS_TIZEN)
 
   // widget.application attributes
 
   manifest->SetString(
-      DotConnect(widget_keys::kTizenApplicationKey,
-                 widget_keys::kNamespaceKey),
+      MakeApplicationPath(widget_keys::kNamespaceKey),
       widget_keys::kTizenNamespacePrefix);
   manifest->SetString(
-      DotConnect(widget_keys::kTizenApplicationKey,
-                 widget_keys::kTizenApplicationIdKey),
-      DotConnect(kDefaultPackageId, kDefaultApplicationName));
+      MakeApplicationPath(widget_keys::kTizenApplicationIdKey),
+      GetDefaultApplicationId());
   manifest->SetString(
-      DotConnect(widget_keys::kTizenApplicationKey,
-                 widget_keys::kTizenApplicationPackageKey),
-      kDefaultPackageId);
+      MakeApplicationPath(widget_keys::kTizenApplicationPackageKey),
+      kDefaultWidgetPackageId);
   manifest->SetString(
-      DotConnect(widget_keys::kTizenApplicationKey,
-                 widget_keys::kTizenApplicationRequiredVersionKey),
-      kDefaultRequiredVersion);
+      MakeApplicationPath(widget_keys::kTizenApplicationRequiredVersionKey),
+      kDefaultWidgetRequiredVersion);
 
 #endif
 
@@ -89,5 +105,41 @@ scoped_refptr<ApplicationData> CreateApplication(Manifest::Type type,
   return application;
 }
 
+std::string MakeElementPath(const std::string& parent,
+    const std::string& element) {
+  std::vector<std::string> parts;
+  parts.push_back(parent);
+  parts.push_back(element);
+  return JoinString(parts, '.');
+}
+
+bool AddDictionary(const std::string& key,
+    scoped_ptr<base::DictionaryValue> child, base::DictionaryValue* parent) {
+  if (key.empty() || !child || !parent)
+    return false;
+
+  scoped_ptr<base::Value> existing_child;
+  base::DictionaryValue* unused;
+  if (parent->GetDictionary(key, &unused)) {
+    if (!parent->Remove(key, &existing_child))
+      return false;
+  }
+
+  if (existing_child) {
+    scoped_ptr<base::ListValue> list(new base::ListValue);
+    list->Set(list->GetSize(), existing_child.release());
+    list->Set(list->GetSize(), child.release());
+    parent->Set(key, list.release());
+  } else {
+    base::ListValue* list;
+    if (parent->GetList(key, &list))
+      list->Set(list->GetSize(), child.release());
+    else
+      parent->Set(key, child.release());
+  }
+
+  return true;
+}
+
 }  // namespace application
 }  // namespace xwalk
index a921cbf..b53ac2a 100644 (file)
@@ -5,6 +5,8 @@
 #ifndef XWALK_APPLICATION_COMMON_MANIFEST_HANDLERS_UNITTEST_UTIL_H_
 #define XWALK_APPLICATION_COMMON_MANIFEST_HANDLERS_UNITTEST_UTIL_H_
 
+#include <string>
+#include <vector>
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
 namespace xwalk {
 namespace application {
 
+extern const char kDefaultManifestName[];
+extern const char kDefaultManifestVersion[];
+extern const char kDefaultWidgetName[];
+extern const char kDefaultWidgetVersion[];
+
+#if defined(OS_TIZEN)
+
+extern const char kDefaultWidgetPackageId[];
+extern const char kDefaultWidgetApplicationName[];
+extern const char kDefaultWidgetRequiredVersion[];
+
+#endif  // defined(OS_TIZEN)
+
+// Creates a minimal valid manifest configuration.
 scoped_ptr<base::DictionaryValue> CreateDefaultManifestConfig();
+
+// Creates a minimal valid widget configuration.
 scoped_ptr<base::DictionaryValue> CreateDefaultWidgetConfig();
 
+// Creates an ApplicationData for specified configuration data.
 scoped_refptr<ApplicationData> CreateApplication(Manifest::Type type,
     const base::DictionaryValue& manifest);
 
+// Creates a path to element under parent element.
+// For example, calling MakePath("a.b", "c") produces "a.b.c".
+std::string MakeElementPath(const std::string& parent,
+    const std::string& element);
+
+// In a parent dictionary adds a child dictionary under a specified key.
+// If it is a first dictionary under the key, it is added as dictionary
+// directly, otherwise it is added as another dictionary in a list of
+// dictionaries. If parent is null, it does nothing.
+bool AddDictionary(const std::string& key,
+    scoped_ptr<base::DictionaryValue> child, base::DictionaryValue* parent);
+
 }  // namespace application
 }  // namespace xwalk
 
index c5aa5b3..50a7e7e 100644 (file)
@@ -169,7 +169,10 @@ bool WidgetHandler::Validate(
   const Manifest* manifest = application->GetManifest();
   DCHECK(manifest);
   std::string ns_value;
-  manifest->GetString(keys::kWidgetNamespaceKey, &ns_value);
+  if (!manifest->GetString(keys::kWidgetNamespaceKey, &ns_value)) {
+    *error = std::string("Failed to retrieve the widget's namespace.");
+    return false;
+  }
   if (base::strcasecmp(keys::kWidgetNamespacePrefix, ns_value.c_str()) != 0) {
     *error = std::string("The widget namespace is invalid.");
     return false;
index b750627..ffc23b7 100644 (file)
@@ -1,11 +1,13 @@
 // Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd 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/manifest_handlers/widget_handler.h"
-
-#include "xwalk/application/common/application_manifest_constants.h"
+#include "base/memory/scoped_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "xwalk/application/common/application_manifest_constants.h"
+#include "xwalk/application/common/manifest_handlers/unittest_util.h"
+#include "xwalk/application/common/manifest_handlers/widget_handler.h"
 
 namespace xwalk {
 
@@ -47,89 +49,90 @@ const char width[] = "480";
 const char* preferencesName[] = {"pname0", "pname1", "pname2"};
 const char* preferencesValue[] = {"pvalue0", "pvalue1", "pvalue2"};
 const char* preferencesReadonly[] = {"true", "false", "false"};
-}  // namespace
 
-class WidgetHandlerTest: public testing::Test {
- public:
-  scoped_refptr<ApplicationData> CreateApplication(
-    const base::DictionaryValue& manifest) {
-    std::string error;
-    scoped_refptr<ApplicationData> application = ApplicationData::Create(
-        base::FilePath(), std::string(), ApplicationData::LOCAL_DIRECTORY,
-        make_scoped_ptr(new Manifest(make_scoped_ptr(manifest.DeepCopy()),
-                                     Manifest::TYPE_WIDGET)),
-        &error);
-    return application;
-  }
+WidgetInfo* GetWidgetInfo(scoped_refptr<ApplicationData> application) {
+  WidgetInfo* info = static_cast<WidgetInfo*>(
+    application->GetManifestData(keys::kWidgetKey));
+  return info;
+}
 
-  WidgetInfo* GetWidgetInfo(scoped_refptr<ApplicationData> application) {
-    WidgetInfo* info = static_cast<WidgetInfo*>(
-      application->GetManifestData(keys::kWidgetKey));
-    return info;
-  }
+template <Manifest::Type type>
+base::DictionaryValue* GetPreferencesItem(int id) {
+  NOTREACHED() << "Use one of already defined template specializations"
+                  " or define a new one.";
+  return nullptr;
+}
 
-  base::DictionaryValue* GetPreferencesItem(int id,
-                                            bool is_parsed_manifest_key) {
-    base::DictionaryValue* preferences = new base::DictionaryValue;
-    if (is_parsed_manifest_key) {
-      preferences->SetString(keys::kPreferencesNameKey,
-                             preferencesName[id]);
-      preferences->SetString(keys::kPreferencesValueKey,
-                             preferencesValue[id]);
-      // PreferencesReadonly is string on manifest and bool on widgetInfo
-      preferences->SetString(keys::kPreferencesReadonlyKey,
-                             preferencesReadonly[id]);
-    } else {
-      preferences->SetString(kWidgetPreferencesName,
-                             preferencesName[id]);
-      preferences->SetString(kWidgetPreferencesValue,
-                             preferencesValue[id]);
-      preferences->SetBoolean(kWidgetPreferencesReadonly,
-                              strncmp(preferencesReadonly[id], "true", 4) == 0);
-    }
-    return preferences;
-  }
+template <>
+base::DictionaryValue* GetPreferencesItem<Manifest::TYPE_MANIFEST>(int id) {
+  base::DictionaryValue* preferences = new base::DictionaryValue;
 
-  // No Preferences and full other information
-  void SetAllInfoToManifest(base::DictionaryValue* manifest) {
-    // Insert some key-value pairs into manifest use full key
-    manifest->SetString(keys::kWidgetNamespaceKey,
-                        keys::kWidgetNamespacePrefix);
-    manifest->SetString(keys::kAuthorKey,      author);
-    manifest->SetString(keys::kDescriptionKey, decription);
-    manifest->SetString(keys::kNameKey,        name);
-    manifest->SetString(keys::kShortNameKey,   shortName);
-    manifest->SetString(keys::kVersionKey,     version);
-    manifest->SetString(keys::kIDKey,          ID);
-    manifest->SetString(keys::kAuthorEmailKey, authorEmail);
-    manifest->SetString(keys::kAuthorHrefKey,  authorHref);
-    manifest->SetString(keys::kHeightKey,      height);
-    manifest->SetString(keys::kWidthKey,       width);
-  }
+  preferences->SetString(keys::kPreferencesNameKey,
+                         preferencesName[id]);
+  preferences->SetString(keys::kPreferencesValueKey,
+                         preferencesValue[id]);
+  // PreferencesReadonly is string on manifest and bool on widgetInfo
+  preferences->SetString(keys::kPreferencesReadonlyKey,
+                         preferencesReadonly[id]);
 
-  // No Preferences and full other information
-  void SetAllInfoToWidget(base::DictionaryValue* widget) {
-    // Insert some key-value pairs into widget use widget key;
-    widget->SetString(kWidgetAuthor,      author);
-    widget->SetString(kWidgetDecription,  decription);
-    widget->SetString(kWidgetName,        name);
-    widget->SetString(kWidgetShortName,   shortName);
-    widget->SetString(kWidgetVersion,     version);
-    widget->SetString(kWidgetID,          ID);
-    widget->SetString(kWidgetAuthorEmail, authorEmail);
-    widget->SetString(kWidgetAuthorHref,  authorHref);
-    widget->SetString(kWidgetHeight,      height);
-    widget->SetString(kWidgetWidth,       width);
-  }
+  return preferences;
+}
+
+template <>
+base::DictionaryValue* GetPreferencesItem<Manifest::TYPE_WIDGET>(int id) {
+  base::DictionaryValue* preferences = new base::DictionaryValue;
+
+  preferences->SetString(kWidgetPreferencesName,
+                         preferencesName[id]);
+  preferences->SetString(kWidgetPreferencesValue,
+                         preferencesValue[id]);
+  preferences->SetBoolean(kWidgetPreferencesReadonly,
+                          strncmp(preferencesReadonly[id], "true", 4) == 0);
+  return preferences;
+}
+
+// No Preferences and full other information
+void SetAllInfoToManifest(base::DictionaryValue* manifest) {
+  // Insert some key-value pairs into manifest use full key
+  manifest->SetString(keys::kWidgetNamespaceKey,
+                      keys::kWidgetNamespacePrefix);
+  manifest->SetString(keys::kAuthorKey,      author);
+  manifest->SetString(keys::kDescriptionKey, decription);
+  manifest->SetString(keys::kNameKey,        name);
+  manifest->SetString(keys::kShortNameKey,   shortName);
+  manifest->SetString(keys::kVersionKey,     version);
+  manifest->SetString(keys::kIDKey,          ID);
+  manifest->SetString(keys::kAuthorEmailKey, authorEmail);
+  manifest->SetString(keys::kAuthorHrefKey,  authorHref);
+  manifest->SetString(keys::kHeightKey,      height);
+  manifest->SetString(keys::kWidthKey,       width);
+}
+
+// No Preferences and full other information
+void SetAllInfoToWidget(base::DictionaryValue* widget) {
+  // Insert some key-value pairs into widget use widget key;
+  widget->SetString(kWidgetAuthor,      author);
+  widget->SetString(kWidgetDecription,  decription);
+  widget->SetString(kWidgetName,        name);
+  widget->SetString(kWidgetShortName,   shortName);
+  widget->SetString(kWidgetVersion,     version);
+  widget->SetString(kWidgetID,          ID);
+  widget->SetString(kWidgetAuthorEmail, authorEmail);
+  widget->SetString(kWidgetAuthorHref,  authorHref);
+  widget->SetString(kWidgetHeight,      height);
+  widget->SetString(kWidgetWidth,       width);
+}
+
+}  // namespace
+
+class WidgetHandlerTest: public testing::Test {
 };
 
 TEST_F(WidgetHandlerTest, ParseManifestWithOnlyNameAndVersion) {
-  base::DictionaryValue manifest;
-  manifest.SetString(keys::kWidgetNamespaceKey, keys::kWidgetNamespacePrefix);
-  manifest.SetString(keys::kNameKey, "no name");
-  manifest.SetString(keys::kVersionKey, "0");
-
-  scoped_refptr<ApplicationData> application = CreateApplication(manifest);
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+  manifest->SetString(keys::kWidgetNamespaceKey, keys::kWidgetNamespacePrefix);
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
   EXPECT_TRUE(application.get());
 
   WidgetInfo* info = GetWidgetInfo(application);
@@ -160,26 +163,28 @@ TEST_F(WidgetHandlerTest, ParseManifestWithOnlyNameAndVersion) {
 TEST_F(WidgetHandlerTest,
        ParseManifestWithAllOfOtherItemsAndOnePreferenceItem) {
   // Create a manifest with one preference item.
-  scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
   SetAllInfoToManifest(manifest.get());
-  manifest->Set(keys::kPreferencesKey, GetPreferencesItem(0, true));
+  manifest->Set(keys::kPreferencesKey,
+                GetPreferencesItem<Manifest::TYPE_MANIFEST>(0));
   // Create an application use this manifest.
-  scoped_refptr<ApplicationData> application;
-  application = CreateApplication(*(manifest.get()));
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_EQ(application->manifest_type(), Manifest::TYPE_WIDGET);
   // Get widget info from this application.
   WidgetInfo* info = GetWidgetInfo(application);
   EXPECT_TRUE(info);
-  scoped_ptr<base::DictionaryValue> Copy(info->GetWidgetInfo()->DeepCopy());
+  scoped_ptr<base::DictionaryValue>
+      deep_copy(info->GetWidgetInfo()->DeepCopy());
   base::DictionaryValue* widget_parsed_from_manifest;
-  Copy->GetAsDictionary(&widget_parsed_from_manifest);
-  EXPECT_TRUE(widget_parsed_from_manifest);
+  EXPECT_TRUE(deep_copy->GetAsDictionary(&widget_parsed_from_manifest));
 
   // Create a widget with one preference item manually.
   scoped_ptr<base::DictionaryValue> widget(new base::DictionaryValue);
   SetAllInfoToWidget(widget.get());
-  widget->Set(kWidgetPreferences, GetPreferencesItem(0, false));
+  widget->Set(kWidgetPreferences,
+              GetPreferencesItem<Manifest::TYPE_WIDGET>(0));
 
   // Compare the widget parsed from manifest with
   // the widget create manually.
@@ -189,31 +194,32 @@ TEST_F(WidgetHandlerTest,
 TEST_F(WidgetHandlerTest,
        ParseManifestWithAllOfOtherItemsAndThreePreferenceItemsList) {
   // Create a manifest with three preference items.
-  scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
   SetAllInfoToManifest(manifest.get());
   base::ListValue* manifestPreferences = new base::ListValue;
   for (int i = 0; i < 3; i++) {
-    manifestPreferences->Append(GetPreferencesItem(i, true));
+    manifestPreferences->Append(GetPreferencesItem<Manifest::TYPE_MANIFEST>(i));
   }
+  // TODO(aszafranek): Set manifestPreferences to manifest and test it below
   // Create an application use this manifest,
-  scoped_refptr<ApplicationData> application;
-  application = CreateApplication(*(manifest.get()));
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_EQ(application->manifest_type(), Manifest::TYPE_WIDGET);
   // Get widget info from this application.
   WidgetInfo* info = GetWidgetInfo(application);
   EXPECT_TRUE(info);
-  scoped_ptr<base::DictionaryValue> Copy(info->GetWidgetInfo()->DeepCopy());
+  scoped_ptr<base::DictionaryValue>
+      deep_copy(info->GetWidgetInfo()->DeepCopy());
   base::DictionaryValue* widget_parsed_from_manifest;
-  Copy->GetAsDictionary(&widget_parsed_from_manifest);
-  EXPECT_TRUE(widget_parsed_from_manifest);
+  EXPECT_TRUE(deep_copy->GetAsDictionary(&widget_parsed_from_manifest));
 
   // Create a widget with three preference items manually.
   scoped_ptr<base::DictionaryValue> widget(new base::DictionaryValue);
   SetAllInfoToWidget(widget.get());
-  base::ListValue* widgetPreferences   = new base::ListValue;
+  base::ListValue* widgetPreferences = new base::ListValue;
   for (int i = 0; i < 3; i++) {
-    widgetPreferences->Append(GetPreferencesItem(i, false));
+    widgetPreferences->Append(GetPreferencesItem<Manifest::TYPE_WIDGET>(i));
   }
 
   // Compare the widget parsed from manifest with
@@ -223,13 +229,13 @@ TEST_F(WidgetHandlerTest,
 
 TEST_F(WidgetHandlerTest,
        ParseManifestWithInvalidAuthorHrefValue) {
-  scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
+  scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
   SetAllInfoToManifest(manifest.get());
   manifest->SetString(keys::kAuthorHrefKey, "INVALID_HREF");
 
   // Create an application use this manifest,
-  scoped_refptr<ApplicationData> application;
-  application = CreateApplication(*(manifest.get()));
+  scoped_refptr<ApplicationData> application =
+      CreateApplication(Manifest::TYPE_WIDGET, *manifest);
   EXPECT_TRUE(application.get());
   EXPECT_EQ(application->manifest_type(), Manifest::TYPE_WIDGET);
   // Get widget info from this application.
@@ -239,5 +245,6 @@ TEST_F(WidgetHandlerTest,
   info->GetWidgetInfo()->GetString(keys::kAuthorHrefKey, &authorhref);
   EXPECT_TRUE(authorhref.empty());
 }
+
 }  // namespace application
 }  // namespace xwalk
index 17c09d4..4f04268 100644 (file)
@@ -26,6 +26,7 @@ XPKPackage::~XPKPackage() {
 
 XPKPackage::XPKPackage(const base::FilePath& path)
     : Package(path, Manifest::TYPE_MANIFEST),
+      header_(),
       zip_addr_(0) {
   if (!base::PathExists(path))
     return;
index 5548b2a..c9226ca 100644 (file)
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-var application = requireNative('application');
 var common = requireNative('widget_common');
 
 var empty = "";
@@ -45,9 +44,6 @@ for (var key in widgetStringInfo) {
 }
 
 var WidgetStorage = function() {
-  var _keyList = new Array();
-  var _itemStorage = new Object();
-
   var _SetItem = function(itemKey, itemValue) {
     var result = extension.internal.sendSyncMessage({
         cmd: 'SetPreferencesItem',
@@ -55,9 +51,6 @@ var WidgetStorage = function() {
         preferencesItemValue: String(itemValue) });
 
     if (result) {
-      if (_itemStorage[String(itemKey)] == undefined)
-        _keyList.push(String(itemKey));
-      _itemStorage[String(itemKey)] = String(itemValue);
       return itemValue;
     } else {
       throw new common.CustomDOMException(
@@ -76,33 +69,36 @@ var WidgetStorage = function() {
   var _GetGetter = function(itemKey) {
     var _itemKey = itemKey;
     return function() {
-      return _itemStorage[String(_itemKey)];
+      var result = extension.internal.sendSyncMessage(
+          { cmd: 'GetItemValueByKey',
+            preferencesItemKey: String(itemKey) });
+      return result == empty ? null : result;
     }
   }
 
   this.init = function() {
-    var result = extension.internal.sendSyncMessage(
-        { cmd: 'GetAllItems' });
+    var result = extension.internal.sendSyncMessage({cmd: 'GetAllItems'});
     for (var itemKey in result) {
-      var itemValue = result[String(itemKey)];
-      _itemStorage[String(itemKey)] = itemValue;
       this.__defineSetter__(String(itemKey), _GetSetter(itemKey));
       this.__defineGetter__(String(itemKey), _GetGetter(itemKey));
-      _keyList.push(String(itemKey));
     }
   }
 
   this.__defineGetter__('length', function() {
-    return _keyList.length;
+    var result = extension.internal.sendSyncMessage({cmd: 'GetAllItems'});
+    return Object.keys(result).length;
   });
 
   this.key = function(index) {
-    return _keyList[index];
+    var result = extension.internal.sendSyncMessage({ cmd: 'GetAllItems'});
+    return Object.keys(result)[index];
   }
 
   this.getItem = function(itemKey) {
-    var item = _itemStorage[String(itemKey)];
-    return item !== undefined ? item : null;
+    var result = extension.internal.sendSyncMessage({
+        cmd: 'GetItemValueByKey',
+        preferencesItemKey: String(itemKey)});
+    return result == empty ? null : result;
   }
 
   this.setItem = function(itemKey, itemValue) {
@@ -112,13 +108,9 @@ var WidgetStorage = function() {
   this.removeItem = function(itemKey) {
     var result = extension.internal.sendSyncMessage({
         cmd: 'RemovePreferencesItem',
-        preferencesItemKey: String(itemKey) });
+        preferencesItemKey: String(itemKey)});
 
-    if (result) {
-      delete this[itemKey];
-      delete _itemStorage[itemKey];
-      _keyList.splice(_keyList.indexOf(String(itemKey)), 1);
-    } else {
+    if (!result) {
       throw new common.CustomDOMException(
           common.CustomDOMException.NO_MODIFICATION_ALLOWED_ERR,
           'The object can not be modified.');
@@ -126,26 +118,7 @@ var WidgetStorage = function() {
   }
 
   this.clear = function() {
-    var itemKey;
-    var result = extension.internal.sendSyncMessage({
-        cmd: 'ClearAllItems' });
-
-    if (!result)
-      return;
-
-    for (var i = _keyList.length-1; i >= 0; --i) {
-      // if the itemKey is still in DB(e.g. readonly),
-      // we should keep it in JS side.
-      var exists = extension.internal.sendSyncMessage({
-          cmd: 'KeyExists',
-          preferencesItemKey: _keyList[i] });
-
-      if (!exists) {
-        delete this[_keyList[i]];
-        delete _itemStorage[_keyList[i]];
-        _keyList.splice(i, 1);
-      }
-    }
+    extension.internal.sendSyncMessage({cmd: 'ClearAllItems'});
   }
 
   this.init();
index af28a65..fb94b01 100644 (file)
@@ -4,10 +4,15 @@
 
 #include "xwalk/application/extension/application_widget_extension.h"
 
+#include <vector>
+
 #include "base/bind.h"
 #include "base/path_service.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 using content::BrowserThread;
 
 namespace {
+
 const char kCommandKey[] = "cmd";
 const char kWidgetAttributeKey[] = "widgetKey";
 const char kPreferencesItemKey[] = "preferencesItemKey";
 const char kPreferencesItemValue[] = "preferencesItemValue";
+
+void DispatchStorageEvent(
+    base::DictionaryValue* msg,
+    content::WebContents* web_contents,
+    content::RenderFrameHost* frame) {
+  if (frame == web_contents->GetFocusedFrame())
+    return;
+
+  std::string key, oldValue, newValue;
+  msg->GetString("key", &key);
+  msg->GetString("oldValue", &oldValue);
+  msg->GetString("newValue", &newValue);
+
+  std::string code = base::StringPrintf(
+      "(function() {"
+      "  var old_value = '%s' == '' ? null : '%s';"
+      "  var new_value = '%s' == '' ? null : '%s';"
+      "  var event = {"
+      "    key: '%s',"
+      "    oldValue: old_value,"
+      "    newValue: new_value,"
+      "    url: window.location.href,"
+      "    storageArea: widget.preferences"
+      "  };"
+      "  for (var key in event) {"
+      "    Object.defineProperty(event, key, {"
+      "      value: event[key],"
+      "      writable: false"
+      "    });"
+      "  }"
+      "  for (var i = 0; i < window.eventListenerList.length; i++)"
+      "    window.eventListenerList[i](event);"
+      "})();", oldValue.c_str(), oldValue.c_str(),
+      newValue.c_str(), newValue.c_str(), key.c_str());
+
+  frame->ExecuteJavaScript(base::UTF8ToUTF16(code));
 }
 
+}  // namespace
+
 namespace xwalk {
 namespace application {
 
@@ -52,8 +96,7 @@ XWalkExtensionInstance* ApplicationWidgetExtension::CreateInstance() {
 
 AppWidgetExtensionInstance::AppWidgetExtensionInstance(
     Application* application)
-  : application_(application),
-    handler_(this) {
+  : application_(application) {
   DCHECK(application_);
   base::ThreadRestrictions::SetIOAllowed(true);
 
@@ -68,7 +111,6 @@ AppWidgetExtensionInstance::AppWidgetExtensionInstance(
 AppWidgetExtensionInstance::~AppWidgetExtensionInstance() {}
 
 void AppWidgetExtensionInstance::HandleMessage(scoped_ptr<base::Value> msg) {
-  handler_.HandleMessage(msg.Pass());
 }
 
 void AppWidgetExtensionInstance::HandleSyncMessage(
@@ -94,6 +136,8 @@ void AppWidgetExtensionInstance::HandleSyncMessage(
     result = ClearAllItems(msg.Pass());
   } else if (command == "GetAllItems") {
     result = GetAllItems(msg.Pass());
+  } else if (command == "GetItemValueByKey") {
+    result = GetItemValueByKey(msg.Pass());
   } else if (command == "KeyExists") {
     result = KeyExists(msg.Pass());
   } else {
@@ -140,9 +184,26 @@ AppWidgetExtensionInstance::SetPreferencesItem(scoped_ptr<base::Value> msg) {
     return result.Pass();
   }
 
-  if (widget_storage_->AddEntry(key, value, false))
+  std::string old_value;
+  if (!widget_storage_->GetValueByKey(key, &old_value)) {
+    old_value = "";
+  }
+  if (old_value == value) {
+    LOG(WARNING) << "You are trying to set the same value."
+                 << " Nothing will be done.";
+    result.reset(new base::FundamentalValue(true));
+    return result.Pass();
+  }
+  if (widget_storage_->AddEntry(key, value, false)) {
     result.reset(new base::FundamentalValue(true));
 
+    scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue());
+    event->SetString("key", key);
+    event->SetString("oldValue", old_value);
+    event->SetString("newValue", value);
+    PostMessageToOtherFrames(event.Pass());
+  }
+
   return result.Pass();
 }
 
@@ -159,8 +220,23 @@ AppWidgetExtensionInstance::RemovePreferencesItem(scoped_ptr<base::Value> msg) {
     return result.Pass();
   }
 
-  if (widget_storage_->RemoveEntry(key))
+  std::string old_value;
+  if (!widget_storage_->GetValueByKey(key, &old_value)) {
+    LOG(WARNING) << "You are trying to remove an entry which doesn't exist."
+                 << " Nothing will be done.";
     result.reset(new base::FundamentalValue(true));
+    return result.Pass();
+  }
+
+  if (widget_storage_->RemoveEntry(key)) {
+    result.reset(new base::FundamentalValue(true));
+
+    scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue());
+    event->SetString("key", key);
+    event->SetString("oldValue", old_value);
+    event->SetString("newValue", "");
+    PostMessageToOtherFrames(event.Pass());
+  }
 
   return result.Pass();
 }
@@ -170,9 +246,27 @@ scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::ClearAllItems(
   scoped_ptr<base::FundamentalValue> result(
       new base::FundamentalValue(false));
 
-  if (widget_storage_->Clear())
-    result.reset(new base::FundamentalValue(true));
+  scoped_ptr<base::DictionaryValue> entries(new base::DictionaryValue());
+  widget_storage_->GetAllEntries(entries.get());
 
+  if (!widget_storage_->Clear())
+    return result.Pass();
+
+  for (base::DictionaryValue::Iterator it(*(entries.get()));
+      !it.IsAtEnd(); it.Advance()) {
+    std::string key = it.key();
+    if (!widget_storage_->EntryExists(key)) {
+      std::string old_value;
+      it.value().GetAsString(&old_value);
+      scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue());
+      event->SetString("key", key);
+      event->SetString("oldValue", old_value);
+      event->SetString("newValue", "");
+      PostMessageToOtherFrames(event.Pass());
+    }
+  }
+
+  result.reset(new base::FundamentalValue(true));
   return result.Pass();
 }
 
@@ -184,6 +278,20 @@ scoped_ptr<base::DictionaryValue> AppWidgetExtensionInstance::GetAllItems(
   return result.Pass();
 }
 
+scoped_ptr<base::StringValue> AppWidgetExtensionInstance::GetItemValueByKey(
+    scoped_ptr<base::Value> msg) {
+  base::DictionaryValue* dict;
+  msg->GetAsDictionary(&dict);
+
+  std::string key;
+  std::string value;
+  if (!dict->GetString(kPreferencesItemKey, &key) ||
+      !widget_storage_->GetValueByKey(key, &value))
+    value = "";
+  scoped_ptr<base::StringValue> result(new base::StringValue(value));
+  return result.Pass();
+}
+
 scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::KeyExists(
     scoped_ptr<base::Value> msg) const {
   scoped_ptr<base::FundamentalValue> result(
@@ -203,5 +311,17 @@ scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::KeyExists(
   return result.Pass();
 }
 
+void AppWidgetExtensionInstance::PostMessageToOtherFrames(
+    scoped_ptr<base::DictionaryValue> msg) {
+  const std::vector<Runtime*>& runtime_set = application_->runtimes();
+  std::vector<Runtime*>::const_iterator it;
+  for (it = runtime_set.begin(); it != runtime_set.end(); ++it) {
+    content::WebContents* web_contents = (*it)->web_contents();
+    web_contents->ForEachFrame(base::Bind(&DispatchStorageEvent,
+                                          msg.get(),
+                                          web_contents));
+  }
+}
+
 }  // namespace application
 }  // namespace xwalk
index b37ddc4..4e44851 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "xwalk/extensions/browser/xwalk_extension_function_handler.h"
 #include "xwalk/extensions/common/xwalk_extension.h"
 
 namespace xwalk {
@@ -15,8 +14,6 @@ namespace application {
 class Application;
 
 using extensions::XWalkExtension;
-using extensions::XWalkExtensionFunctionHandler;
-using extensions::XWalkExtensionFunctionInfo;
 using extensions::XWalkExtensionInstance;
 
 class ApplicationWidgetExtension : public XWalkExtension {
@@ -46,12 +43,13 @@ class AppWidgetExtensionInstance : public XWalkExtensionInstance {
       scoped_ptr<base::Value> mgs);
   scoped_ptr<base::FundamentalValue> ClearAllItems(scoped_ptr<base::Value> mgs);
   scoped_ptr<base::DictionaryValue> GetAllItems(scoped_ptr<base::Value> mgs);
+  scoped_ptr<base::StringValue> GetItemValueByKey(scoped_ptr<base::Value> mgs);
   scoped_ptr<base::FundamentalValue> KeyExists(
       scoped_ptr<base::Value> mgs) const;
+  void PostMessageToOtherFrames(scoped_ptr<base::DictionaryValue> msg);
 
   Application* application_;
   scoped_ptr<class AppWidgetStorage> widget_storage_;
-  XWalkExtensionFunctionHandler handler_;
 };
 
 }  // namespace application
index 7dc6caa..dd95166 100644 (file)
@@ -54,6 +54,10 @@ const char kSelectCountWithBindOp[] =
 const char kSelectAllItem[] =
     "SELECT key, value FROM widget_storage ";
 
+const char kSelectValueWithBindOp[] =
+    "SELECT value FROM widget_storage "
+    "WHERE key = ?";
+
 const char kSelectReadOnlyWithBindOp[] =
     "SELECT read_only FROM widget_storage "
     "WHERE key = ?";
@@ -146,7 +150,8 @@ bool AppWidgetStorage::InitStorageTable() {
   }
 
   sql::Transaction transaction(sqlite_db_.get());
-  transaction.Begin();
+  if (!transaction.Begin())
+    return false;
   if (!sqlite_db_->Execute(kCreateStorageTableOp))
     return false;
   if (!transaction.Commit())
@@ -167,7 +172,7 @@ bool AppWidgetStorage::EntryExists(const std::string& key) const {
       kSelectCountWithBindOp));
   stmt.BindString(0, key);
   if (!stmt.Step()) {
-    LOG(ERROR) << "An error occured when selecting count from DB.";
+    LOG(ERROR) << "There is no item in current DB.";
     return false;
   }
 
@@ -181,18 +186,18 @@ bool AppWidgetStorage::EntryExists(const std::string& key) const {
 bool AppWidgetStorage::IsReadOnly(const std::string& key) {
   sql::Transaction transaction(sqlite_db_.get());
   if (!transaction.Begin())
-    return true;
+    return false;
 
   sql::Statement stmt(sqlite_db_->GetUniqueStatement(
       kSelectReadOnlyWithBindOp));
   stmt.BindString(0, key);
   if (!stmt.Step()) {
-    LOG(ERROR) << "An error occured when selecting count from DB.";
-    return true;
+    LOG(WARNING) << "The key doesn't exist or there is an error in current DB.";
+    return false;
   }
 
   if (!transaction.Commit())
-    return true;
+    return false;
 
   return stmt.ColumnBool(0);
 }
@@ -230,12 +235,36 @@ bool AppWidgetStorage::AddEntry(const std::string& key,
   return transaction.Commit();
 }
 
+bool AppWidgetStorage::GetValueByKey(const std::string& key,
+                                     std::string* value) {
+  if (!db_initialized_ && !Init())
+    return false;
+
+  sql::Transaction transaction(sqlite_db_.get());
+  if (!transaction.Begin())
+    return false;
+
+  sql::Statement stmt(sqlite_db_->GetUniqueStatement(
+      kSelectValueWithBindOp));
+  stmt.BindString(0, key);
+  if (!stmt.Step()) {
+    LOG(WARNING) << "The key doesn't exit or there is an error in current DB.";
+    return false;
+  }
+
+  if (!transaction.Commit())
+    return false;
+
+  *value = stmt.ColumnString(0);
+  return true;
+}
+
 bool AppWidgetStorage::RemoveEntry(const std::string& key) {
   if (!db_initialized_ && !Init())
     return false;
 
   if (IsReadOnly(key)) {
-    LOG(ERROR) << "Could not remove read only item " << key;
+    LOG(ERROR) << "The key is readonly or it doesn't exist." << key;
     return false;
   }
 
@@ -260,7 +289,8 @@ bool AppWidgetStorage::Clear() {
     return false;
 
   sql::Transaction transaction(sqlite_db_.get());
-  transaction.Begin();
+  if (!transaction.Begin())
+    return false;
 
   sql::Statement stmt(sqlite_db_->GetUniqueStatement(
       kClearStorageTableWithBindOp));
index ad83ed6..58412a6 100644 (file)
@@ -31,6 +31,7 @@ class AppWidgetStorage {
   bool Clear();
   bool GetAllEntries(base::DictionaryValue* result);
   bool EntryExists(const std::string& key) const;
+  bool GetValueByKey(const std::string& key, std::string* value);
 
  private:
   bool Init();
diff --git a/src/xwalk/application/tools/linux/dbus_connection.cc b/src/xwalk/application/tools/linux/dbus_connection.cc
deleted file mode 100644 (file)
index 2e7f3c3..0000000
+++ /dev/null
@@ -1,21 +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/application/tools/linux/dbus_connection.h"
-
-GDBusConnection* get_session_bus_connection(GError** error) {
-#if defined(OS_TIZEN_MOBILE)
-  // In Tizen the session bus is created in /run/user/app/dbus/user_bus_socket
-  // but this information isn't set in DBUS_SESSION_BUS_ADDRESS, neither when
-  // logging via 'sdb shell' and changing user to 'app', nor when an application
-  // is launched.
-  return g_dbus_connection_new_for_address_sync(
-      "unix:path=/run/user/app/dbus/user_bus_socket",
-      GDBusConnectionFlags(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
-                           | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
-      NULL, NULL, error);
-#else
-  return g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, error);
-#endif
-}
diff --git a/src/xwalk/application/tools/linux/dbus_connection.h b/src/xwalk/application/tools/linux/dbus_connection.h
deleted file mode 100644 (file)
index 022eee5..0000000
+++ /dev/null
@@ -1,12 +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_APPLICATION_TOOLS_LINUX_DBUS_CONNECTION_H_
-#define XWALK_APPLICATION_TOOLS_LINUX_DBUS_CONNECTION_H_
-
-#include <gio/gio.h>
-
-GDBusConnection* get_session_bus_connection(GError** error);
-
-#endif  // XWALK_APPLICATION_TOOLS_LINUX_DBUS_CONNECTION_H_
diff --git a/src/xwalk/application/tools/linux/dbus_object_manager.cc b/src/xwalk/application/tools/linux/dbus_object_manager.cc
new file mode 100644 (file)
index 0000000..feccbcc
--- /dev/null
@@ -0,0 +1,219 @@
+// 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/application/tools/linux/dbus_object_manager.h"
+
+#include "base/message_loop/message_loop.h"
+
+namespace {
+
+const char kServiceName[] = "org.crosswalkproject.Runtime1";
+const char kRunningManagerIface[] = "org.crosswalkproject.Running.Manager1";
+const char kRunningAppIface[] = "org.crosswalkproject.Running.Application1";
+const char kRunningManagerDBusPath[] = "/running1";
+const char kEPChannelCreatedSignalName[] = "EPChannelCreated";
+
+struct Properties : public dbus::PropertySet {
+  dbus::Property<std::string> app_id;
+
+  Properties(dbus::ObjectProxy* object_proxy,
+             const std::string& interface_name,
+             PropertyChangedCallback property_changed_callback)
+      : PropertySet(object_proxy, interface_name, property_changed_callback) {
+    RegisterProperty("AppID", &app_id);
+  }
+};
+
+}  // namespace
+
+DBusObjectManager::DBusObjectManager(dbus::Bus* bus,
+                                     base::MessageLoop* main_loop)
+    : bus_(bus),
+      main_loop_(main_loop),
+      weak_ptr_factory_(this) {
+  ConnectToApplicationManager();
+}
+
+bool DBusObjectManager::Launch(const std::string& appid_or_url,
+     int launcher_pid, bool fullscreen, bool remote_debugging) {
+  if (!running_proxy_)
+    return false;
+  dbus::MethodCall method_call(
+      kRunningManagerIface, "Launch");
+  dbus::MessageWriter writer(&method_call);
+  writer.AppendString(appid_or_url);
+  writer.AppendUint32(launcher_pid);
+  writer.AppendBool(fullscreen);
+  writer.AppendBool(remote_debugging);
+  scoped_ptr<dbus::Response> response(
+      running_proxy_->CallMethodAndBlock(&method_call,
+      dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
+  if (!response.get())
+    return false;
+  if (!response->GetErrorName().empty()) {
+    LOG(ERROR) << "Error during call to 'Launch': "
+               << response->GetErrorName();
+    return false;
+  }
+
+  dbus::MessageReader reader(response.get());
+  dbus::ObjectPath running_application_path;
+  if (!reader.PopObjectPath(&running_application_path)) {
+    LOG(WARNING) << "Failed to create app proxy.";
+  } else {
+    app_proxy_ = bus_->GetObjectProxy(kServiceName, running_application_path);
+    if (app_proxy_)
+      ConnectToApplicationSignal(kEPChannelCreatedSignalName);
+  }
+  return true;
+}
+
+std::pair<std::string, int> DBusObjectManager::GetEPChannel() const {
+  std::pair<std::string, int> fd;
+  if (!app_proxy_) {
+    fd.second = -1;
+    return fd;
+  }
+  dbus::MethodCall method_call(kRunningAppIface, "GetEPChannel");
+  scoped_ptr<dbus::Response> response = app_proxy_->CallMethodAndBlock(
+      &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+  const std::string& error = response->GetErrorName();
+  if (!error.empty()) {
+    LOG(ERROR) << "Error during call to 'GetEPChannel': "
+               << error;
+    fd.second = -1;
+    return fd;
+  }
+  dbus::MessageReader reader(response.release());
+  dbus::FileDescriptor extension_process_fd_;
+  if (!reader.PopString(&fd.first) ||
+      !reader.PopFileDescriptor(&extension_process_fd_)) {
+    LOG(ERROR) << "Couldn't get EP Channel";
+    fd.second = -1;
+    return fd;
+  }
+  extension_process_fd_.CheckValidity();
+  fd.second = extension_process_fd_.TakeValue();
+  return fd;
+}
+
+bool DBusObjectManager::Suspend() {
+  if (!app_proxy_)
+    return false;
+  dbus::MethodCall method_call(kRunningAppIface, "Suspend");
+  scoped_ptr<dbus::Response> response = app_proxy_->CallMethodAndBlock(
+      &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+  if (!response->GetErrorName().empty()) {
+    LOG(ERROR) << "Error during call to 'Suspend': "
+               << response->GetErrorName();
+    return false;
+  }
+  return true;
+}
+
+bool DBusObjectManager::Resume() {
+  if (!app_proxy_)
+    return false;
+  dbus::MethodCall method_call(kRunningAppIface, "Resume");
+  scoped_ptr<dbus::Response> response = app_proxy_->CallMethodAndBlock(
+      &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+  if (!response->GetErrorName().empty()) {
+    LOG(ERROR) << "Error during call to 'Resume': "
+               << response->GetErrorName();
+    return false;
+  }
+  return true;
+}
+
+void DBusObjectManager::OnOwnershipCallback(const std::string& service_name,
+                                            bool success) {
+  LOG(WARNING) << "Couldn't get ownership of D-Bus service name: "
+               << service_name << ".";
+}
+
+void DBusObjectManager::ConnectToApplicationManager() {
+  running_apps_manager_ = bus_->GetObjectManager(kServiceName,
+      dbus::ObjectPath(kRunningManagerDBusPath));
+  running_apps_manager_->RegisterInterface(kRunningAppIface, this);
+  running_proxy_ = bus_->GetObjectProxy(kServiceName,
+      dbus::ObjectPath(kRunningManagerDBusPath));
+}
+
+void DBusObjectManager::ObjectAdded(const dbus::ObjectPath& object_path,
+    const std::string& interface_name) {
+}
+
+void DBusObjectManager::ObjectRemoved(const dbus::ObjectPath& object_path,
+    const std::string& interface_name) {
+  if (object_path != app_proxy_->object_path())
+    return;
+  LOG(INFO) << "Application '" << object_path.value()
+            << "' disappeared, exiting.";
+  main_loop_->QuitNow();
+}
+
+dbus::PropertySet* DBusObjectManager::CreateProperties(
+    dbus::ObjectProxy *object_proxy,
+    const dbus::ObjectPath& object_path,
+    const std::string& interface_name) {
+  Properties* properties = new Properties(
+      object_proxy, interface_name,
+      base::Bind(&DBusObjectManager::OnPropertyChanged,
+                 base::Unretained(this), object_path));
+  return static_cast<dbus::PropertySet*>(properties);
+}
+
+void DBusObjectManager::OnPropertyChanged(const dbus::ObjectPath& object_path,
+    const std::string& name) {
+  if (!running_apps_manager_)
+    ConnectToApplicationManager();
+}
+
+void DBusObjectManager::ConnectToApplicationSignal(
+    const std::string& signal_name) {
+  DCHECK(app_proxy_);
+  app_proxy_->ConnectToSignal(kRunningAppIface, signal_name,
+      base::Bind(&DBusObjectManager::OnAppSignal,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&DBusObjectManager::OnAppSignalConnected,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+bool DBusObjectManager::IsApplicationRunning(const std::string& app_id) {
+  std::vector<dbus::ObjectPath> objects = running_apps_manager_->GetObjects();
+  bool is_running = false;
+  for (dbus::ObjectPath obj : objects) {
+    Properties* properties =
+        static_cast<Properties*>(
+            running_apps_manager_->GetProperties(
+                obj, kRunningAppIface));
+    if (!properties)
+      continue;
+    if (properties->app_id.value() == app_id) {
+      is_running = true;
+      break;
+    }
+  }
+  LOG(INFO) << "Application " << app_id << " is "
+            << (is_running ? "running." : "not running.");
+  return is_running;
+}
+
+void DBusObjectManager::OnAppSignal(dbus::Signal* signal) {
+  std::string signal_name = signal->GetMember();
+  if (signal_name == kEPChannelCreatedSignalName) {
+    if (observer_)
+      observer_->OnEPChannelCreated();
+  } else {
+    LOG(INFO) << "Unknown signal received: " << signal_name;
+  }
+}
+
+void DBusObjectManager::OnAppSignalConnected(
+    const std::string& interface_name,
+    const std::string& signal_name,
+    bool success) {
+  if (!success)
+    LOG(WARNING) << "Failed to connect signal: " << signal_name;
+}
diff --git a/src/xwalk/application/tools/linux/dbus_object_manager.h b/src/xwalk/application/tools/linux/dbus_object_manager.h
new file mode 100644 (file)
index 0000000..ccb9fb2
--- /dev/null
@@ -0,0 +1,82 @@
+// 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_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_
+#define XWALK_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/threading/thread.h"
+#include "base/values.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/message.h"
+#include "dbus/object_manager.h"
+#include "dbus/object_path.h"
+#include "dbus/object_proxy.h"
+#include "dbus/property.h"
+
+class DBusObjectManager : public dbus::ObjectManager::Interface {
+ public:
+  class Observer {
+   public:
+    virtual void OnEPChannelCreated() = 0;
+
+   protected:
+    virtual ~Observer() {}
+  };
+
+  DBusObjectManager(dbus::Bus* bus, base::MessageLoop* main_loop);
+
+  bool Launch(const std::string& appid_or_url, int launcher_pid,
+              bool fullscreen, bool remote_debugging);
+  std::pair<std::string, int> GetEPChannel() const;
+  bool Suspend();
+  bool Resume();
+
+  bool IsApplicationRunning(const std::string& app_id);
+
+  void SetObserver(Observer* observer) { observer_ = observer; }
+
+ private:
+  void OnOwnershipCallback(const std::string& service_name, bool success);
+  void ObjectAdded(const dbus::ObjectPath& object_path,
+                   const std::string& interface_name) override;
+  void ObjectRemoved(const dbus::ObjectPath& object_path,
+                     const std::string& interface_name) override;
+  dbus::PropertySet* CreateProperties(
+      dbus::ObjectProxy* object_proxy,
+      const dbus::ObjectPath& object_path,
+      const std::string& interface_name) override;
+
+  void OnPropertyChanged(const dbus::ObjectPath& object_path,
+                         const std::string& name);
+
+  void ConnectToApplicationManager();
+  void ConnectToApplicationSignal(const std::string& signal_name);
+  void OnAppSignal(dbus::Signal* signal);
+  void OnAppSignalConnected(const std::string& interface_name,
+                            const std::string& signal_name,
+                            bool success);
+
+  scoped_refptr<dbus::Bus> bus_;
+  dbus::ObjectManager* running_apps_manager_;
+  dbus::ObjectProxy* running_proxy_;
+  dbus::ObjectProxy* app_proxy_;
+
+  // this is needed for exit events which come via dbus interface
+  base::MessageLoop* main_loop_;
+
+  base::WeakPtrFactory<DBusObjectManager> weak_ptr_factory_;
+
+  Observer* observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(DBusObjectManager);
+};
+
+#endif  // XWALK_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_
index a70f1b4..e3bc48d 100644 (file)
         '../../../build/system.gyp:gio',
         '../../../extensions/extensions.gyp:xwalk_extensions',
         '../../../application/common/xwalk_application_common.gypi:xwalk_application_common_lib',
+        '../../../dbus/xwalk_dbus.gyp:xwalk_dbus'
       ],
       'sources': [
-        'dbus_connection.cc',
-        'dbus_connection.h',
+        'dbus_object_manager.cc',
+        'dbus_object_manager.h',
         'xwalk_extension_process_launcher.cc',
         'xwalk_extension_process_launcher.h',
         'xwalk_launcher_main.cc',
@@ -27,6 +28,8 @@
             '../../../build/system.gyp:tizen_appcore_common'
           ],
           'sources': [
+            'xwalk_launcher.cc',
+            'xwalk_launcher.h',
             'xwalk_launcher_tizen.cc',
             'xwalk_launcher_tizen.h',
             '../tizen/xwalk_tizen_user.cc',
@@ -61,6 +64,8 @@
             '../tizen/xwalk_tizen_user.h',
             '../../../runtime/common/xwalk_paths.cc',
             '../../../runtime/common/xwalk_paths.h',
+            '../../../runtime/common/xwalk_switches.cc',
+            '../../../runtime/common/xwalk_switches.h',
             '../../../runtime/common/xwalk_system_locale.cc',
             '../../../runtime/common/xwalk_system_locale.h',
           ],
diff --git a/src/xwalk/application/tools/linux/xwalk_launcher.cc b/src/xwalk/application/tools/linux/xwalk_launcher.cc
new file mode 100644 (file)
index 0000000..04964d5
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unistd.h>
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "dbus/object_proxy.h"
+
+#include "base/logging.h"
+
+#include "xwalk/application/tools/linux/xwalk_launcher.h"
+
+namespace {
+
+const char xwalk_service_name[] = "org.crosswalkproject.Runtime1";
+const char xwalk_running_path[] = "/running1";
+const char xwalk_running_manager_iface[] =
+    "org.crosswalkproject.Running.Manager1";
+const char xwalk_running_app_iface[] =
+    "org.crosswalkproject.Running.Application1";
+
+}  // namespace
+
+XWalkLauncher::XWalkLauncher(bool query_running, base::MessageLoop* main_loop)
+    : ep_launcher_(nullptr),
+      query_running_(query_running),
+      main_loop_(main_loop) {
+  base::Thread::Options thread_options;
+  thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+  dbus_thread_.reset(new base::Thread("Crosswalk D-Bus thread"));
+  dbus_thread_->StartWithOptions(thread_options);
+
+  dbus::Bus::Options options;
+#if defined (OS_TIZEN_MOBILE)
+  options.bus_type = dbus::Bus::CUSTOM_ADDRESS;
+  options.address.assign("unix:path=/run/user/app/dbus/user_bus_socket");
+#endif
+  options.bus_type = dbus::Bus::SESSION;
+  options.connection_type = dbus::Bus::PRIVATE;
+  options.dbus_task_runner = dbus_thread_->message_loop_proxy();
+  dbus::Bus* bus = new dbus::Bus(options);
+  bus->Connect();
+  bus->GetManagedObjects();
+
+  dbus_object_manager_.reset(new DBusObjectManager(bus, main_loop));
+  dbus_object_manager_->SetObserver(this);
+}
+
+XWalkLauncher::~XWalkLauncher() {
+}
+
+int XWalkLauncher::Launch(const std::string& appid_or_url, bool fullscreen,
+                          bool remote_debugging, int argc, char* argv[]) {
+  appid_or_url_ = appid_or_url;
+  fullscreen_ = fullscreen;
+  remote_debugging_ = remote_debugging;
+
+  // Query app.
+  if (query_running_) {
+    return dbus_object_manager_->IsApplicationRunning(appid_or_url_);
+  }
+
+  return !LaunchApplication();
+}
+
+int XWalkLauncher::LaunchApplication() {
+  ep_launcher_.reset(new XWalkExtensionProcessLauncher());
+
+  launcher_pid_ = getpid();
+  if (!dbus_object_manager_->Launch(appid_or_url_, launcher_pid_,
+                                    fullscreen_, remote_debugging_))
+    return 1;
+  return InitExtensionProcessChannel();
+}
+
+bool XWalkLauncher::InitExtensionProcessChannel() {
+  if (ep_launcher_->is_started())
+    return false;
+
+  // Need to call method via DBus to get EP channel
+  std::pair<std::string, int> fd = dbus_object_manager_->GetEPChannel();
+  if (fd.first.empty() || fd.second < 0)
+    return false;
+  ep_launcher_->Launch(fd.first, fd.second);
+  return true;
+}
+
+void XWalkLauncher::OnEPChannelCreated() {
+  InitExtensionProcessChannel();
+}
diff --git a/src/xwalk/application/tools/linux/xwalk_launcher.h b/src/xwalk/application/tools/linux/xwalk_launcher.h
new file mode 100644 (file)
index 0000000..e4c0533
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd 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_LINUX_XWALK_LAUNCHER_H_
+#define XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/threading/thread.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+
+#include "xwalk/application/tools/linux/dbus_object_manager.h"
+#include "xwalk/application/tools/linux/xwalk_extension_process_launcher.h"
+
+class XWalkLauncher : public DBusObjectManager::Observer {
+ public:
+  XWalkLauncher(bool query_running, base::MessageLoop* main_loop);
+  virtual ~XWalkLauncher();
+  virtual int Launch(const std::string& appid_or_url, bool fullscreen,
+                     bool remote_debugging, int argc = 0,
+                     char* argv[] = nullptr);
+
+ protected:
+  int LaunchApplication();
+
+  std::unique_ptr<XWalkExtensionProcessLauncher> ep_launcher_;
+
+  unsigned int launcher_pid_;
+  std::string appid_or_url_;
+  bool fullscreen_;
+  bool remote_debugging_;
+  bool query_running_;
+
+  base::MessageLoop* main_loop_;
+
+  std::unique_ptr<DBusObjectManager> dbus_object_manager_;
+
+ private:
+  bool InitExtensionProcessChannel();
+  virtual void OnEPChannelCreated() override;
+
+  std::unique_ptr<base::Thread> dbus_thread_;
+};
+
+#endif  // XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_H_
index 46c956b..8ea14b7 100644 (file)
 // Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <libgen.h>
-
 #include <glib.h>
-#include <gio/gio.h>
-#include <gio/gunixfdlist.h>
 
-#include "xwalk/application/tools/linux/dbus_connection.h"
-#include "xwalk/application/tools/linux/xwalk_extension_process_launcher.h"
+#include <memory>
+
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump.h"
+#include "base/message_loop/message_pump_glib.h"
+#include "base/run_loop.h"
+
+#include "xwalk/application/tools/linux/xwalk_launcher.h"
 #if defined(OS_TIZEN)
-#include "url/gurl.h"
 #include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
-#include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
 #endif
 
-static const char* xwalk_service_name = "org.crosswalkproject.Runtime1";
-static const char* xwalk_running_path = "/running1";
-static const char* xwalk_running_manager_iface =
-    "org.crosswalkproject.Running.Manager1";
-static const char* xwalk_running_app_iface =
-    "org.crosswalkproject.Running.Application1";
+namespace {
 
-static char* application_object_path;
+int g_argc;
+char** g_argv;
+gboolean query_running = FALSE;
+gboolean fullscreen = FALSE;
+gboolean remote_debugging = FALSE;
+gchar** cmd_appid_or_url;
+char* application_object_path;
 
-static GMainLoop* mainloop;
-static GDBusConnection* g_connection;
-static GDBusObjectManager* g_running_apps_manager;
-static XWalkExtensionProcessLauncher* ep_launcher = NULL;
+}  // namespace
 
-static int g_argc;
-static char** g_argv;
-static gboolean query_running = FALSE;
-static gboolean fullscreen = FALSE;
-static gboolean remote_debugging = FALSE;
-static gchar** cmd_appid_or_url;
-
-static GOptionEntry entries[] = {
+static const GOptionEntry entries[] {
   { "running", 'r', 0, G_OPTION_ARG_NONE, &query_running,
-    "Check whether the application is running", NULL },
+    "Check whether the application is running", nullptr },
   { "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &fullscreen,
-    "Run the application as fullscreen", NULL },
+    "Run the application as fullscreen", nullptr },
   { "debugging_port", 'd', 0, G_OPTION_ARG_NONE, &remote_debugging,
-    "Enable remote debugging for the application", NULL },
-  { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &cmd_appid_or_url,
-    "ID of the application to be launched or URL to open", NULL },
-  { NULL }
+    "Enable remote debugging for the application", nullptr },
+  { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY,
+    &cmd_appid_or_url,
+    "ID of the application to be launched or URL to open", nullptr },
+  { nullptr }
 };
 
-static void object_removed(GDBusObjectManager* manager, GDBusObject* object,
-                           gpointer user_data) {
-  const char* path = g_dbus_object_get_object_path(object);
-
-  if (g_strcmp0(path, application_object_path))
-    return;
-
-  fprintf(stderr, "Application '%s' disappeared, exiting.\n", path);
-
-  delete ep_launcher;
-  g_main_loop_quit(mainloop);
-}
-
-static void on_app_properties_changed(GDBusProxy* proxy,
-                                      GVariant* changed_properties,
-                                      GStrv invalidated_properties,
-                                      gpointer user_data) {
-  const char* interface = g_dbus_proxy_get_interface_name(proxy);
-
-  fprintf(stderr, "properties changed %s\n", interface);
-
-  if (g_variant_n_children(changed_properties) == 0)
-    return;
-
-  if (g_strcmp0(interface, xwalk_running_app_iface))
-    return;
-
-  GVariantIter* iter;
-  const gchar* key;
-  GVariant* value;
-
-  g_variant_get(changed_properties, "a{sv}", &iter);
-
-  while (g_variant_iter_loop(iter, "{&sv}", &key, &value)) {
-    if (g_strcmp0(key, "State"))
-      continue;
-
-    const gchar* state = g_variant_get_string(value, NULL);
-
-    fprintf(stderr, "Application state %s\n", state);
-  }
-}
-
-static gboolean init_extension_process_channel(GDBusProxy* app_proxy) {
-  if (ep_launcher->is_started())
-    return FALSE;
-
-  // Get the client socket file descriptor from fd_list. The reply will
-  // contains an index to the list.
-  GUnixFDList* fd_list;
-  GVariant* res = g_dbus_proxy_call_with_unix_fd_list_sync(
-      app_proxy, "GetEPChannel", NULL, G_DBUS_CALL_FLAGS_NONE,
-      -1, NULL, &fd_list, NULL, NULL);
-  if (!res || g_variant_n_children(res) != 2)
-    return FALSE;
-
-  const gchar* channel_id =
-      g_variant_get_string(g_variant_get_child_value(res, 0), NULL);
-  if (!channel_id || !strlen(channel_id))
-    return FALSE;
-
-  gint32 client_fd_idx =
-      g_variant_get_handle(g_variant_get_child_value(res, 1));
-  int client_fd = g_unix_fd_list_get(fd_list, client_fd_idx, NULL);
-
-  ep_launcher->Launch(channel_id, client_fd);
-  return TRUE;
-}
-
-static void on_app_signal(GDBusProxy* proxy,
-                          gchar* sender_name,
-                          gchar* signal_name,
-                          GVariant* parameters,
-                          gpointer user_data) {
-  if (!strcmp(signal_name, "EPChannelCreated")) {
-    init_extension_process_channel(proxy);
-  } else {
-    fprintf(stderr, "Unkown signal received: %s\n", signal_name);
-  }
-}
-
-static int query_application_running(const char* app_id) {
-  GList* objects = g_dbus_object_manager_get_objects(g_running_apps_manager);
-  GList* it;
-  bool is_running = FALSE;
-
-  for (it = objects; it; it = it->next) {
-    GDBusObject* object = reinterpret_cast<GDBusObject*>(it->data);
-    GDBusInterface* iface = g_dbus_object_get_interface(
-        object,
-        xwalk_running_app_iface);
-    if (!iface)
-      continue;
-
-    GDBusProxy* proxy = G_DBUS_PROXY(iface);
-    GVariant* id_variant;
-    id_variant = g_dbus_proxy_get_cached_property(proxy, "AppID");
-    if (!id_variant) {
-      g_object_unref(iface);
-      continue;
-    }
-
-    const gchar* id;
-    g_variant_get(id_variant, "s", &id);
-    if (!strcmp(app_id, id)) {
-      is_running = TRUE;
-      break;
-    }
-
-    g_object_unref(iface);
-  }
-  const char* str = is_running ? "running" : "not running";
-  g_print("Application %s is %s.\n", app_id, str);
-
-  g_list_free_full(objects, g_object_unref);
-  return is_running ? 0 : 1;
-}
-
-static void launch_application(const char* appid_or_url,
-                               gboolean fullscreen,
-                               gboolean remote_debugging) {
-  ep_launcher = new XWalkExtensionProcessLauncher();
-  GError* error = NULL;
-  g_signal_connect(g_running_apps_manager, "object-removed",
-                   G_CALLBACK(object_removed), NULL);
-
-  GDBusProxy* running_proxy = g_dbus_proxy_new_sync(
-      g_connection,
-      G_DBUS_PROXY_FLAGS_NONE, NULL, xwalk_service_name,
-      xwalk_running_path, xwalk_running_manager_iface, NULL, &error);
-  if (!running_proxy) {
-    g_print("Couldn't create proxy for '%s': %s\n", xwalk_running_manager_iface,
-            error->message);
-    g_error_free(error);
-    exit(1);
-  }
-
-  unsigned int launcher_pid = getpid();
-
-  GVariant* result  = g_dbus_proxy_call_sync(running_proxy, "Launch",
-      g_variant_new("(subb)", appid_or_url, launcher_pid, fullscreen,
-                    remote_debugging),
-      G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-  if (!result) {
-    fprintf(stderr, "Couldn't call 'Launch' method: %s\n", error->message);
-    exit(1);
-  }
-
-  g_variant_get(result, "(o)", &application_object_path);
-  fprintf(stderr, "Application launched with path '%s'\n",
-          application_object_path);
-
-  GDBusProxy* app_proxy = g_dbus_proxy_new_sync(
-      g_connection,
-      G_DBUS_PROXY_FLAGS_NONE, NULL, xwalk_service_name,
-      application_object_path, xwalk_running_app_iface, NULL, &error);
-  if (!app_proxy) {
-    g_print("Couldn't create proxy for '%s': %s\n", xwalk_running_app_iface,
-            error->message);
-    g_error_free(error);
-    exit(1);
-  }
-
-  g_signal_connect(app_proxy, "g-properties-changed",
-                   G_CALLBACK(on_app_properties_changed), NULL);
-
-  mainloop = g_main_loop_new(NULL, FALSE);
-  g_signal_connect(app_proxy, "g-signal", G_CALLBACK(on_app_signal), NULL);
-
-#if defined(OS_TIZEN)
-  char name[128];
-  snprintf(name, sizeof(name), "xwalk-%s", appid_or_url);
-
-  if (xwalk_appcore_init(g_argc, g_argv, name, app_proxy)) {
-    fprintf(stderr, "Failed to initialize appcore");
-    exit(1);
-  }
-#endif
-
-  init_extension_process_channel(app_proxy);
-  g_main_loop_run(mainloop);
-}
-
-void connect_to_application_manager() {
-  GError* error = NULL;
-  g_connection = get_session_bus_connection(&error);
-  if (!g_connection) {
-    fprintf(stderr, "Couldn't get the session bus connection: %s\n",
-            error->message);
-    exit(1);
-  }
-
-  g_running_apps_manager =
-      g_dbus_object_manager_client_new_sync(
-          g_connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
-          xwalk_service_name, xwalk_running_path,
-          NULL, NULL, NULL, NULL, &error);
-  if (!g_running_apps_manager) {
-    fprintf(stderr, "Service '%s' does could not be reached: %s\n",
-            xwalk_service_name, error->message);
-    exit(1);
-  }
-}
-
 int main(int argc, char** argv) {
-  GError* error = NULL;
-  char* appid_or_url;
-
-  g_argc = argc;
-  g_argv = argv;
-
 #if !GLIB_CHECK_VERSION(2, 36, 0)
   // g_type_init() is deprecated on GLib since 2.36.
   g_type_init();
@@ -274,42 +50,43 @@ int main(int argc, char** argv) {
 
 #if defined(OS_TIZEN)
   if (xwalk_tizen_check_group_users())
-    exit(1);
+    return 1;
 #endif
+  base::MessageLoop msg_loop(
+      make_scoped_ptr<base::MessagePump>(new base::MessagePumpGlib()));
+
+  g_argc = argc;
+  g_argv = argv;
 
+  GError* error = nullptr;
   GOptionContext* context =
       g_option_context_new("- Crosswalk Application Launcher");
-  g_option_context_add_main_entries(context, entries, NULL);
+  g_option_context_add_main_entries(context, entries, nullptr);
   if (!g_option_context_parse(context, &argc, &argv, &error)) {
-    fprintf(stderr, "Option parsing failed: %s\n", error->message);
+    LOG(ERROR) << "Option parsing failed: " << error->message;
     exit(1);
   }
 
-  connect_to_application_manager();
-
-  // Launch app.
-  if (!strcmp(basename(argv[0]), "xwalk-launcher")) {
-    if (cmd_appid_or_url == NULL) {
-      fprintf(stderr, "No AppID informed, nothing to do.\n");
-      return 0;
-    }
-    appid_or_url = strdup(cmd_appid_or_url[0]);
-#if defined(OS_TIZEN)
-    if (GURL(appid_or_url).spec().empty()
-       && xwalk_change_cmdline(argc, argv, appid_or_url))
+  std::string appid_or_url;
+  if (!strcmp(basename(g_argv[0]), "xwalk-launcher")) {
+    if (!cmd_appid_or_url) {
+      LOG(ERROR) << "No AppID informed, nothing to do.";
       exit(1);
-#endif
+    }
+    appid_or_url = std::string(cmd_appid_or_url[0]);
   } else {
-    appid_or_url = strdup(basename(argv[0]));
+    appid_or_url = std::string(basename(g_argv[0]));
   }
 
-
-  // Query app.
-  if (query_running) {
-    return query_application_running(appid_or_url);
-  }
-
-  launch_application(appid_or_url, fullscreen, remote_debugging);
-  free(appid_or_url);
-  return 0;
+  std::unique_ptr<XWalkLauncher> launcher;
+#if defined(OS_TIZEN)
+  launcher.reset(new XWalkLauncherTizen(query_running, &msg_loop));
+#else
+  launcher.reset(new XWalkLauncher(query_running, &msg_loop));
+#endif
+  int result = launcher->Launch(appid_or_url, fullscreen, remote_debugging,
+                                argc, argv);
+  if (!result)
+    msg_loop.Run();
+  return result;
 }
index a26b053..8aa67b7 100644 (file)
@@ -1,40 +1,31 @@
 // Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <glib.h>
-#include <gio/gio.h>
+#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
+
+#include <unistd.h>
+#include <pkgmgr-info.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
-#include <appcore/appcore-common.h>
-#include <pkgmgr-info.h>
+#include <string.h>
 
-#include "xwalk/application/common/id_util.h"
-#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
+#include <string>
 
-enum app_event {
-  AE_UNKNOWN,
-  AE_CREATE,
-  AE_TERMINATE,
-  AE_PAUSE,
-  AE_RESUME,
-  AE_RESET,
-  AE_LOWMEM_POST,
-  AE_MEM_FLUSH,
-  AE_MAX
-};
+#include "base/logging.h"
+#include "url/gurl.h"
 
 // Private struct from appcore-internal, necessary to get events from
 // the system.
 struct ui_ops {
   void* data;
-  void (*cb_app)(enum app_event evnt, void* data, bundle* b);
+  void (*cb_app)(app_event evnt, void* data, bundle* b);
 };
 
-static struct ui_ops appcore_ops;
+namespace {
 
-static const char* event2str(enum app_event event) {
+const char* Event2Str(app_event event) {
   switch (event) {
     case AE_UNKNOWN:
       return "AE_UNKNOWN";
@@ -59,33 +50,68 @@ static const char* event2str(enum app_event event) {
   return "INVALID EVENT";
 }
 
-static void application_event_cb(enum app_event event, void* data, bundle* b) {
-  fprintf(stderr, "event '%s'\n", event2str(event));
-  GDBusProxy* app_proxy = reinterpret_cast<GDBusProxy*>(data);
+ui_ops app_ops;
+
+}  // namespace
 
-  if (!app_proxy) {
-    fprintf(stderr, "Invalid DBus proxy.");
-    return;
+XWalkLauncherTizen::XWalkLauncherTizen(bool query_running,
+    base::MessageLoop* main_loop)
+    : XWalkLauncher(query_running, main_loop) {
+}
+
+int XWalkLauncherTizen::Launch(const std::string& appid_or_url, bool fullscreen,
+                               bool remote_debugging, int argc, char* argv[]) {
+  appid_or_url_ = appid_or_url;
+  fullscreen_ = fullscreen;
+  remote_debugging_ = remote_debugging;
+  // Query app.
+  if (query_running_) {
+    return dbus_object_manager_->IsApplicationRunning(appid_or_url_);
   }
+  std::string name = "xwalk-" + appid_or_url_;
+
+  if (XwalkAppcoreInit(name, argc, argv)) {
+    LOG(ERROR) << "Failed to initialize appcore.";
+    return 1;
+  }
+  if (GURL(appid_or_url_).spec().empty()
+      && XwalkChangeCmdline(appid_or_url_, argc, argv))
+    return 1;
+  return 0;
+}
+
+bool XWalkLauncherTizen::Suspend() {
+  return dbus_object_manager_->Suspend();
+}
+
+bool XWalkLauncherTizen::Resume() {
+  return dbus_object_manager_->Resume();
+}
+
+void XWalkLauncherTizen::application_event_cb(app_event event,
+                                              void* data, bundle* b) {
+  XWalkLauncherTizen* xwalk_launcher = static_cast<XWalkLauncherTizen*>(data);
+  LOG(INFO) << "event '" << Event2Str(event) << "'";
 
   switch (event) {
     case AE_UNKNOWN:
     case AE_CREATE:
       break;
     case AE_TERMINATE:
-      exit(0);
+      xwalk_launcher->main_loop_->QuitNow();
       break;
     case AE_PAUSE:
-      g_dbus_proxy_call(
-          app_proxy, "Suspend", NULL,
-          G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+      if (!xwalk_launcher->Suspend())
+        LOG(ERROR) << "Suspending application failed";
       break;
     case AE_RESUME:
-      g_dbus_proxy_call(
-          app_proxy, "Resume", NULL,
-          G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+      if (!xwalk_launcher->Resume())
+        LOG(ERROR) << "Resuming application failed";
       break;
     case AE_RESET:
+      if (!xwalk_launcher->LaunchApplication())
+        xwalk_launcher->main_loop_->QuitNow();
+      break;
     case AE_LOWMEM_POST:
     case AE_MEM_FLUSH:
     case AE_MAX:
@@ -93,34 +119,37 @@ static void application_event_cb(enum app_event event, void* data, bundle* b) {
   }
 }
 
-int xwalk_appcore_init(
-    int argc, char** argv, const char* name, GDBusProxy* app_proxy) {
-  appcore_ops.cb_app = application_event_cb;
-  appcore_ops.data = app_proxy;
-
-  return appcore_init(name, &appcore_ops, argc, argv);
+int XWalkLauncherTizen::XwalkAppcoreInit(const std::string& name,
+                                         int argc, char* argv[]) {
+  app_ops.cb_app = application_event_cb;
+  app_ops.data = this;
+  return appcore_init(name.c_str(), &app_ops, argc, argv);
 }
 
-int xwalk_change_cmdline(int argc, char** argv, const char* app_id) {
+int XWalkLauncherTizen::XwalkChangeCmdline(const std::string& app_id,
+                                           int argc, char* argv[]) {
   // Change /proc/<pid>/cmdline to app exec path. See XWALK-1722 for details.
   pkgmgrinfo_appinfo_h handle;
-  char* exec_path = NULL;
+  char* exec_path = nullptr;
   // todo : add is_admin
-  if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id,
+  if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(),
       getuid(), &handle) != PMINFO_R_OK ||
       pkgmgrinfo_appinfo_get_exec(handle, &exec_path) != PMINFO_R_OK ||
       !exec_path) {
-    if (pkgmgrinfo_appinfo_get_appinfo(app_id, &handle) != PMINFO_R_OK ||
+    if (pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle) !=
+        PMINFO_R_OK ||
         pkgmgrinfo_appinfo_get_exec(handle, &exec_path) != PMINFO_R_OK ||
         !exec_path) {
-      fprintf(stderr, "Couldn't find exec path for application: %s\n", app_id);
+      LOG(ERROR) << "Couldn't find exec path for application: " << app_id;
       return -1;
     }
   }
 
+  // zeros g_argv_
   for (int i = 0; i < argc; ++i)
     memset(argv[i], 0, strlen(argv[i]));
-  strncpy(argv[0], exec_path, strlen(exec_path)+1);
+
+  strncpy(argv[0], exec_path, strlen(exec_path) + 1);
   pkgmgrinfo_appinfo_destroy_appinfo(handle);
   return 0;
 }
index 75237bd..a0c8f3f 100644 (file)
@@ -1,13 +1,50 @@
 // Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd 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_LINUX_XWALK_LAUNCHER_TIZEN_H_
 #define XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_TIZEN_H_
 
-int xwalk_appcore_init(int argc, char** argv,
-                       const char* name, GDBusProxy* app_proxy);
+#include <appcore-common.h>
+#include <glib.h>
 
-int xwalk_change_cmdline(int argc, char** argv, const char* app_id);
+#include <memory>
+#include <string>
+
+#include "base/message_loop/message_loop.h"
+
+#include "xwalk/application/common/id_util.h"
+#include "xwalk/application/tools/linux/xwalk_launcher.h"
+#include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
+
+// Private enum from appcore-internal
+extern "C" enum app_event {
+  AE_UNKNOWN,
+  AE_CREATE,
+  AE_TERMINATE,
+  AE_PAUSE,
+  AE_RESUME,
+  AE_RESET,
+  AE_LOWMEM_POST,
+  AE_MEM_FLUSH,
+  AE_MAX
+};
+
+class XWalkLauncherTizen : public XWalkLauncher {
+ public:
+  XWalkLauncherTizen(bool query_running, base::MessageLoop* main_loop);
+  int Launch(const std::string& appid_or_url, bool fullscreen,
+             bool remote_debugging, int argc, char* argv[]);
+  bool Suspend();
+  bool Resume();
+
+ private:
+  static void application_event_cb(app_event event, void* data, bundle* b);
+  int XwalkAppcoreInit(const std::string& name, int argc, char* argv[]);
+  int XwalkChangeCmdline(const std::string& app_id, int argc, char* argv[]);
+
+  base::MessageLoop* main_loop_;
+};
 
 #endif  // XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_TIZEN_H_
index 862a47b..148155b 100644 (file)
@@ -16,7 +16,6 @@
 #include "base/path_service.h"
 #include "xwalk/application/common/id_util.h"
 #include "xwalk/application/common/tizen/application_storage.h"
-#include "xwalk/application/tools/linux/dbus_connection.h"
 #include "xwalk/application/tools/tizen/xwalk_package_installer.h"
 #include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
 #include "xwalk/runtime/common/xwalk_paths.h"
index ba5abfd..9a6a0c2 100644 (file)
@@ -28,6 +28,8 @@
         # TODO(t.iwanek) fix me - this duplicates compilation of those files
         '../../../runtime/common/xwalk_paths.cc',
         '../../../runtime/common/xwalk_paths.h',
+        '../../../runtime/common/xwalk_switches.cc',
+        '../../../runtime/common/xwalk_switches.h',
         '../../../runtime/common/xwalk_system_locale.cc',
         '../../../runtime/common/xwalk_system_locale.h',
       ],
@@ -51,6 +53,8 @@
         # TODO(t.iwanek) fix me - this duplicates compilation of those files
         '../../../runtime/common/xwalk_paths.cc',
         '../../../runtime/common/xwalk_paths.h',
+        '../../../runtime/common/xwalk_switches.cc',
+        '../../../runtime/common/xwalk_switches.h',
         '../../../runtime/common/xwalk_system_locale.cc',
         '../../../runtime/common/xwalk_system_locale.h',
       ],
index c28789e..e076d38 100644 (file)
@@ -2,7 +2,6 @@
   'variables': {
     'tizen%': 0,
     'tizen_mobile%': 0,
-    'shared_process_mode%': 0,
     'enable_murphy%': 0,
   },
   'target_defaults': {
@@ -18,9 +17,6 @@
       ['tizen_mobile==1', {
         'defines': ['OS_TIZEN_MOBILE=1', 'OS_TIZEN=1'],
       }],
-      ['shared_process_mode==1', {
-        'defines': ['SHARED_PROCESS_MODE=1'],
-      }],
       ['enable_murphy==1', {
         'defines': ['ENABLE_MURPHY=1'],
       }],
index 96a0878..903b873 100644 (file)
@@ -168,7 +168,7 @@ ManagedObject::~ManagedObject() {}
 
 ObjectPath ManagedObject::path() const {
   return path_;
-};
+}
 
 void ManagedObject::AppendAllPropertiesToWriter(MessageWriter* writer) const {
   MessageWriter interfaces_writer(NULL);
index 75c8a2b..b278860 100644 (file)
@@ -37,7 +37,7 @@ class XWalkExtensionFunctionInfo {
   // be called from any thread.
   void PostResult(scoped_ptr<base::ListValue> result) const {
     post_result_cb_.Run(result.Pass());
-  };
+  }
 
   std::string name() const {
     return name_;
index fd03fd5..f8c267d 100644 (file)
@@ -21,6 +21,7 @@
 #include "ipc/message_filter.h"
 #include "xwalk/extensions/common/xwalk_extension_messages.h"
 #include "xwalk/extensions/common/xwalk_extension_switches.h"
+#include "xwalk/runtime/browser/xwalk_runner.h"
 #include "xwalk/runtime/common/xwalk_switches.h"
 
 using content::BrowserThread;
@@ -153,7 +154,7 @@ void XWalkExtensionProcessHost::StartProcess() {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   CHECK(!process_ || !channel_);
 
-#if defined(SHARED_PROCESS_MODE)
+  if (XWalkRunner::GetInstance()->shared_process_mode_enabled()) {
 #if defined(OS_LINUX)
     std::string channel_id =
         IPC::Channel::GenerateVerifiedChannelID(std::string());
@@ -171,7 +172,7 @@ void XWalkExtensionProcessHost::StartProcess() {
 #else
     NOTIMPLEMENTED();
 #endif  // #if defined(OS_LINUX)
-#else
+  } else {
     process_.reset(content::BrowserChildProcessHost::Create(
         content::PROCESS_TYPE_CONTENT_END, this));
 
@@ -207,7 +208,7 @@ void XWalkExtensionProcessHost::StartProcess() {
     process_->Launch(
         new ExtensionSandboxedProcessLauncherDelegate(process_->GetHost()),
         cmd_line.release());
-#endif  // #if defined(SHARED_PROCESS_MODE)
+  }
 
   base::ListValue runtime_variables_lv;
   ToListValue(&const_cast<base::ValueMap&>(*runtime_variables_),
index 9890bb7..aa47b4c 100644 (file)
@@ -41,7 +41,10 @@ void XWalkExternalInstance::HandleMessage(scoped_ptr<base::Value> msg) {
   }
 
   std::string string_msg;
-  msg->GetAsString(&string_msg);
+  if (!msg->GetAsString(&string_msg)) {
+    LOG(WARNING) << "Failed to retrieve the message's value.";
+    return;
+  }
   callback(xw_instance_, string_msg.c_str());
 }
 
@@ -54,7 +57,10 @@ void XWalkExternalInstance::HandleSyncMessage(scoped_ptr<base::Value> msg) {
   }
 
   std::string string_msg;
-  msg->GetAsString(&string_msg);
+  if (!msg->GetAsString(&string_msg)) {
+    LOG(WARNING) << "Failed to retrieve the sync message's value.";
+    return;
+  }
 
   callback(xw_instance_, string_msg.c_str());
 }
index f693816..9aeeff7 100644 (file)
Binary files a/src/xwalk/packaging/crosswalk.png and b/src/xwalk/packaging/crosswalk.png differ
index 8e9c587..4850150 100644 (file)
@@ -24,7 +24,7 @@
 %define _binary_payload w3.gzdio
 
 Name:           crosswalk
-Version:        11.39.260.0
+Version:        11.39.264.0
 Release:        0
 Summary:        Chromium-based app runtime
 License:        (BSD-3-Clause and LGPL-2.1+)
@@ -237,7 +237,6 @@ ${GYP_EXTRA_FLAGS} \
 -Duse_system_libexif=1 \
 -Duse_system_libxml=1 \
 -Duse_system_yasm=1 \
--Dshared_process_mode=1 \
 -Denable_hidpi=1
 
 ninja %{?_smp_mflags} -C src/out/Release xwalk xwalk_launcher xwalk_application_tools
index 5989755..7632a2e 100644 (file)
Binary files a/src/xwalk/runtime/android/runtime_lib/res/drawable-hdpi/crosswalk.png and b/src/xwalk/runtime/android/runtime_lib/res/drawable-hdpi/crosswalk.png differ
index e87864a..dbbcb3d 100644 (file)
Binary files a/src/xwalk/runtime/android/runtime_lib/res/drawable-ldpi/crosswalk.png and b/src/xwalk/runtime/android/runtime_lib/res/drawable-ldpi/crosswalk.png differ
index fc19a3e..90c660e 100644 (file)
Binary files a/src/xwalk/runtime/android/runtime_lib/res/drawable-mdpi/crosswalk.png and b/src/xwalk/runtime/android/runtime_lib/res/drawable-mdpi/crosswalk.png differ
index b69b4e8..9aeeff7 100644 (file)
Binary files a/src/xwalk/runtime/android/runtime_lib/res/drawable-xhdpi/crosswalk.png and b/src/xwalk/runtime/android/runtime_lib/res/drawable-xhdpi/crosswalk.png differ
index 5989755..7632a2e 100644 (file)
Binary files a/src/xwalk/runtime/android/sample/res/drawable-hdpi/crosswalk.png and b/src/xwalk/runtime/android/sample/res/drawable-hdpi/crosswalk.png differ
index e87864a..dbbcb3d 100644 (file)
Binary files a/src/xwalk/runtime/android/sample/res/drawable-ldpi/crosswalk.png and b/src/xwalk/runtime/android/sample/res/drawable-ldpi/crosswalk.png differ
index fc19a3e..90c660e 100644 (file)
Binary files a/src/xwalk/runtime/android/sample/res/drawable-mdpi/crosswalk.png and b/src/xwalk/runtime/android/sample/res/drawable-mdpi/crosswalk.png differ
index b69b4e8..9aeeff7 100644 (file)
Binary files a/src/xwalk/runtime/android/sample/res/drawable-xhdpi/crosswalk.png and b/src/xwalk/runtime/android/sample/res/drawable-xhdpi/crosswalk.png differ
index ba26c31..15df5d0 100644 (file)
@@ -35,7 +35,7 @@ struct XWalkSettings::FieldIds {
   // JNI is ineffective and should not be used. Please keep in mind that in the
   // legacy WebView the whole Sync method took <1ms on Xoom, and no one is
   // expected to modify settings in performance-critical code.
-  FieldIds() { }
+  FieldIds() = default;
 
   explicit FieldIds(JNIEnv* env) {
     const char* kStringClassName = "Ljava/lang/String;";
index b94e53d..3c73d1a 100644 (file)
@@ -46,7 +46,7 @@ class RuntimeFileSelectHelper
  private:
   friend class base::RefCountedThreadSafe<RuntimeFileSelectHelper>;
   FRIEND_TEST_ALL_PREFIXES(RuntimeFileSelectHelperTest, IsAcceptTypeValid);
-  explicit RuntimeFileSelectHelper();
+  RuntimeFileSelectHelper();
   virtual ~RuntimeFileSelectHelper();
 
   // Utility class which can listen for directory lister events and relay
index 4fcfbd0..b3a8926 100644 (file)
@@ -13,7 +13,7 @@ namespace xwalk {
 
 class RuntimeJavaScriptDialogManager : public content::JavaScriptDialogManager {
  public:
-  explicit RuntimeJavaScriptDialogManager();
+  RuntimeJavaScriptDialogManager();
   virtual ~RuntimeJavaScriptDialogManager();
 
   virtual void RunJavaScriptDialog(
index ff088cd..c9d12d4 100644 (file)
@@ -40,6 +40,7 @@
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "xwalk/application/common/constants.h"
 #include "xwalk/runtime/browser/runtime_network_delegate.h"
+#include "xwalk/runtime/common/xwalk_content_client.h"
 
 #if defined(OS_ANDROID)
 #include "xwalk/runtime/browser/android/cookie_manager.h"
@@ -113,8 +114,8 @@ net::URLRequestContext* RuntimeURLRequestContextGetter::GetURLRequestContext() {
     storage_->set_channel_id_service(new net::ChannelIDService(
         new net::DefaultChannelIDStore(NULL),
         base::WorkerPool::GetTaskRunner(true)));
-    storage_->set_http_user_agent_settings(
-        new net::StaticHttpUserAgentSettings("en-us,en", base::EmptyString()));
+    storage_->set_http_user_agent_settings(new net::StaticHttpUserAgentSettings(
+        "en-us,en", xwalk::GetUserAgent()));
 
     scoped_ptr<net::HostResolver> host_resolver(
         net::HostResolver::CreateDefaultResolver(NULL));
index 7f95b55..fa642b5 100644 (file)
@@ -216,20 +216,20 @@ void XWalkBrowserMainParts::PreMainMessageLoopRun() {
     return;
   }
 
-#if !defined(SHARED_PROCESS_MODE)
-  application::ApplicationSystem* app_system = xwalk_runner_->app_system();
-  app_system->LaunchFromCommandLine(*command_line, startup_url_,
-                                    run_default_message_loop_);
-  // If the |ui_task| is specified in main function parameter, it indicates
-  // that we will run this UI task instead of running the the default main
-  // message loop. See |content::BrowserTestBase::SetUp| for |ui_task| usage
-  // case.
-  if (parameters_.ui_task) {
-    parameters_.ui_task->Run();
-    delete parameters_.ui_task;
-    run_default_message_loop_ = false;
+  if (!xwalk_runner_->shared_process_mode_enabled()) {
+    application::ApplicationSystem* app_system = xwalk_runner_->app_system();
+    app_system->LaunchFromCommandLine(*command_line, startup_url_,
+                                      run_default_message_loop_);
+    // If the |ui_task| is specified in main function parameter, it indicates
+    // that we will run this UI task instead of running the the default main
+    // message loop. See |content::BrowserTestBase::SetUp| for |ui_task| usage
+    // case.
+    if (parameters_.ui_task) {
+      parameters_.ui_task->Run();
+      delete parameters_.ui_task;
+      run_default_message_loop_ = false;
+    }
   }
-#endif
 }
 
 bool XWalkBrowserMainParts::MainMessageLoopRun(int* result_code) {
index 423a64e..fc3507c 100644 (file)
@@ -40,7 +40,8 @@ XWalkRunner* g_xwalk_runner = NULL;
 
 }  // namespace
 
-XWalkRunner::XWalkRunner() {
+XWalkRunner::XWalkRunner()
+    : shared_process_mode_enabled_(false) {
   VLOG(1) << "Creating XWalkRunner object.";
   DCHECK(!g_xwalk_runner);
   g_xwalk_runner = this;
index fe46163..f8ac8cc 100644 (file)
@@ -81,6 +81,9 @@ class XWalkRunner {
   void EnableRemoteDebugging(int port);
   void DisableRemoteDebugging();
 
+  bool shared_process_mode_enabled() const
+      { return shared_process_mode_enabled_; }
+
  protected:
   XWalkRunner();
 
@@ -98,6 +101,8 @@ class XWalkRunner {
   virtual scoped_ptr<SysAppsComponent> CreateSysAppsComponent();
   virtual scoped_ptr<StorageComponent> CreateStorageComponent();
 
+  bool shared_process_mode_enabled_;
+
  private:
   friend class XWalkMainDelegate;
   friend class ::XWalkTestSuiteInitializer;
index 8a004ba..3b0a322 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "xwalk/runtime/browser/xwalk_runner_tizen.h"
 
+#include "base/command_line.h"
 #include "content/public/browser/browser_thread.h"
 #include "crypto/nss_util.h"
 #include "xwalk/application/browser/application_service.h"
 #include "xwalk/runtime/browser/sysapps_component.h"
 #include "xwalk/runtime/browser/xwalk_component.h"
 #include "xwalk/runtime/common/xwalk_runtime_features.h"
+#include "xwalk/runtime/common/xwalk_switches.h"
 
 namespace xwalk {
 
-XWalkRunnerTizen::XWalkRunnerTizen() {}
+XWalkRunnerTizen::XWalkRunnerTizen() {
+  CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+  shared_process_mode_enabled_ =
+      !(cmd_line->HasSwitch(switches::kXWalkDisableSharedProcessMode));
+}
 
 XWalkRunnerTizen::~XWalkRunnerTizen() {}
 
@@ -30,12 +36,12 @@ void XWalkRunnerTizen::PreMainMessageLoopRun() {
   // NSSInitSingleton is a costly operation (up to 100ms on VTC-1010),
   // resulting in postponing the parsing and composition steps of the render
   // process at cold start. Therefore, move the initialization logic here.
-#if defined(SHARED_PROCESS_MODE)
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&crypto::EnsureNSSInit));
-#endif
+  if (shared_process_mode_enabled()) {
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO,
+        FROM_HERE,
+        base::Bind(&crypto::EnsureNSSInit));
+  }
 }
 
 }  // namespace xwalk
index 0971add..dab6783 100644 (file)
@@ -85,7 +85,7 @@ base::FilePath GetConfigPath() {
 
 bool GetXWalkDataPath(base::FilePath* path) {
   base::FilePath::StringType xwalk_suffix;
-#if defined(SHARED_PROCESS_MODE)
+#if defined(OS_TIZEN)
   xwalk_suffix = FILE_PATH_LITERAL("xwalk-service");
 #else
   xwalk_suffix = FILE_PATH_LITERAL("xwalk");
index 43a6e71..7c371aa 100644 (file)
@@ -12,6 +12,9 @@ const char kAppIcon[] = "app-icon";
 // Disables the usage of Portable Native Client.
 const char kDisablePnacl[] = "disable-pnacl";
 
+// Disables the shared process mode
+const char kXWalkDisableSharedProcessMode[] = "disable-shared-process-mode";
+
 // Enable all the experimental features in XWalk.
 const char kExperimentalFeatures[] = "enable-xwalk-experimental-features";
 
index 642a769..049e3fb 100644 (file)
@@ -17,6 +17,7 @@ extern const char kFullscreen[];
 extern const char kListFeaturesFlags[];
 extern const char kXWalkAllowExternalExtensionsForRemoteSources[];
 extern const char kXWalkDataPath[];
+extern const char kXWalkDisableSharedProcessMode[];
 
 #if defined(OS_ANDROID)
 extern const char kXWalkProfileName[];
index e631072..7522608 100644 (file)
@@ -68,6 +68,25 @@ bool XWalkRenderViewExtTizen::OnMessageReceived(const IPC::Message& message) {
   return handled;
 }
 
+void XWalkRenderViewExtTizen::DidStartProvisionalLoad(
+    blink::WebLocalFrame* frame) {
+  std::string code =
+      "(function() {"
+      "  window.eventListenerList = [];"
+      "  window._addEventListener = window.addEventListener;"
+      "  window.addEventListener = function(event, callback, useCapture) {"
+      "    if (event == 'storage') {"
+      "      window.eventListenerList.push(callback);"
+      "    }"
+      "    window._addEventListener(event, callback, useCapture);"
+      "  }"
+      "})();";
+
+  blink::WebScriptSource source =
+      blink::WebScriptSource(base::ASCIIToUTF16(code));
+  frame->executeScript(source);
+}
+
 void XWalkRenderViewExtTizen::OnHWKeyPressed(int keycode) {
   std::string event_name;
   if (keycode == ui::VKEY_BACK) {
index 1181e5d..6a54b66 100644 (file)
@@ -8,6 +8,7 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "content/public/renderer/render_view_observer.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
 
 namespace xwalk {
 
@@ -21,6 +22,7 @@ class XWalkRenderViewExtTizen : public content::RenderViewObserver {
 
   // RenderView::Observer:
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+  virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) OVERRIDE;
 
   void OnHWKeyPressed(int keycode);
 
index 0a94cab..013e7cc 100644 (file)
Binary files a/src/xwalk/runtime/resources/icons/crosswalk.ico and b/src/xwalk/runtime/resources/icons/crosswalk.ico differ
index b69b4e8..9aeeff7 100644 (file)
Binary files a/src/xwalk/runtime/resources/icons/crosswalk_144x144.png and b/src/xwalk/runtime/resources/icons/crosswalk_144x144.png differ
index e87864a..dbbcb3d 100644 (file)
Binary files a/src/xwalk/runtime/resources/icons/crosswalk_48x48.png and b/src/xwalk/runtime/resources/icons/crosswalk_48x48.png differ
index fc19a3e..90c660e 100644 (file)
Binary files a/src/xwalk/runtime/resources/icons/crosswalk_72x72.png and b/src/xwalk/runtime/resources/icons/crosswalk_72x72.png differ
index 5989755..7632a2e 100644 (file)
Binary files a/src/xwalk/runtime/resources/icons/crosswalk_96x96.png and b/src/xwalk/runtime/resources/icons/crosswalk_96x96.png differ
index e2dd96b..40dd07a 100644 (file)
@@ -23,7 +23,7 @@ using extensions::XWalkExtensionInstance;
 
 class DeviceCapabilitiesExtension : public XWalkExtension {
  public:
-  explicit DeviceCapabilitiesExtension();
+  DeviceCapabilitiesExtension();
   virtual ~DeviceCapabilitiesExtension();
 
   // XWalkExtension implementation.
index 499c54b..e171cb0 100644 (file)
@@ -19,7 +19,7 @@ using extensions::XWalkExtensionInstance;
 
 class RawSocketExtension : public XWalkExtension {
  public:
-  explicit RawSocketExtension();
+  RawSocketExtension();
   virtual ~RawSocketExtension();
 
   // XWalkExtension implementation.
index e756ede..99a7142 100644 (file)
@@ -59,6 +59,7 @@
         }],
         ['tizen==1', {
           'sources': [
+            'application/common/manifest_handlers/tizen_appwidget_handler_unittest.cc',
             'application/common/manifest_handlers/tizen_navigation_handler_unittest.cc',
           ],
         }],