From: Eurogiciel-BOT Date: Mon, 15 Dec 2014 13:21:46 +0000 (+0000) Subject: Upstream version 11.39.264.0 X-Git-Tag: submit/tizen/20141215.140058~20 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fframework%2Fweb%2Fcrosswalk.git;a=commitdiff_plain;h=a3137fbf780cf581b1011fd9024eff767a6c1d4b Upstream version 11.39.264.0 Upstream commit-id 0019cd573cdef4fa4fd00ecd9cda8d1846b07026 Change-Id: Iaf0768bf962735e1e8405ce98921cc663d6cb269 Signed-off-by: Eurogiciel-BOT --- diff --git a/packaging/crosswalk.png b/packaging/crosswalk.png index f693816..9aeeff7 100644 Binary files a/packaging/crosswalk.png and b/packaging/crosswalk.png differ diff --git a/packaging/crosswalk.spec b/packaging/crosswalk.spec index 8e9c587..4850150 100644 --- a/packaging/crosswalk.spec +++ b/packaging/crosswalk.spec @@ -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 diff --git a/src/.DEPS.git b/src/.DEPS.git index 5725bbd..4d0fba8 100644 --- a/src/.DEPS.git +++ b/src/.DEPS.git @@ -7,7 +7,7 @@ vars = { 'eyes-free': 'http://eyes-free.googlecode.com/svn', 'webkit_rev': - '@46701e45dce4e844a0a1d14d69a91a509587aba1', + '@e17a1818a3674776f83cb20461e90763d28bf1c9', 'blink': 'http://src.chromium.org/blink', 'skia': diff --git a/src/DEPS b/src/DEPS index da8bfd6..ce6db00 100644 --- a/src/DEPS +++ b/src/DEPS @@ -156,12 +156,10 @@ deps_os = { 'src/third_party/bidichecker': None, 'src/third_party/libc++/trunk': None, 'src/tools/page_cycler/acid3': None, - 'src/third_party/nss': - (Var("git.chromium.org")) + '/chromium/deps/nss.git@87b96db4268293187d7cf741907a6d5d1d8080e0', 'src/chrome/test/data/perf/canvas_bench': None, 'src/third_party/libexif/sources': None, 'src/build/util/support': None, - 'src/third_party/libc++abi/trunk': None, + 'src/third_party/libsrtp': None, 'src/third_party/WebKit/LayoutTests/w3c/csswg-test': None, 'src/third_party/pymox/src': None, 'src/media/cdm/ppapi/api': None, @@ -171,7 +169,9 @@ deps_os = { 'src/third_party/openmax_dl': None, 'src/third_party/google_toolbox_for_mac/src': (Var("git.chromium.org")) + '/external/google-toolbox-for-mac.git@a09526298f9dd1ec49d3b3ac5608d2a257b94cef', + 'src/third_party/webgl': None, 'src/third_party/WebKit/LayoutTests/w3c/web-platform-tests': None, + 'src/third_party/scons-2.0.1': None, 'src/chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin': None, 'src/third_party/opus/src': None, 'src/third_party/webpagereplay': None, @@ -179,79 +179,79 @@ deps_os = { 'src/native_client': None, 'src/third_party/usrsctp/usrsctplib': None, 'src/third_party/brotli/src': None, - 'src/third_party/webgl': None, + 'src/third_party/libc++abi/trunk': None, 'src/third_party/yasm/source/patched-yasm': None, 'src/testing/iossim/third_party/class-dump': (Var("git.chromium.org")) + '/chromium/deps/class-dump.git@89bd40883c767584240b4dade8b74e6f57b9bdab', - 'src/third_party/libjpeg_turbo': None, 'src/third_party/cld_2/src': None, - 'src/third_party/libsrtp': None, + 'src/third_party/libjpeg_turbo': None, 'src/third_party/ots': None, 'src/third_party/ffmpeg': None, 'src/third_party/hunspell': None, 'src/third_party/swig/Lib': None, - 'src/third_party/scons-2.0.1': None - }, - 'unix': { - 'src/third_party/fontconfig/src': - (Var("git.chromium.org")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1', - 'build/third_party/cbuildbot_chromite': - (Var("git.chromium.org")) + '/chromiumos/chromite.git@1e95b44e033daa6b48e2e9702c5b08a9410f11d8', - 'src/third_party/cros_system_api': - (Var("git.chromium.org")) + '/chromiumos/platform/system_api.git@f0fc55329fa536195861778a2ddc6115b4a977bc', - 'src/third_party/pyelftools': - (Var("git.chromium.org")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e', - 'src/third_party/chromite': - (Var("git.chromium.org")) + '/chromiumos/chromite.git@8e92d5c24da7967e27ab2498abc2d2f7ac6ec65a', - 'build/third_party/xvfb': - '/trunk/tools/third_party/xvfb@125214', - 'src/third_party/xdg-utils': - (Var("git.chromium.org")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d', - 'src/third_party/undoview': - (Var("git.chromium.org")) + '/chromium/deps/undoview.git@3ba503e248f3cdbd81b78325a24ece0984637559', - 'src/chrome/tools/test/reference_build/chrome_linux': - (Var("git.chromium.org")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36', - 'src/third_party/swig/linux': - (Var("git.chromium.org")) + '/chromium/deps/swig/linux.git@866b8e0e0e0cfe99ebe608260030916ca0c3f92d', - 'src/third_party/liblouis/src': - (Var("git.chromium.org")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2', - 'src/third_party/freetype2/src': - (Var("git.chromium.org")) + '/chromium/src/third_party/freetype2.git@d699c2994ecc178c4ed05ac2086061b2034c2178', - 'src/third_party/lss': - (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb' - }, - 'android': { - 'src/third_party/android_webview_glue/src': - (Var("git.chromium.org")) + '/external/android_webview_glue.git@a1b0248c80f239e2f6476b9f395b27d0ba1eb3cd', - 'src/third_party/jarjar': - (Var("git.chromium.org")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920', - 'src/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille': - (Var("git.chromium.org")) + '/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git@77bf6edb0138e3a38a2772248696f130dab45e34', - 'src/third_party/freetype': - (Var("git.chromium.org")) + '/chromium/src/third_party/freetype.git@a2b9955b49034a51dfbc8bf9f4e9d312149cecac', - 'src/third_party/apache-mime4j': - (Var("git.chromium.org")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a', - 'src/third_party/elfutils/src': - (Var("git.chromium.org")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7', - 'src/pdf': None, - 'src/third_party/junit/src': - (Var("git.chromium.org")) + '/external/junit.git@c62e2df8dbecccb1b434d4ba8843b59e90b03266', - 'src/third_party/android_tools': - (Var("git.chromium.org")) + '/android_tools.git@d2b86205ff973a3844020feacb35ca6b1d82efbe', - 'src/third_party/httpcomponents-client': - (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c', - 'src/third_party/findbugs': - (Var("git.chromium.org")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12', - 'src/third_party/lss': - (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb', - 'src/third_party/android_protobuf/src': - (Var("git.chromium.org")) + '/external/android_protobuf.git@94f522f907e3f34f70d9e7816b947e62fddbb267', - 'src/third_party/jsr-305/src': - (Var("git.chromium.org")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919', - 'src/third_party/httpcomponents-core': - (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62' - } + 'src/third_party/nss': + (Var("git.chromium.org")) + '/chromium/deps/nss.git@87b96db4268293187d7cf741907a6d5d1d8080e0' + }, + 'unix': { + 'src/third_party/fontconfig/src': + (Var("git.chromium.org")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1', + 'src/third_party/freetype2/src': + (Var("git.chromium.org")) + '/chromium/src/third_party/freetype2.git@d699c2994ecc178c4ed05ac2086061b2034c2178', + 'src/third_party/pyelftools': + (Var("git.chromium.org")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e', + 'src/third_party/chromite': + (Var("git.chromium.org")) + '/chromiumos/chromite.git@8e92d5c24da7967e27ab2498abc2d2f7ac6ec65a', + 'build/third_party/xvfb': + '/trunk/tools/third_party/xvfb@125214', + 'src/third_party/xdg-utils': + (Var("git.chromium.org")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d', + 'src/third_party/undoview': + (Var("git.chromium.org")) + '/chromium/deps/undoview.git@3ba503e248f3cdbd81b78325a24ece0984637559', + 'src/third_party/cros_system_api': + (Var("git.chromium.org")) + '/chromiumos/platform/system_api.git@f0fc55329fa536195861778a2ddc6115b4a977bc', + 'src/chrome/tools/test/reference_build/chrome_linux': + (Var("git.chromium.org")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36', + 'src/third_party/swig/linux': + (Var("git.chromium.org")) + '/chromium/deps/swig/linux.git@866b8e0e0e0cfe99ebe608260030916ca0c3f92d', + 'src/third_party/liblouis/src': + (Var("git.chromium.org")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2', + 'build/third_party/cbuildbot_chromite': + (Var("git.chromium.org")) + '/chromiumos/chromite.git@1e95b44e033daa6b48e2e9702c5b08a9410f11d8', + 'src/third_party/lss': + (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb' + }, + 'android': { + 'src/third_party/android_webview_glue/src': + (Var("git.chromium.org")) + '/external/android_webview_glue.git@a1b0248c80f239e2f6476b9f395b27d0ba1eb3cd', + 'src/third_party/jarjar': + (Var("git.chromium.org")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920', + 'src/third_party/android_tools': + (Var("git.chromium.org")) + '/android_tools.git@d2b86205ff973a3844020feacb35ca6b1d82efbe', + 'src/pdf': None, + 'src/third_party/apache-mime4j': + (Var("git.chromium.org")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a', + 'src/third_party/elfutils/src': + (Var("git.chromium.org")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7', + 'src/third_party/freetype': + (Var("git.chromium.org")) + '/chromium/src/third_party/freetype.git@a2b9955b49034a51dfbc8bf9f4e9d312149cecac', + 'src/third_party/junit/src': + (Var("git.chromium.org")) + '/external/junit.git@c62e2df8dbecccb1b434d4ba8843b59e90b03266', + 'src/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille': + (Var("git.chromium.org")) + '/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git@77bf6edb0138e3a38a2772248696f130dab45e34', + 'src/third_party/httpcomponents-client': + (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c', + 'src/third_party/findbugs': + (Var("git.chromium.org")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12', + 'src/third_party/lss': + (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb', + 'src/third_party/android_protobuf/src': + (Var("git.chromium.org")) + '/external/android_protobuf.git@94f522f907e3f34f70d9e7816b947e62fddbb267', + 'src/third_party/jsr-305/src': + (Var("git.chromium.org")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919', + 'src/third_party/httpcomponents-core': + (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62' } +} deps = { 'depot_tools': @@ -262,8 +262,6 @@ deps = { (Var("git.chromium.org")) + '/external/bidichecker/lib.git@97f2aa645b74c28c57eca56992235c79850fa9e0', 'src/third_party/libc++/trunk': (Var("git.chromium.org")) + '/chromium/llvm-project/libcxx.git@48198f9110397fff47fe7c37cbfa296be7d44d3d', - 'src/third_party/colorama/src': - (Var("git.chromium.org")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/libwebm/source': (Var("git.chromium.org")) + '/webm/libwebm.git@0d4cb404ea4195e5e21d04db2c955615535ce62e', 'src/third_party/usrsctp/usrsctplib': @@ -374,20 +372,22 @@ deps = { (Var("git.chromium.org")) + '/chromium/deps/icu52.git@d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174', 'src/third_party/opus/src': (Var("git.chromium.org")) + '/chromium/deps/opus.git@cae696156f1e60006e39821e79a1811ae1933c69', - 'src/tools/grit': - (Var("git.chromium.org")) + '/external/grit-i18n.git@740badd5e3e44434a9a47b5d16749daac1e8ea80', + 'src/third_party/colorama/src': + (Var("git.chromium.org")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/snappy/src': (Var("git.chromium.org")) + '/external/snappy.git@762bb32f0c9d2f31ba4958c7c0933d22e80c20bf', 'src/third_party/webpagereplay': (Var("git.chromium.org")) + '/external/web-page-replay.git@2f7b704b8b567983c040f555d3e46f9766db8e87', 'src/third_party/WebKit': - (Var("git.chromium.org")) + '/chromium/blink.git@46701e45dce4e844a0a1d14d69a91a509587aba1', + (Var("git.chromium.org")) + '/chromium/blink.git@e17a1818a3674776f83cb20461e90763d28bf1c9', 'src/breakpad/src': (Var("git.chromium.org")) + '/external/google-breakpad/src.git@35189355da4b65ed5e7692f790c240a9ab347731', 'src/third_party/hunspell': (Var("git.chromium.org")) + '/chromium/deps/hunspell.git@c956c0e97af00ef789afb2f64d02c9a5a50e6eb1', 'src/tools/deps2git': (Var("git.chromium.org")) + '/chromium/tools/deps2git.git@f04828eb0b5acd3e7ad983c024870f17f17b06d9', + 'src/tools/grit': + (Var("git.chromium.org")) + '/external/grit-i18n.git@740badd5e3e44434a9a47b5d16749daac1e8ea80', 'src/third_party/libjpeg_turbo': (Var("git.chromium.org")) + '/chromium/deps/libjpeg_turbo.git@034e9a9747e0983bc19808ea70e469bc8342081f', 'src/testing/gtest': diff --git a/src/build/android/pylib/gtest/setup.py b/src/build/android/pylib/gtest/setup.py index 2782859..6a9e65b 100644 --- a/src/build/android/pylib/gtest/setup.py +++ b/src/build/android/pylib/gtest/setup.py @@ -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', diff --git a/src/build/util/LASTCHANGE b/src/build/util/LASTCHANGE index 207e3ce..e823590 100644 --- a/src/build/util/LASTCHANGE +++ b/src/build/util/LASTCHANGE @@ -1 +1 @@ -LASTCHANGE=ea46c0b6279a60b0173a092f0e9f0403a2a047a9 +LASTCHANGE=0bbff352135bacf2e6a17b5ffebd387f3c2d085f diff --git a/src/build/util/LASTCHANGE.blink b/src/build/util/LASTCHANGE.blink index 2fb81d9..9ed5759 100644 --- a/src/build/util/LASTCHANGE.blink +++ b/src/build/util/LASTCHANGE.blink @@ -1 +1 @@ -LASTCHANGE=1620ccec09abbd0dae196999fbcd94505136b306 +LASTCHANGE=dc24b658e6b89accb1e21a14bc06dc72bfc00c41 diff --git a/src/chrome/VERSION b/src/chrome/VERSION index e93a31c..3f7bfc2 100644 --- a/src/chrome/VERSION +++ b/src/chrome/VERSION @@ -1,4 +1,4 @@ MAJOR=39 MINOR=0 BUILD=2171 -PATCH=62 +PATCH=71 diff --git a/src/chrome/app/generated_resources.grd b/src/chrome/app/generated_resources.grd index 56f7986..be03be6 100644 --- a/src/chrome/app/generated_resources.grd +++ b/src/chrome/app/generated_resources.grd @@ -6525,6 +6525,14 @@ Keep your key file in a safe place. You will need it to create new versions of y 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. + + + Enable Link Disambiguation Popup. + + + Enable the zoomed bubble that appears on touchscreens when accidentally touching more than one link at a time. + + diff --git a/src/chrome/browser/about_flags.cc b/src/chrome/browser/about_flags.cc index 6004fab..0d9d667 100644 --- a/src/chrome/browser/about_flags.cc +++ b/src/chrome/browser/about_flags.cc @@ -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) { diff --git a/src/chrome/browser/chromeos/login/oobe_browsertest.cc b/src/chrome/browser/chromeos/login/oobe_browsertest.cc index 9241cbd..53b218a 100644 --- a/src/chrome/browser/chromeos/login/oobe_browsertest.cc +++ b/src/chrome/browser/chromeos/login/oobe_browsertest.cc @@ -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::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 diff --git a/src/chrome/browser/defaults.cc b/src/chrome/browser/defaults.cc index ff39b1d..6d6b6b6 100644 --- a/src/chrome/browser/defaults.cc +++ b/src/chrome/browser/defaults.cc @@ -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; diff --git a/src/chrome/browser/defaults.h b/src/chrome/browser/defaults.h index 157d561..41b16d6 100644 --- a/src/chrome/browser/defaults.h +++ b/src/chrome/browser/defaults.h @@ -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; diff --git a/src/chrome/browser/renderer_preferences_util.cc b/src/chrome/browser/renderer_preferences_util.cc index 7f67482..519e63b 100644 --- a/src/chrome/browser/renderer_preferences_util.cc +++ b/src/chrome/browser/renderer_preferences_util.cc @@ -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) diff --git a/src/chrome/browser/sync/test/integration/enable_disable_test.cc b/src/chrome/browser/sync/test/integration/enable_disable_test.cc index fdb7f57..957720e 100644 --- a/src/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/src/chrome/browser/sync/test/integration/enable_disable_test.cc @@ -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. diff --git a/src/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc b/src/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc index 55176d2..d2a1970 100644 --- a/src/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc +++ b/src/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc @@ -178,9 +178,6 @@ void ChromeWebContentsViewDelegateViews::ShowDisambiguationPopup( const base::Callback& gesture_cb, const base::Callback& 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); diff --git a/src/components/sync_driver/sync_prefs.cc b/src/components/sync_driver/sync_prefs.cc index cc7914d..fd5ffb2 100644 --- a/src/components/sync_driver/sync_prefs.cc +++ b/src/components/sync_driver/sync_prefs.cc @@ -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); } diff --git a/src/components/sync_driver/sync_prefs_unittest.cc b/src/components/sync_driver/sync_prefs_unittest.cc index 683d55a..fb8dddb 100644 --- a/src/components/sync_driver/sync_prefs_unittest.cc +++ b/src/components/sync_driver/sync_prefs_unittest.cc @@ -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 diff --git a/src/content/browser/renderer_host/render_process_host_impl.cc b/src/content/browser/renderer_host/render_process_host_impl.cc index 9e46f22..ef9570f 100644 --- a/src/content/browser/renderer_host/render_process_host_impl.cc +++ b/src/content/browser/renderer_host/render_process_host_impl.cc @@ -1132,6 +1132,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kEnableGPUClientLogging, switches::kEnableGpuClientTracing, switches::kEnableGPUServiceLogging, + switches::kEnableLinkDisambiguationPopup, switches::kEnableLowResTiling, switches::kEnableInbandTextTracks, switches::kEnableLCDText, diff --git a/src/content/content_tests.gypi b/src/content/content_tests.gypi index ba9da06..e311974 100644 --- a/src/content/content_tests.gypi +++ b/src/content/content_tests.gypi @@ -838,21 +838,6 @@ '../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', diff --git a/src/content/content_unittests.isolate b/src/content/content_unittests.isolate index 87a4ee9..7f4f9c4 100644 --- a/src/content/content_unittests.isolate +++ b/src/content/content_unittests.isolate @@ -56,13 +56,6 @@ ], }, }], - ['OS=="linux" and libpeer_target_type=="loadable_module"', { - 'variables': { - 'isolate_dependency_tracked': [ - '<(PRODUCT_DIR)/lib/libpeerconnection.so', - ], - }, - }], ['OS=="mac"', { 'variables': { 'command': [ @@ -98,13 +91,6 @@ ], }, }], - ['OS=="win" and libpeer_target_type=="loadable_module"', { - 'variables': { - 'isolate_dependency_tracked': [ - '<(PRODUCT_DIR)/libpeerconnection.dll', - ], - }, - }], ], 'includes': [ '../base/base.isolate', diff --git a/src/content/renderer/media/media_stream_audio_processor.cc b/src/content/renderer/media/media_stream_audio_processor.cc index ac41187..4efc507 100644 --- a/src/content/renderer/media/media_stream_audio_processor.cc +++ b/src/content/renderer/media/media_stream_audio_processor.cc @@ -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) { diff --git a/src/content/renderer/media/media_stream_audio_processor_options.cc b/src/content/renderer/media/media_stream_audio_processor_options.cc index 8462a65..e386308 100644 --- a/src/content/renderer/media/media_stream_audio_processor_options.cc +++ b/src/content/renderer/media/media_stream_audio_processor_options.cc @@ -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) { diff --git a/src/content/renderer/render_view_impl.cc b/src/content/renderer/render_view_impl.cc index 453fffa..edb7ab5 100644 --- a/src/content/renderer/render_view_impl.cc +++ b/src/content/renderer/render_view_impl.cc @@ -4031,6 +4031,9 @@ bool RenderViewImpl::didTapMultipleTargets( const WebSize& inner_viewport_offset, const WebRect& touch_rect, const WebVector& 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 = diff --git a/src/third_party/WebKit/Source/web/LinkHighlight.cpp b/src/third_party/WebKit/Source/web/LinkHighlight.cpp index afaed96..611fa8a 100644 --- a/src/third_party/WebKit/Source/web/LinkHighlight.cpp +++ b/src/third_party/WebKit/Source/web/LinkHighlight.cpp @@ -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() diff --git a/src/third_party/WebKit/Source/web/LinkHighlight.h b/src/third_party/WebKit/Source/web/LinkHighlight.h index cea39b0..47c203e 100644 --- a/src/third_party/WebKit/Source/web/LinkHighlight.h +++ b/src/third_party/WebKit/Source/web/LinkHighlight.h @@ -39,7 +39,6 @@ namespace blink { -class DisplayList; class Node; class RenderLayer; class RenderObject; @@ -86,7 +85,6 @@ private: OwnPtr m_contentLayer; OwnPtr m_clipLayer; Path m_path; - RefPtr m_displayList; RefPtrWillBePersistent m_node; WebViewImpl* m_owningWebViewImpl; diff --git a/src/third_party/libjingle/BUILD.gn b/src/third_party/libjingle/BUILD.gn index 69a744e..02c2bf9 100644 --- a/src/third_party/libjingle/BUILD.gn +++ b/src/third_party/libjingle/BUILD.gn @@ -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", ] diff --git a/src/third_party/libjingle/libjingle.gyp b/src/third_party/libjingle/libjingle.gyp index 63a5230..0eaf86c 100644 --- a/src/third_party/libjingle/libjingle.gyp +++ b/src/third_party/libjingle/libjingle.gyp @@ -589,7 +589,6 @@ '<(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', diff --git a/src/third_party/libjingle/overrides/init_webrtc.cc b/src/third_party/libjingle/overrides/init_webrtc.cc index 0004d8e..ab89d58 100644 --- a/src/third_party/libjingle/overrides/init_webrtc.cc +++ b/src/third_party/libjingle/overrides/init_webrtc.cc @@ -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 diff --git a/src/third_party/libjingle/overrides/init_webrtc.h b/src/third_party/libjingle/overrides/init_webrtc.h index 4d06e9e..c5c190c 100644 --- a/src/third_party/libjingle/overrides/init_webrtc.h +++ b/src/third_party/libjingle/overrides/init_webrtc.h @@ -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_ diff --git a/src/third_party/libjingle/overrides/initialize_module.cc b/src/third_party/libjingle/overrides/initialize_module.cc index b84e2d8..ce11567 100644 --- a/src/third_party/libjingle/overrides/initialize_module.cc +++ b/src/third_party/libjingle/overrides/initialize_module.cc @@ -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) diff --git a/src/tools/metrics/histograms/histograms.xml b/src/tools/metrics/histograms/histograms.xml index ef70a5a..858a12d 100644 --- a/src/tools/metrics/histograms/histograms.xml +++ b/src/tools/metrics/histograms/histograms.xml @@ -45643,6 +45643,7 @@ To add a new entry, add it with any value and run test to compute valid value. + @@ -45799,6 +45800,7 @@ To add a new entry, add it with any value and run test to compute valid value. + diff --git a/src/ui/base/ui_base_switches.cc b/src/ui/base/ui_base_switches.cc index 3bf7de0..11416ee 100644 --- a/src/ui/base/ui_base_switches.cc +++ b/src/ui/base/ui_base_switches.cc @@ -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"; diff --git a/src/ui/base/ui_base_switches.h b/src/ui/base/ui_base_switches.h index a23c920..ce267fb 100644 --- a/src/ui/base/ui_base_switches.h +++ b/src/ui/base/ui_base_switches.h @@ -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[]; diff --git a/src/ui/base/ui_base_switches_util.cc b/src/ui/base/ui_base_switches_util.cc index ba20e53..f562ea4 100644 --- a/src/ui/base/ui_base_switches_util.cc +++ b/src/ui/base/ui_base_switches_util.cc @@ -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); diff --git a/src/ui/base/ui_base_switches_util.h b/src/ui/base/ui_base_switches_util.h index 8dbc408..3988f6d 100644 --- a/src/ui/base/ui_base_switches_util.h +++ b/src/ui/base/ui_base_switches_util.h @@ -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(); diff --git a/src/xwalk/DEPS.xwalk b/src/xwalk/DEPS.xwalk index e085009..66e32ed 100644 --- a/src/xwalk/DEPS.xwalk +++ b/src/xwalk/DEPS.xwalk @@ -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' diff --git a/src/xwalk/VERSION b/src/xwalk/VERSION index 0af64ea..3ef08e0 100644 --- a/src/xwalk/VERSION +++ b/src/xwalk/VERSION @@ -1,4 +1,4 @@ MAJOR=11 MINOR=39 -BUILD=260 +BUILD=264 PATCH=0 diff --git a/src/xwalk/app/android/app_hello_world/res/drawable-hdpi/crosswalk.png b/src/xwalk/app/android/app_hello_world/res/drawable-hdpi/crosswalk.png index 5989755..7632a2e 100644 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 diff --git a/src/xwalk/app/android/app_hello_world/res/drawable-ldpi/crosswalk.png b/src/xwalk/app/android/app_hello_world/res/drawable-ldpi/crosswalk.png index e87864a..dbbcb3d 100644 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 diff --git a/src/xwalk/app/android/app_hello_world/res/drawable-mdpi/crosswalk.png b/src/xwalk/app/android/app_hello_world/res/drawable-mdpi/crosswalk.png index fc19a3e..90c660e 100644 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 diff --git a/src/xwalk/app/android/app_hello_world/res/drawable-xhdpi/crosswalk.png b/src/xwalk/app/android/app_hello_world/res/drawable-xhdpi/crosswalk.png index b69b4e8..9aeeff7 100644 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 diff --git a/src/xwalk/app/android/app_template/res/drawable-hdpi/crosswalk.png b/src/xwalk/app/android/app_template/res/drawable-hdpi/crosswalk.png index 5989755..7632a2e 100644 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 diff --git a/src/xwalk/app/android/app_template/res/drawable-ldpi/crosswalk.png b/src/xwalk/app/android/app_template/res/drawable-ldpi/crosswalk.png index e87864a..dbbcb3d 100644 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 diff --git a/src/xwalk/app/android/app_template/res/drawable-mdpi/crosswalk.png b/src/xwalk/app/android/app_template/res/drawable-mdpi/crosswalk.png index fc19a3e..90c660e 100644 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 diff --git a/src/xwalk/app/android/app_template/res/drawable-xhdpi/crosswalk.png b/src/xwalk/app/android/app_template/res/drawable-xhdpi/crosswalk.png index b69b4e8..9aeeff7 100644 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 diff --git a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_144.png b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_144.png index b69b4e8..9aeeff7 100644 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 diff --git a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_48.png b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_48.png index e87864a..dbbcb3d 100644 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 diff --git a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_72.png b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_72.png index fc19a3e..90c660e 100644 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 diff --git a/src/xwalk/app/tools/android/test_data/manifest/icons/icon_96.png b/src/xwalk/app/tools/android/test_data/manifest/icons/icon_96.png index 5989755..7632a2e 100644 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 diff --git a/src/xwalk/application/browser/application_service.cc b/src/xwalk/application/browser/application_service.cc index 2dbc11d..4adb166 100644 --- a/src/xwalk/application/browser/application_service.cc +++ b/src/xwalk/application/browser/application_service.cc @@ -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, diff --git a/src/xwalk/application/browser/application_system_linux.cc b/src/xwalk/application/browser/application_system_linux.cc index e8f0130..339e093 100644 --- a/src/xwalk/application/browser/application_system_linux.cc +++ b/src/xwalk/application/browser/application_system_linux.cc @@ -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() {} diff --git a/src/xwalk/application/common/manifest_handlers/csp_handler_unittest.cc b/src/xwalk/application/common/manifest_handlers/csp_handler_unittest.cc index 8829982..495c0ef 100644 --- a/src/xwalk/application/common/manifest_handlers/csp_handler_unittest.cc +++ b/src/xwalk/application/common/manifest_handlers/csp_handler_unittest.cc @@ -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 CreateApplication() { - std::string error; - scoped_refptr 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 application) { + const CSPInfo* info = static_cast( + application->GetManifestData(GetCSPKey(application->manifest_type()))); + return info; +} - const CSPInfo* GetCSPInfo( - scoped_refptr application) { - const CSPInfo* info = static_cast( - 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 application = CreateApplication(); + scoped_ptr manifest = CreateDefaultManifestConfig(); + scoped_refptr 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 application = CreateApplication(); + scoped_ptr manifest = CreateDefaultManifestConfig(); + manifest->SetString(keys::kCSPKey, ""); + scoped_refptr 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 application = CreateApplication(); + scoped_ptr manifest = CreateDefaultManifestConfig(); + manifest->SetString(keys::kCSPKey, "default-src 'self' "); + scoped_refptr application = + CreateApplication(Manifest::TYPE_MANIFEST, *manifest); EXPECT_TRUE(application.get()); const std::map >& 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 application = CreateApplication(); + scoped_ptr manifest = CreateDefaultWidgetConfig(); + manifest->SetString(widget_keys::kCSPKey, ""); + scoped_refptr 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 application = CreateApplication(); + scoped_ptr manifest = CreateDefaultWidgetConfig(); + manifest->SetString(widget_keys::kCSPKey, "default-src 'self' "); + scoped_refptr application = + CreateApplication(Manifest::TYPE_WIDGET, *manifest); EXPECT_TRUE(application.get()); EXPECT_TRUE(GetCSPInfo(application)); const std::map >& policies = diff --git a/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler.cc b/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler.cc index 2edbd58..03d0d7a 100644 --- a/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler.cc +++ b/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler.cc @@ -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 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 index 0000000..de42388 --- /dev/null +++ b/src/xwalk/application/common/manifest_handlers/tizen_appwidget_handler_unittest.cc @@ -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 +#include +#include +#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 application) { + const TizenAppWidgetInfo* info = static_cast( + 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 CreateTizenElement() { + scoped_ptr result(new base::DictionaryValue); + result->SetString(keys::kNamespaceKey, keys::kTizenNamespacePrefix); + return result.Pass(); +} + +// Creates a dictionary representing an app-widget element. +scoped_ptr 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 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 CreateBoxLabel( + const std::string& label, const std::string& lang = std::string()) { + scoped_ptr 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 CreateBoxIcon(const std::string& src) { + scoped_ptr result = CreateTizenElement(); + SetNotEmptyString(keys::kTizenAppWidgetBoxIconSrcKey, src, result.get()); + return result.Pass(); +} + +// Creates a dictionary representing a box-content element. +scoped_ptr CreateBoxContent( + const std::string& src, const std::string& mouse_event = std::string(), + const std::string& touch_effect = std::string()) { + scoped_ptr 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 CreateBoxSize( + const std::string& type, const std::string& preview = std::string(), + const std::string& use_decoration = std::string()) { + scoped_ptr 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 CreateBoxDropView( + const std::string& src, const std::string& width, + const std::string& height) { + scoped_ptr 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 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 CreateMinimalAppWidget( + const std::string& name, const std::string& primary) { + std::string id = CreateAppWidgetId(name); + + scoped_ptr result = CreateAppWidget(id, primary); + + CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey, + CreateBoxLabel("sample label"), result.get())); + + scoped_ptr 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 CreateFullAppWidget( + const std::string& name, const std::string& primary) { + std::string id = CreateAppWidgetId(name); + + scoped_ptr 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 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 parts; + base::SplitString(path, '.', &parts); + for (size_t i = 0, count = parts.size(); i < count; ++i) { + const std::string& part = parts[i]; + + std::vector 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr app_widget = + CreateFullAppWidget("first", "true"); + + CHECK(AddDictionary(keys::kTizenAppWidgetFullKey, + app_widget.Pass(), manifest.get())); + + CHECK(ChangeOrRemove(path, manifest.get(), value)); + + scoped_refptr 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 manifest = CreateDefaultWidgetConfig(); + + scoped_refptr 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr app_widget = + CreateMinimalAppWidget("first", "true"); + + CHECK(AddDictionary(keys::kTizenAppWidgetFullKey, + app_widget.Pass(), manifest.get())); + + scoped_refptr 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 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr 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 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 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr app_widget = + CreateFullAppWidget("first", "true"); + + CHECK(AddDictionary(keys::kTizenAppWidgetFullKey, + app_widget.Pass(), manifest.get())); + + scoped_refptr 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 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr app_widget = + CreateFullAppWidget("first", "true"); + + scoped_ptr 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 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr 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 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 manifest = CreateDefaultWidgetConfig(); + + scoped_ptr 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 application = + CreateApplication(Manifest::TYPE_WIDGET, *manifest); + EXPECT_EQ(nullptr, application.get()); +} + +} // namespace application +} // namespace xwalk diff --git a/src/xwalk/application/common/manifest_handlers/unittest_util.cc b/src/xwalk/application/common/manifest_handlers/unittest_util.cc index 64c6171..6401d10 100644 --- a/src/xwalk/application/common/manifest_handlers/unittest_util.cc +++ b/src/xwalk/application/common/manifest_handlers/unittest_util.cc @@ -4,7 +4,7 @@ #include "xwalk/application/common/manifest_handlers/unittest_util.h" -#include +#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 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 CreateDefaultManifestConfig() { scoped_ptr 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 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 CreateApplication(Manifest::Type type, return application; } +std::string MakeElementPath(const std::string& parent, + const std::string& element) { + std::vector parts; + parts.push_back(parent); + parts.push_back(element); + return JoinString(parts, '.'); +} + +bool AddDictionary(const std::string& key, + scoped_ptr child, base::DictionaryValue* parent) { + if (key.empty() || !child || !parent) + return false; + + scoped_ptr existing_child; + base::DictionaryValue* unused; + if (parent->GetDictionary(key, &unused)) { + if (!parent->Remove(key, &existing_child)) + return false; + } + + if (existing_child) { + scoped_ptr 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 diff --git a/src/xwalk/application/common/manifest_handlers/unittest_util.h b/src/xwalk/application/common/manifest_handlers/unittest_util.h index a921cbf..b53ac2a 100644 --- a/src/xwalk/application/common/manifest_handlers/unittest_util.h +++ b/src/xwalk/application/common/manifest_handlers/unittest_util.h @@ -5,6 +5,8 @@ #ifndef XWALK_APPLICATION_COMMON_MANIFEST_HANDLERS_UNITTEST_UTIL_H_ #define XWALK_APPLICATION_COMMON_MANIFEST_HANDLERS_UNITTEST_UTIL_H_ +#include +#include #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" @@ -14,12 +16,41 @@ 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 CreateDefaultManifestConfig(); + +// Creates a minimal valid widget configuration. scoped_ptr CreateDefaultWidgetConfig(); +// Creates an ApplicationData for specified configuration data. scoped_refptr 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 child, base::DictionaryValue* parent); + } // namespace application } // namespace xwalk diff --git a/src/xwalk/application/common/manifest_handlers/widget_handler.cc b/src/xwalk/application/common/manifest_handlers/widget_handler.cc index c5aa5b3..50a7e7e 100644 --- a/src/xwalk/application/common/manifest_handlers/widget_handler.cc +++ b/src/xwalk/application/common/manifest_handlers/widget_handler.cc @@ -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; diff --git a/src/xwalk/application/common/manifest_handlers/widget_handler_unittest.cc b/src/xwalk/application/common/manifest_handlers/widget_handler_unittest.cc index b750627..ffc23b7 100644 --- a/src/xwalk/application/common/manifest_handlers/widget_handler_unittest.cc +++ b/src/xwalk/application/common/manifest_handlers/widget_handler_unittest.cc @@ -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 CreateApplication( - const base::DictionaryValue& manifest) { - std::string error; - scoped_refptr 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 application) { + WidgetInfo* info = static_cast( + application->GetManifestData(keys::kWidgetKey)); + return info; +} - WidgetInfo* GetWidgetInfo(scoped_refptr application) { - WidgetInfo* info = static_cast( - application->GetManifestData(keys::kWidgetKey)); - return info; - } +template +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(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(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 application = CreateApplication(manifest); + scoped_ptr manifest = CreateDefaultWidgetConfig(); + manifest->SetString(keys::kWidgetNamespaceKey, keys::kWidgetNamespacePrefix); + scoped_refptr 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 manifest(new base::DictionaryValue); + scoped_ptr manifest = CreateDefaultWidgetConfig(); SetAllInfoToManifest(manifest.get()); - manifest->Set(keys::kPreferencesKey, GetPreferencesItem(0, true)); + manifest->Set(keys::kPreferencesKey, + GetPreferencesItem(0)); // Create an application use this manifest. - scoped_refptr application; - application = CreateApplication(*(manifest.get())); + scoped_refptr 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 Copy(info->GetWidgetInfo()->DeepCopy()); + scoped_ptr + 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 widget(new base::DictionaryValue); SetAllInfoToWidget(widget.get()); - widget->Set(kWidgetPreferences, GetPreferencesItem(0, false)); + widget->Set(kWidgetPreferences, + GetPreferencesItem(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 manifest(new base::DictionaryValue); + scoped_ptr 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(i)); } + // TODO(aszafranek): Set manifestPreferences to manifest and test it below // Create an application use this manifest, - scoped_refptr application; - application = CreateApplication(*(manifest.get())); + scoped_refptr 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 Copy(info->GetWidgetInfo()->DeepCopy()); + scoped_ptr + 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 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(i)); } // Compare the widget parsed from manifest with @@ -223,13 +229,13 @@ TEST_F(WidgetHandlerTest, TEST_F(WidgetHandlerTest, ParseManifestWithInvalidAuthorHrefValue) { - scoped_ptr manifest(new base::DictionaryValue); + scoped_ptr manifest = CreateDefaultWidgetConfig(); SetAllInfoToManifest(manifest.get()); manifest->SetString(keys::kAuthorHrefKey, "INVALID_HREF"); // Create an application use this manifest, - scoped_refptr application; - application = CreateApplication(*(manifest.get())); + scoped_refptr 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 diff --git a/src/xwalk/application/common/package/xpk_package.cc b/src/xwalk/application/common/package/xpk_package.cc index 17c09d4..4f04268 100644 --- a/src/xwalk/application/common/package/xpk_package.cc +++ b/src/xwalk/application/common/package/xpk_package.cc @@ -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; diff --git a/src/xwalk/application/extension/application_widget_api.js b/src/xwalk/application/extension/application_widget_api.js index 5548b2a..c9226ca 100644 --- a/src/xwalk/application/extension/application_widget_api.js +++ b/src/xwalk/application/extension/application_widget_api.js @@ -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(); diff --git a/src/xwalk/application/extension/application_widget_extension.cc b/src/xwalk/application/extension/application_widget_extension.cc index af28a65..fb94b01 100644 --- a/src/xwalk/application/extension/application_widget_extension.cc +++ b/src/xwalk/application/extension/application_widget_extension.cc @@ -4,10 +4,15 @@ #include "xwalk/application/extension/application_widget_extension.h" +#include + #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" @@ -27,12 +32,51 @@ 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 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 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 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 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 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 AppWidgetExtensionInstance::ClearAllItems( scoped_ptr result( new base::FundamentalValue(false)); - if (widget_storage_->Clear()) - result.reset(new base::FundamentalValue(true)); + scoped_ptr 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 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 AppWidgetExtensionInstance::GetAllItems( return result.Pass(); } +scoped_ptr AppWidgetExtensionInstance::GetItemValueByKey( + scoped_ptr 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 result(new base::StringValue(value)); + return result.Pass(); +} + scoped_ptr AppWidgetExtensionInstance::KeyExists( scoped_ptr msg) const { scoped_ptr result( @@ -203,5 +311,17 @@ scoped_ptr AppWidgetExtensionInstance::KeyExists( return result.Pass(); } +void AppWidgetExtensionInstance::PostMessageToOtherFrames( + scoped_ptr msg) { + const std::vector& runtime_set = application_->runtimes(); + std::vector::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 diff --git a/src/xwalk/application/extension/application_widget_extension.h b/src/xwalk/application/extension/application_widget_extension.h index b37ddc4..4e44851 100644 --- a/src/xwalk/application/extension/application_widget_extension.h +++ b/src/xwalk/application/extension/application_widget_extension.h @@ -7,7 +7,6 @@ #include -#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 mgs); scoped_ptr ClearAllItems(scoped_ptr mgs); scoped_ptr GetAllItems(scoped_ptr mgs); + scoped_ptr GetItemValueByKey(scoped_ptr mgs); scoped_ptr KeyExists( scoped_ptr mgs) const; + void PostMessageToOtherFrames(scoped_ptr msg); Application* application_; scoped_ptr widget_storage_; - XWalkExtensionFunctionHandler handler_; }; } // namespace application diff --git a/src/xwalk/application/extension/application_widget_storage.cc b/src/xwalk/application/extension/application_widget_storage.cc index 7dc6caa..dd95166 100644 --- a/src/xwalk/application/extension/application_widget_storage.cc +++ b/src/xwalk/application/extension/application_widget_storage.cc @@ -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)); diff --git a/src/xwalk/application/extension/application_widget_storage.h b/src/xwalk/application/extension/application_widget_storage.h index ad83ed6..58412a6 100644 --- a/src/xwalk/application/extension/application_widget_storage.h +++ b/src/xwalk/application/extension/application_widget_storage.h @@ -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 index 2e7f3c3..0000000 --- a/src/xwalk/application/tools/linux/dbus_connection.cc +++ /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 index 022eee5..0000000 --- a/src/xwalk/application/tools/linux/dbus_connection.h +++ /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 - -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 index 0000000..feccbcc --- /dev/null +++ b/src/xwalk/application/tools/linux/dbus_object_manager.cc @@ -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 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 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 DBusObjectManager::GetEPChannel() const { + std::pair fd; + if (!app_proxy_) { + fd.second = -1; + return fd; + } + dbus::MethodCall method_call(kRunningAppIface, "GetEPChannel"); + scoped_ptr 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 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 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(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 objects = running_apps_manager_->GetObjects(); + bool is_running = false; + for (dbus::ObjectPath obj : objects) { + Properties* properties = + static_cast( + 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 index 0000000..ccb9fb2 --- /dev/null +++ b/src/xwalk/application/tools/linux/dbus_object_manager.h @@ -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 +#include +#include +#include + +#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 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 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 weak_ptr_factory_; + + Observer* observer_; + + DISALLOW_COPY_AND_ASSIGN(DBusObjectManager); +}; + +#endif // XWALK_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_ diff --git a/src/xwalk/application/tools/linux/xwalk_application_tools.gyp b/src/xwalk/application/tools/linux/xwalk_application_tools.gyp index a70f1b4..e3bc48d 100644 --- a/src/xwalk/application/tools/linux/xwalk_application_tools.gyp +++ b/src/xwalk/application/tools/linux/xwalk_application_tools.gyp @@ -12,10 +12,11 @@ '../../../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 index 0000000..04964d5 --- /dev/null +++ b/src/xwalk/application/tools/linux/xwalk_launcher.cc @@ -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 + +#include +#include +#include + +#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 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 index 0000000..e4c0533 --- /dev/null +++ b/src/xwalk/application/tools/linux/xwalk_launcher.h @@ -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 +#include + +#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 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 dbus_object_manager_; + + private: + bool InitExtensionProcessChannel(); + virtual void OnEPChannelCreated() override; + + std::unique_ptr dbus_thread_; +}; + +#endif // XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_H_ diff --git a/src/xwalk/application/tools/linux/xwalk_launcher_main.cc b/src/xwalk/application/tools/linux/xwalk_launcher_main.cc index 46c956b..8ea14b7 100644 --- a/src/xwalk/application/tools/linux/xwalk_launcher_main.cc +++ b/src/xwalk/application/tools/linux/xwalk_launcher_main.cc @@ -1,272 +1,48 @@ // 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 -#include -#include -#include -#include -#include -#include -#include - #include -#include -#include -#include "xwalk/application/tools/linux/dbus_connection.h" -#include "xwalk/application/tools/linux/xwalk_extension_process_launcher.h" +#include + +#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(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(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 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; } diff --git a/src/xwalk/application/tools/linux/xwalk_launcher_tizen.cc b/src/xwalk/application/tools/linux/xwalk_launcher_tizen.cc index a26b053..8aa67b7 100644 --- a/src/xwalk/application/tools/linux/xwalk_launcher_tizen.cc +++ b/src/xwalk/application/tools/linux/xwalk_launcher_tizen.cc @@ -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 -#include +#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h" + +#include +#include #include -#include #include -#include -#include +#include -#include "xwalk/application/common/id_util.h" -#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h" +#include -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(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(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//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; } diff --git a/src/xwalk/application/tools/linux/xwalk_launcher_tizen.h b/src/xwalk/application/tools/linux/xwalk_launcher_tizen.h index 75237bd..a0c8f3f 100644 --- a/src/xwalk/application/tools/linux/xwalk_launcher_tizen.h +++ b/src/xwalk/application/tools/linux/xwalk_launcher_tizen.h @@ -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 +#include -int xwalk_change_cmdline(int argc, char** argv, const char* app_id); +#include +#include + +#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_ diff --git a/src/xwalk/application/tools/tizen/xwalk_backend.cc b/src/xwalk/application/tools/tizen/xwalk_backend.cc index 862a47b..148155b 100644 --- a/src/xwalk/application/tools/tizen/xwalk_backend.cc +++ b/src/xwalk/application/tools/tizen/xwalk_backend.cc @@ -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" diff --git a/src/xwalk/application/tools/tizen/xwalk_tizen_tools.gyp b/src/xwalk/application/tools/tizen/xwalk_tizen_tools.gyp index ba5abfd..9a6a0c2 100644 --- a/src/xwalk/application/tools/tizen/xwalk_tizen_tools.gyp +++ b/src/xwalk/application/tools/tizen/xwalk_tizen_tools.gyp @@ -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', ], diff --git a/src/xwalk/build/common.gypi b/src/xwalk/build/common.gypi index c28789e..e076d38 100644 --- a/src/xwalk/build/common.gypi +++ b/src/xwalk/build/common.gypi @@ -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'], }], diff --git a/src/xwalk/dbus/object_manager_adaptor.cc b/src/xwalk/dbus/object_manager_adaptor.cc index 96a0878..903b873 100644 --- a/src/xwalk/dbus/object_manager_adaptor.cc +++ b/src/xwalk/dbus/object_manager_adaptor.cc @@ -168,7 +168,7 @@ ManagedObject::~ManagedObject() {} ObjectPath ManagedObject::path() const { return path_; -}; +} void ManagedObject::AppendAllPropertiesToWriter(MessageWriter* writer) const { MessageWriter interfaces_writer(NULL); diff --git a/src/xwalk/extensions/browser/xwalk_extension_function_handler.h b/src/xwalk/extensions/browser/xwalk_extension_function_handler.h index 75c8a2b..b278860 100644 --- a/src/xwalk/extensions/browser/xwalk_extension_function_handler.h +++ b/src/xwalk/extensions/browser/xwalk_extension_function_handler.h @@ -37,7 +37,7 @@ class XWalkExtensionFunctionInfo { // be called from any thread. void PostResult(scoped_ptr result) const { post_result_cb_.Run(result.Pass()); - }; + } std::string name() const { return name_; diff --git a/src/xwalk/extensions/browser/xwalk_extension_process_host.cc b/src/xwalk/extensions/browser/xwalk_extension_process_host.cc index fd03fd5..f8c267d 100644 --- a/src/xwalk/extensions/browser/xwalk_extension_process_host.cc +++ b/src/xwalk/extensions/browser/xwalk_extension_process_host.cc @@ -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(*runtime_variables_), diff --git a/src/xwalk/extensions/common/xwalk_external_instance.cc b/src/xwalk/extensions/common/xwalk_external_instance.cc index 9890bb7..aa47b4c 100644 --- a/src/xwalk/extensions/common/xwalk_external_instance.cc +++ b/src/xwalk/extensions/common/xwalk_external_instance.cc @@ -41,7 +41,10 @@ void XWalkExternalInstance::HandleMessage(scoped_ptr 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 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()); } diff --git a/src/xwalk/packaging/crosswalk.png b/src/xwalk/packaging/crosswalk.png index f693816..9aeeff7 100644 Binary files a/src/xwalk/packaging/crosswalk.png and b/src/xwalk/packaging/crosswalk.png differ diff --git a/src/xwalk/packaging/crosswalk.spec b/src/xwalk/packaging/crosswalk.spec index 8e9c587..4850150 100644 --- a/src/xwalk/packaging/crosswalk.spec +++ b/src/xwalk/packaging/crosswalk.spec @@ -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 diff --git a/src/xwalk/runtime/android/runtime_lib/res/drawable-hdpi/crosswalk.png b/src/xwalk/runtime/android/runtime_lib/res/drawable-hdpi/crosswalk.png index 5989755..7632a2e 100644 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 diff --git a/src/xwalk/runtime/android/runtime_lib/res/drawable-ldpi/crosswalk.png b/src/xwalk/runtime/android/runtime_lib/res/drawable-ldpi/crosswalk.png index e87864a..dbbcb3d 100644 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 diff --git a/src/xwalk/runtime/android/runtime_lib/res/drawable-mdpi/crosswalk.png b/src/xwalk/runtime/android/runtime_lib/res/drawable-mdpi/crosswalk.png index fc19a3e..90c660e 100644 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 diff --git a/src/xwalk/runtime/android/runtime_lib/res/drawable-xhdpi/crosswalk.png b/src/xwalk/runtime/android/runtime_lib/res/drawable-xhdpi/crosswalk.png index b69b4e8..9aeeff7 100644 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 diff --git a/src/xwalk/runtime/android/sample/res/drawable-hdpi/crosswalk.png b/src/xwalk/runtime/android/sample/res/drawable-hdpi/crosswalk.png index 5989755..7632a2e 100644 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 diff --git a/src/xwalk/runtime/android/sample/res/drawable-ldpi/crosswalk.png b/src/xwalk/runtime/android/sample/res/drawable-ldpi/crosswalk.png index e87864a..dbbcb3d 100644 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 diff --git a/src/xwalk/runtime/android/sample/res/drawable-mdpi/crosswalk.png b/src/xwalk/runtime/android/sample/res/drawable-mdpi/crosswalk.png index fc19a3e..90c660e 100644 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 diff --git a/src/xwalk/runtime/android/sample/res/drawable-xhdpi/crosswalk.png b/src/xwalk/runtime/android/sample/res/drawable-xhdpi/crosswalk.png index b69b4e8..9aeeff7 100644 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 diff --git a/src/xwalk/runtime/browser/android/xwalk_settings.cc b/src/xwalk/runtime/browser/android/xwalk_settings.cc index ba26c31..15df5d0 100644 --- a/src/xwalk/runtime/browser/android/xwalk_settings.cc +++ b/src/xwalk/runtime/browser/android/xwalk_settings.cc @@ -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;"; diff --git a/src/xwalk/runtime/browser/runtime_file_select_helper.h b/src/xwalk/runtime/browser/runtime_file_select_helper.h index b94e53d..3c73d1a 100644 --- a/src/xwalk/runtime/browser/runtime_file_select_helper.h +++ b/src/xwalk/runtime/browser/runtime_file_select_helper.h @@ -46,7 +46,7 @@ class RuntimeFileSelectHelper private: friend class base::RefCountedThreadSafe; FRIEND_TEST_ALL_PREFIXES(RuntimeFileSelectHelperTest, IsAcceptTypeValid); - explicit RuntimeFileSelectHelper(); + RuntimeFileSelectHelper(); virtual ~RuntimeFileSelectHelper(); // Utility class which can listen for directory lister events and relay diff --git a/src/xwalk/runtime/browser/runtime_javascript_dialog_manager.h b/src/xwalk/runtime/browser/runtime_javascript_dialog_manager.h index 4fcfbd0..b3a8926 100644 --- a/src/xwalk/runtime/browser/runtime_javascript_dialog_manager.h +++ b/src/xwalk/runtime/browser/runtime_javascript_dialog_manager.h @@ -13,7 +13,7 @@ namespace xwalk { class RuntimeJavaScriptDialogManager : public content::JavaScriptDialogManager { public: - explicit RuntimeJavaScriptDialogManager(); + RuntimeJavaScriptDialogManager(); virtual ~RuntimeJavaScriptDialogManager(); virtual void RunJavaScriptDialog( diff --git a/src/xwalk/runtime/browser/runtime_url_request_context_getter.cc b/src/xwalk/runtime/browser/runtime_url_request_context_getter.cc index ff088cd..c9d12d4 100644 --- a/src/xwalk/runtime/browser/runtime_url_request_context_getter.cc +++ b/src/xwalk/runtime/browser/runtime_url_request_context_getter.cc @@ -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 host_resolver( net::HostResolver::CreateDefaultResolver(NULL)); diff --git a/src/xwalk/runtime/browser/xwalk_browser_main_parts.cc b/src/xwalk/runtime/browser/xwalk_browser_main_parts.cc index 7f95b55..fa642b5 100644 --- a/src/xwalk/runtime/browser/xwalk_browser_main_parts.cc +++ b/src/xwalk/runtime/browser/xwalk_browser_main_parts.cc @@ -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) { diff --git a/src/xwalk/runtime/browser/xwalk_runner.cc b/src/xwalk/runtime/browser/xwalk_runner.cc index 423a64e..fc3507c 100644 --- a/src/xwalk/runtime/browser/xwalk_runner.cc +++ b/src/xwalk/runtime/browser/xwalk_runner.cc @@ -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; diff --git a/src/xwalk/runtime/browser/xwalk_runner.h b/src/xwalk/runtime/browser/xwalk_runner.h index fe46163..f8ac8cc 100644 --- a/src/xwalk/runtime/browser/xwalk_runner.h +++ b/src/xwalk/runtime/browser/xwalk_runner.h @@ -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 CreateSysAppsComponent(); virtual scoped_ptr CreateStorageComponent(); + bool shared_process_mode_enabled_; + private: friend class XWalkMainDelegate; friend class ::XWalkTestSuiteInitializer; diff --git a/src/xwalk/runtime/browser/xwalk_runner_tizen.cc b/src/xwalk/runtime/browser/xwalk_runner_tizen.cc index 8a004ba..3b0a322 100644 --- a/src/xwalk/runtime/browser/xwalk_runner_tizen.cc +++ b/src/xwalk/runtime/browser/xwalk_runner_tizen.cc @@ -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" @@ -12,10 +13,15 @@ #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 diff --git a/src/xwalk/runtime/common/xwalk_paths.cc b/src/xwalk/runtime/common/xwalk_paths.cc index 0971add..dab6783 100644 --- a/src/xwalk/runtime/common/xwalk_paths.cc +++ b/src/xwalk/runtime/common/xwalk_paths.cc @@ -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"); diff --git a/src/xwalk/runtime/common/xwalk_switches.cc b/src/xwalk/runtime/common/xwalk_switches.cc index 43a6e71..7c371aa 100644 --- a/src/xwalk/runtime/common/xwalk_switches.cc +++ b/src/xwalk/runtime/common/xwalk_switches.cc @@ -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"; diff --git a/src/xwalk/runtime/common/xwalk_switches.h b/src/xwalk/runtime/common/xwalk_switches.h index 642a769..049e3fb 100644 --- a/src/xwalk/runtime/common/xwalk_switches.h +++ b/src/xwalk/runtime/common/xwalk_switches.h @@ -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[]; diff --git a/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.cc b/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.cc index e631072..7522608 100644 --- a/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.cc +++ b/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.cc @@ -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) { diff --git a/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h b/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h index 1181e5d..6a54b66 100644 --- a/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h +++ b/src/xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "content/public/renderer/render_view_observer.h" +#include "third_party/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); diff --git a/src/xwalk/runtime/resources/icons/crosswalk.ico b/src/xwalk/runtime/resources/icons/crosswalk.ico index 0a94cab..013e7cc 100644 Binary files a/src/xwalk/runtime/resources/icons/crosswalk.ico and b/src/xwalk/runtime/resources/icons/crosswalk.ico differ diff --git a/src/xwalk/runtime/resources/icons/crosswalk_144x144.png b/src/xwalk/runtime/resources/icons/crosswalk_144x144.png index b69b4e8..9aeeff7 100644 Binary files a/src/xwalk/runtime/resources/icons/crosswalk_144x144.png and b/src/xwalk/runtime/resources/icons/crosswalk_144x144.png differ diff --git a/src/xwalk/runtime/resources/icons/crosswalk_48x48.png b/src/xwalk/runtime/resources/icons/crosswalk_48x48.png index e87864a..dbbcb3d 100644 Binary files a/src/xwalk/runtime/resources/icons/crosswalk_48x48.png and b/src/xwalk/runtime/resources/icons/crosswalk_48x48.png differ diff --git a/src/xwalk/runtime/resources/icons/crosswalk_72x72.png b/src/xwalk/runtime/resources/icons/crosswalk_72x72.png index fc19a3e..90c660e 100644 Binary files a/src/xwalk/runtime/resources/icons/crosswalk_72x72.png and b/src/xwalk/runtime/resources/icons/crosswalk_72x72.png differ diff --git a/src/xwalk/runtime/resources/icons/crosswalk_96x96.png b/src/xwalk/runtime/resources/icons/crosswalk_96x96.png index 5989755..7632a2e 100644 Binary files a/src/xwalk/runtime/resources/icons/crosswalk_96x96.png and b/src/xwalk/runtime/resources/icons/crosswalk_96x96.png differ diff --git a/src/xwalk/sysapps/device_capabilities/device_capabilities_extension.h b/src/xwalk/sysapps/device_capabilities/device_capabilities_extension.h index e2dd96b..40dd07a 100644 --- a/src/xwalk/sysapps/device_capabilities/device_capabilities_extension.h +++ b/src/xwalk/sysapps/device_capabilities/device_capabilities_extension.h @@ -23,7 +23,7 @@ using extensions::XWalkExtensionInstance; class DeviceCapabilitiesExtension : public XWalkExtension { public: - explicit DeviceCapabilitiesExtension(); + DeviceCapabilitiesExtension(); virtual ~DeviceCapabilitiesExtension(); // XWalkExtension implementation. diff --git a/src/xwalk/sysapps/raw_socket/raw_socket_extension.h b/src/xwalk/sysapps/raw_socket/raw_socket_extension.h index 499c54b..e171cb0 100644 --- a/src/xwalk/sysapps/raw_socket/raw_socket_extension.h +++ b/src/xwalk/sysapps/raw_socket/raw_socket_extension.h @@ -19,7 +19,7 @@ using extensions::XWalkExtensionInstance; class RawSocketExtension : public XWalkExtension { public: - explicit RawSocketExtension(); + RawSocketExtension(); virtual ~RawSocketExtension(); // XWalkExtension implementation. diff --git a/src/xwalk/xwalk_tests.gypi b/src/xwalk/xwalk_tests.gypi index e756ede..99a7142 100644 --- a/src/xwalk/xwalk_tests.gypi +++ b/src/xwalk/xwalk_tests.gypi @@ -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', ], }],