%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+)
-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
'eyes-free':
'http://eyes-free.googlecode.com/svn',
'webkit_rev':
- '@46701e45dce4e844a0a1d14d69a91a509587aba1',
+ '@e17a1818a3674776f83cb20461e90763d28bf1c9',
'blink':
'http://src.chromium.org/blink',
'skia':
'src/third_party/bidichecker': None,\r
'src/third_party/libc++/trunk': None,\r
'src/tools/page_cycler/acid3': None,\r
- 'src/third_party/nss':\r
- (Var("git.chromium.org")) + '/chromium/deps/nss.git@87b96db4268293187d7cf741907a6d5d1d8080e0',\r
'src/chrome/test/data/perf/canvas_bench': None,\r
'src/third_party/libexif/sources': None,\r
'src/build/util/support': None,\r
- 'src/third_party/libc++abi/trunk': None,\r
+ 'src/third_party/libsrtp': None,\r
'src/third_party/WebKit/LayoutTests/w3c/csswg-test': None,\r
'src/third_party/pymox/src': None,\r
'src/media/cdm/ppapi/api': None,\r
'src/third_party/openmax_dl': None,\r
'src/third_party/google_toolbox_for_mac/src':\r
(Var("git.chromium.org")) + '/external/google-toolbox-for-mac.git@a09526298f9dd1ec49d3b3ac5608d2a257b94cef',\r
+ 'src/third_party/webgl': None,\r
'src/third_party/WebKit/LayoutTests/w3c/web-platform-tests': None,\r
+ 'src/third_party/scons-2.0.1': None,\r
'src/chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin': None,\r
'src/third_party/opus/src': None,\r
'src/third_party/webpagereplay': None,\r
'src/native_client': None,\r
'src/third_party/usrsctp/usrsctplib': None,\r
'src/third_party/brotli/src': None,\r
- 'src/third_party/webgl': None,\r
+ 'src/third_party/libc++abi/trunk': None,\r
'src/third_party/yasm/source/patched-yasm': None,\r
'src/testing/iossim/third_party/class-dump':\r
(Var("git.chromium.org")) + '/chromium/deps/class-dump.git@89bd40883c767584240b4dade8b74e6f57b9bdab',\r
- 'src/third_party/libjpeg_turbo': None,\r
'src/third_party/cld_2/src': None,\r
- 'src/third_party/libsrtp': None,\r
+ 'src/third_party/libjpeg_turbo': None,\r
'src/third_party/ots': None,\r
'src/third_party/ffmpeg': None,\r
'src/third_party/hunspell': None,\r
'src/third_party/swig/Lib': None,\r
- 'src/third_party/scons-2.0.1': None\r
- },\r
- 'unix': {\r
- 'src/third_party/fontconfig/src':\r
- (Var("git.chromium.org")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1',\r
- 'build/third_party/cbuildbot_chromite':\r
- (Var("git.chromium.org")) + '/chromiumos/chromite.git@1e95b44e033daa6b48e2e9702c5b08a9410f11d8',\r
- 'src/third_party/cros_system_api':\r
- (Var("git.chromium.org")) + '/chromiumos/platform/system_api.git@f0fc55329fa536195861778a2ddc6115b4a977bc',\r
- 'src/third_party/pyelftools':\r
- (Var("git.chromium.org")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e',\r
- 'src/third_party/chromite':\r
- (Var("git.chromium.org")) + '/chromiumos/chromite.git@8e92d5c24da7967e27ab2498abc2d2f7ac6ec65a',\r
- 'build/third_party/xvfb':\r
- '/trunk/tools/third_party/xvfb@125214',\r
- 'src/third_party/xdg-utils':\r
- (Var("git.chromium.org")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d',\r
- 'src/third_party/undoview':\r
- (Var("git.chromium.org")) + '/chromium/deps/undoview.git@3ba503e248f3cdbd81b78325a24ece0984637559',\r
- 'src/chrome/tools/test/reference_build/chrome_linux':\r
- (Var("git.chromium.org")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36',\r
- 'src/third_party/swig/linux':\r
- (Var("git.chromium.org")) + '/chromium/deps/swig/linux.git@866b8e0e0e0cfe99ebe608260030916ca0c3f92d',\r
- 'src/third_party/liblouis/src':\r
- (Var("git.chromium.org")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2',\r
- 'src/third_party/freetype2/src':\r
- (Var("git.chromium.org")) + '/chromium/src/third_party/freetype2.git@d699c2994ecc178c4ed05ac2086061b2034c2178',\r
- 'src/third_party/lss':\r
- (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb'\r
- },\r
- 'android': {\r
- 'src/third_party/android_webview_glue/src':\r
- (Var("git.chromium.org")) + '/external/android_webview_glue.git@a1b0248c80f239e2f6476b9f395b27d0ba1eb3cd',\r
- 'src/third_party/jarjar':\r
- (Var("git.chromium.org")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920',\r
- 'src/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille':\r
- (Var("git.chromium.org")) + '/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git@77bf6edb0138e3a38a2772248696f130dab45e34',\r
- 'src/third_party/freetype':\r
- (Var("git.chromium.org")) + '/chromium/src/third_party/freetype.git@a2b9955b49034a51dfbc8bf9f4e9d312149cecac',\r
- 'src/third_party/apache-mime4j':\r
- (Var("git.chromium.org")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',\r
- 'src/third_party/elfutils/src':\r
- (Var("git.chromium.org")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7',\r
- 'src/pdf': None,\r
- 'src/third_party/junit/src':\r
- (Var("git.chromium.org")) + '/external/junit.git@c62e2df8dbecccb1b434d4ba8843b59e90b03266',\r
- 'src/third_party/android_tools':\r
- (Var("git.chromium.org")) + '/android_tools.git@d2b86205ff973a3844020feacb35ca6b1d82efbe',\r
- 'src/third_party/httpcomponents-client':\r
- (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c',\r
- 'src/third_party/findbugs':\r
- (Var("git.chromium.org")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12',\r
- 'src/third_party/lss':\r
- (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb',\r
- 'src/third_party/android_protobuf/src':\r
- (Var("git.chromium.org")) + '/external/android_protobuf.git@94f522f907e3f34f70d9e7816b947e62fddbb267',\r
- 'src/third_party/jsr-305/src':\r
- (Var("git.chromium.org")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919',\r
- 'src/third_party/httpcomponents-core':\r
- (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62'\r
- }\r
+ 'src/third_party/nss':\r
+ (Var("git.chromium.org")) + '/chromium/deps/nss.git@87b96db4268293187d7cf741907a6d5d1d8080e0'\r
+ },\r
+ 'unix': {\r
+ 'src/third_party/fontconfig/src':\r
+ (Var("git.chromium.org")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1',\r
+ 'src/third_party/freetype2/src':\r
+ (Var("git.chromium.org")) + '/chromium/src/third_party/freetype2.git@d699c2994ecc178c4ed05ac2086061b2034c2178',\r
+ 'src/third_party/pyelftools':\r
+ (Var("git.chromium.org")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e',\r
+ 'src/third_party/chromite':\r
+ (Var("git.chromium.org")) + '/chromiumos/chromite.git@8e92d5c24da7967e27ab2498abc2d2f7ac6ec65a',\r
+ 'build/third_party/xvfb':\r
+ '/trunk/tools/third_party/xvfb@125214',\r
+ 'src/third_party/xdg-utils':\r
+ (Var("git.chromium.org")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d',\r
+ 'src/third_party/undoview':\r
+ (Var("git.chromium.org")) + '/chromium/deps/undoview.git@3ba503e248f3cdbd81b78325a24ece0984637559',\r
+ 'src/third_party/cros_system_api':\r
+ (Var("git.chromium.org")) + '/chromiumos/platform/system_api.git@f0fc55329fa536195861778a2ddc6115b4a977bc',\r
+ 'src/chrome/tools/test/reference_build/chrome_linux':\r
+ (Var("git.chromium.org")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36',\r
+ 'src/third_party/swig/linux':\r
+ (Var("git.chromium.org")) + '/chromium/deps/swig/linux.git@866b8e0e0e0cfe99ebe608260030916ca0c3f92d',\r
+ 'src/third_party/liblouis/src':\r
+ (Var("git.chromium.org")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2',\r
+ 'build/third_party/cbuildbot_chromite':\r
+ (Var("git.chromium.org")) + '/chromiumos/chromite.git@1e95b44e033daa6b48e2e9702c5b08a9410f11d8',\r
+ 'src/third_party/lss':\r
+ (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb'\r
+ },\r
+ 'android': {\r
+ 'src/third_party/android_webview_glue/src':\r
+ (Var("git.chromium.org")) + '/external/android_webview_glue.git@a1b0248c80f239e2f6476b9f395b27d0ba1eb3cd',\r
+ 'src/third_party/jarjar':\r
+ (Var("git.chromium.org")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920',\r
+ 'src/third_party/android_tools':\r
+ (Var("git.chromium.org")) + '/android_tools.git@d2b86205ff973a3844020feacb35ca6b1d82efbe',\r
+ 'src/pdf': None,\r
+ 'src/third_party/apache-mime4j':\r
+ (Var("git.chromium.org")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',\r
+ 'src/third_party/elfutils/src':\r
+ (Var("git.chromium.org")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7',\r
+ 'src/third_party/freetype':\r
+ (Var("git.chromium.org")) + '/chromium/src/third_party/freetype.git@a2b9955b49034a51dfbc8bf9f4e9d312149cecac',\r
+ 'src/third_party/junit/src':\r
+ (Var("git.chromium.org")) + '/external/junit.git@c62e2df8dbecccb1b434d4ba8843b59e90b03266',\r
+ 'src/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille':\r
+ (Var("git.chromium.org")) + '/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git@77bf6edb0138e3a38a2772248696f130dab45e34',\r
+ 'src/third_party/httpcomponents-client':\r
+ (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c',\r
+ 'src/third_party/findbugs':\r
+ (Var("git.chromium.org")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12',\r
+ 'src/third_party/lss':\r
+ (Var("git.chromium.org")) + '/external/linux-syscall-support/lss.git@952107fa7cea0daaabead28c0e92d579bee517eb',\r
+ 'src/third_party/android_protobuf/src':\r
+ (Var("git.chromium.org")) + '/external/android_protobuf.git@94f522f907e3f34f70d9e7816b947e62fddbb267',\r
+ 'src/third_party/jsr-305/src':\r
+ (Var("git.chromium.org")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919',\r
+ 'src/third_party/httpcomponents-core':\r
+ (Var("git.chromium.org")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62'\r
}\r
+}\r
\r
deps = {\r
'depot_tools':\r
(Var("git.chromium.org")) + '/external/bidichecker/lib.git@97f2aa645b74c28c57eca56992235c79850fa9e0',\r
'src/third_party/libc++/trunk':\r
(Var("git.chromium.org")) + '/chromium/llvm-project/libcxx.git@48198f9110397fff47fe7c37cbfa296be7d44d3d',\r
- 'src/third_party/colorama/src':\r
- (Var("git.chromium.org")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',\r
'src/third_party/libwebm/source':\r
(Var("git.chromium.org")) + '/webm/libwebm.git@0d4cb404ea4195e5e21d04db2c955615535ce62e',\r
'src/third_party/usrsctp/usrsctplib':\r
(Var("git.chromium.org")) + '/chromium/deps/icu52.git@d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174',\r
'src/third_party/opus/src':\r
(Var("git.chromium.org")) + '/chromium/deps/opus.git@cae696156f1e60006e39821e79a1811ae1933c69',\r
- 'src/tools/grit':\r
- (Var("git.chromium.org")) + '/external/grit-i18n.git@740badd5e3e44434a9a47b5d16749daac1e8ea80',\r
+ 'src/third_party/colorama/src':\r
+ (Var("git.chromium.org")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',\r
'src/third_party/snappy/src':\r
(Var("git.chromium.org")) + '/external/snappy.git@762bb32f0c9d2f31ba4958c7c0933d22e80c20bf',\r
'src/third_party/webpagereplay':\r
(Var("git.chromium.org")) + '/external/web-page-replay.git@2f7b704b8b567983c040f555d3e46f9766db8e87',\r
'src/third_party/WebKit':\r
- (Var("git.chromium.org")) + '/chromium/blink.git@46701e45dce4e844a0a1d14d69a91a509587aba1',\r
+ (Var("git.chromium.org")) + '/chromium/blink.git@e17a1818a3674776f83cb20461e90763d28bf1c9',\r
'src/breakpad/src':\r
(Var("git.chromium.org")) + '/external/google-breakpad/src.git@35189355da4b65ed5e7692f790c240a9ab347731',\r
'src/third_party/hunspell':\r
(Var("git.chromium.org")) + '/chromium/deps/hunspell.git@c956c0e97af00ef789afb2f64d02c9a5a50e6eb1',\r
'src/tools/deps2git':\r
(Var("git.chromium.org")) + '/chromium/tools/deps2git.git@f04828eb0b5acd3e7ad983c024870f17f17b06d9',\r
+ 'src/tools/grit':\r
+ (Var("git.chromium.org")) + '/external/grit-i18n.git@740badd5e3e44434a9a47b5d16749daac1e8ea80',\r
'src/third_party/libjpeg_turbo':\r
(Var("git.chromium.org")) + '/chromium/deps/libjpeg_turbo.git@034e9a9747e0983bc19808ea70e469bc8342081f',\r
'src/testing/gtest':\r
'--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',
-LASTCHANGE=ea46c0b6279a60b0173a092f0e9f0403a2a047a9
+LASTCHANGE=0bbff352135bacf2e6a17b5ffebd387f3c2d085f
-LASTCHANGE=1620ccec09abbd0dae196999fbcd94505136b306
+LASTCHANGE=dc24b658e6b89accb1e21a14bc06dc72bfc00c41
MAJOR=39
MINOR=0
BUILD=2171
-PATCH=62
+PATCH=71
<message name="IDS_FLAGS_ENABLE_TAB_AUDIO_MUTING_DESCRIPTION" desc="Description of the flag that enables the tab audio muting UI experiment in chrome://extensions.">
When enabled, the audio indicators in the tab strip double as tab audio mute controls. This also adds commands in the tab context menu for quickly muting multiple selected tabs.
</message>
+ <if expr="toolkit_views">
+ <message name="IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_NAME" desc="Title for the flag to enable the Link Disambiguation Popup, a bubble that appears over the web content screen when the user uses a touchscreen to touch a link but accidentally touches more than one link in a single gesture. The bubble appears with a zoomed-in view of the area around their touch, allowing them to more easily select the element they wanted.">
+ Enable Link Disambiguation Popup.
+ </message>
+ <message name="IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_DESCRIPTION" desc="Description for the flag to enable the Link Disambiguation Popup, a feature on touchscreens that when enabled will cause a small zoomed popup to appear over a group of links the user has touched, allowing for selection of links on pages not yet optimized for touch input.">
+ Enable the zoomed bubble that appears on touchscreens when accidentally touching more than one link at a time.
+ </message>
+ </if>
<!-- Crashes -->
<message name="IDS_CRASHES_TITLE" desc="Title for the chrome://crashes page.">
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)
{
#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"
OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_ENROLLMENT).Wait();
}
-IN_PROC_BROWSER_TEST_F(OobeTest, LinkDisambiguationDefaultRespected) {
- chromeos::LoginDisplayHostImpl* display_host =
- static_cast<chromeos::LoginDisplayHostImpl*>(
- chromeos::LoginDisplayHostImpl::default_host());
- ASSERT_TRUE(display_host);
- chromeos::WebUILoginView* login_view = display_host->GetWebUILoginView();
- ASSERT_TRUE(login_view);
- content::WebContents* web_contents = login_view->GetWebContents();
- ASSERT_TRUE(web_contents);
- content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
- ASSERT_TRUE(prefs);
- // Per crbug/431163 the WiFi selection dropdown doesn't support the link
- // disambiguation popup for gesture events, and this feature is disabled
- // within ChromeOS. Ensure that the web preferences reflect the default.
- if (browser_defaults::kShowLinkDisambiguationPopup) {
- EXPECT_EQ(
- content::TapMultipleTargetsStrategy::
- TAP_MULTIPLE_TARGETS_STRATEGY_POPUP,
- prefs->tap_multiple_targets_strategy);
- } else {
- EXPECT_EQ(
- content::TapMultipleTargetsStrategy::TAP_MULTIPLE_TARGETS_STRATEGY_NONE,
- prefs->tap_multiple_targets_strategy);
- }
-}
-
} // namespace chromeos
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;
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;
#endif
#if defined(TOOLKIT_VIEWS)
-#include "chrome/browser/defaults.h"
#include "ui/views/controls/textfield/textfield.h"
#endif
#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)
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.
const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
#if defined(USE_AURA)
- if (!browser_defaults::kShowLinkDisambiguationPopup)
- return;
-
link_disambiguation_popup_.reset(new LinkDisambiguationPopup);
link_disambiguation_popup_->Show(
zoomed_bitmap, target_rect, content, gesture_cb, mouse_cb);
// 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(
default:
break;
}
- NOTREACHED();
+ NOTREACHED() << "Type is " << data_type;
return NULL;
}
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)) {
NOTREACHED();
return;
}
+
+ // Device info is always preferred.
+ if (type == syncer::DEVICE_INFO)
+ return;
+
pref_service_->SetBoolean(pref_name, is_preferred);
}
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
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)));
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
switches::kEnableGPUClientLogging,
switches::kEnableGpuClientTracing,
switches::kEnableGPUServiceLogging,
+ switches::kEnableLinkDisambiguationPopup,
switches::kEnableLowResTiling,
switches::kEnableInbandTextTracks,
switches::kEnableLCDText,
'../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',
],
},
}],
- ['OS=="linux" and libpeer_target_type=="loadable_module"', {
- 'variables': {
- 'isolate_dependency_tracked': [
- '<(PRODUCT_DIR)/lib/libpeerconnection.so',
- ],
- },
- }],
['OS=="mac"', {
'variables': {
'command': [
],
},
}],
- ['OS=="win" and libpeer_target_type=="loadable_module"', {
- 'variables': {
- 'isolate_dependency_tracked': [
- '<(PRODUCT_DIR)/libpeerconnection.dll',
- ],
- },
- }],
],
'includes': [
'../base/base.isolate',
#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"
#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) {
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) {
const WebSize& inner_viewport_offset,
const WebRect& touch_rect,
const WebVector<WebRect>& target_rects) {
+ if (!switches::IsLinkDisambiguationPopupEnabled())
+ return false;
+
// Never show a disambiguation popup when accessibility is enabled,
// as this interferes with "touch exploration".
AccessibilityMode accessibility_mode =
#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"
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());
}
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()
namespace blink {
-class DisplayList;
class Node;
class RenderLayer;
class RenderObject;
OwnPtr<WebContentLayer> m_contentLayer;
OwnPtr<WebLayer> m_clipLayer;
Path m_path;
- RefPtr<DisplayList> m_displayList;
RefPtrWillBePersistent<Node> m_node;
WebViewImpl* m_owningWebViewImpl;
deps = [
":libjingle_webrtc_common",
"//third_party/webrtc",
- "//third_party/webrtc/modules/audio_processing",
"//third_party/webrtc/system_wrappers",
"//third_party/webrtc/voice_engine",
]
'<(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',
#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"
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
// 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.
&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;
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
namespace webrtc {
class AudioDeviceModule;
-class AudioProcessing;
-class Config;
} // namespace webrtc
typedef std::string (*FieldTrialFindFullName)(const std::string& trial_name);
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.
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).
// 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_
#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"
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;
*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)
<int value="-1696366449" label="disable-permissions-bubbles"/>
<int value="-1662447331" label="wake-on-packets"/>
<int value="-1619757314" label="touch-scrolling-mode"/>
+ <int value="-1614912400" label="enable-link-disambiguation-popup"/>
<int value="-1605567628" label="disable-overlay-scrollbar"/>
<int value="-1596559650" label="max-tiles-for-interest-area"/>
<int value="-1571841513" label="enable-devtools-experiments"/>
<int value="880510010" label="enable-permissions-bubbles"/>
<int value="887011602" label="enable-spelling-auto-correct"/>
<int value="909439558" label="disable-device-discovery"/>
+ <int value="929462705" label="disable-link-disambiguation-popup"/>
<int value="1022992701" label="enable-origin-chip-always"/>
<int value="1033597574" label="disable-layer-squashing"/>
<int value="1050321458" label="new-profile-management"/>
// 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";
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[];
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);
namespace switches {
+UI_BASE_EXPORT bool IsLinkDisambiguationPopupEnabled();
UI_BASE_EXPORT bool IsTextInputFocusManagerEnabled();
UI_BASE_EXPORT bool IsTouchDragDropEnabled();
UI_BASE_EXPORT bool IsTouchEditingEnabled();
# Edit these when rolling DEPS.xwalk.
# -----------------------------------
-chromium_crosswalk_rev = 'ea46c0b6279a60b0173a092f0e9f0403a2a047a9'
+chromium_crosswalk_rev = '0bbff352135bacf2e6a17b5ffebd387f3c2d085f'
v8_crosswalk_rev = '05d1cf41ef1b6e73079f69492d9e942ec19cc61a'
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'
MAJOR=11
MINOR=39
-BUILD=260
+BUILD=264
PATCH=0
#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)
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,
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() {}
// 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 {
namespace application {
-class CSPHandlerTest: public testing::Test {
- public:
- scoped_refptr<ApplicationData> CreateApplication() {
- std::string error;
- scoped_refptr<ApplicationData> app_data = ApplicationData::Create(
- base::FilePath(), std::string(), ApplicationData::LOCAL_DIRECTORY,
- make_scoped_ptr(new Manifest(make_scoped_ptr(manifest.DeepCopy()))),
- &error);
- return app_data;
- }
+namespace {
+
+const CSPInfo* GetCSPInfo(
+ scoped_refptr<ApplicationData> application) {
+ const CSPInfo* info = static_cast<CSPInfo*>(
+ application->GetManifestData(GetCSPKey(application->manifest_type())));
+ return info;
+}
- const CSPInfo* GetCSPInfo(
- scoped_refptr<ApplicationData> application) {
- const CSPInfo* info = static_cast<CSPInfo*>(
- application->GetManifestData(GetCSPKey(application->manifest_type())));
- return info;
- }
+} // namespace
- base::DictionaryValue manifest;
+class CSPHandlerTest: public testing::Test {
};
// FIXME: the default CSP policy settings in CSP manifest handler
// are temporally removed, since they had affected some tests and legacy apps.
TEST_F(CSPHandlerTest, DISABLED_NoCSP) {
- manifest.SetString(keys::kNameKey, "no name");
- manifest.SetString(keys::kXWalkVersionKey, "0");
- scoped_refptr<ApplicationData> application = CreateApplication();
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultManifestConfig();
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_MANIFEST, *manifest);
EXPECT_TRUE(application.get());
EXPECT_EQ(GetCSPInfo(application)->GetDirectives().size(), 2);
}
TEST_F(CSPHandlerTest, EmptyCSP) {
- manifest.SetString(keys::kNameKey, "no name");
- manifest.SetString(keys::kXWalkVersionKey, "0");
- manifest.SetString(keys::kCSPKey, "");
- scoped_refptr<ApplicationData> application = CreateApplication();
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultManifestConfig();
+ manifest->SetString(keys::kCSPKey, "");
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_MANIFEST, *manifest);
EXPECT_TRUE(application.get());
EXPECT_EQ(GetCSPInfo(application)->GetDirectives().size(), 0);
}
TEST_F(CSPHandlerTest, CSP) {
- manifest.SetString(keys::kNameKey, "no name");
- manifest.SetString(keys::kXWalkVersionKey, "0");
- manifest.SetString(keys::kCSPKey, "default-src 'self' ");
- scoped_refptr<ApplicationData> application = CreateApplication();
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultManifestConfig();
+ manifest->SetString(keys::kCSPKey, "default-src 'self' ");
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_MANIFEST, *manifest);
EXPECT_TRUE(application.get());
const std::map<std::string, std::vector<std::string> >& policies =
GetCSPInfo(application)->GetDirectives();
#if defined(OS_TIZEN)
TEST_F(CSPHandlerTest, WGTEmptyCSP) {
- manifest.SetString(widget_keys::kNameKey, "no name");
- manifest.SetString(widget_keys::kVersionKey, "0");
- manifest.SetString(widget_keys::kCSPKey, "");
- scoped_refptr<ApplicationData> application = CreateApplication();
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+ manifest->SetString(widget_keys::kCSPKey, "");
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
EXPECT_TRUE(application.get());
EXPECT_TRUE(GetCSPInfo(application));
EXPECT_EQ(GetCSPInfo(application)->GetDirectives().size(), 0);
}
TEST_F(CSPHandlerTest, WGTCSP) {
- manifest.SetString(widget_keys::kNameKey, "no name");
- manifest.SetString(widget_keys::kVersionKey, "0");
- manifest.SetString(widget_keys::kCSPKey, "default-src 'self' ");
- scoped_refptr<ApplicationData> application = CreateApplication();
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+ manifest->SetString(widget_keys::kCSPKey, "default-src 'self' ");
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
EXPECT_TRUE(application.get());
EXPECT_TRUE(GetCSPInfo(application));
const std::map<std::string, std::vector<std::string> >& policies =
// 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;
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);
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);
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);
}
if (!parse_single(*inner_dict, key, data_container, error))
return false;
-
return true;
}
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <map>
+#include <string>
+#include <vector>
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "xwalk/application/common/application_manifest_constants.h"
+#include "xwalk/application/common/manifest.h"
+#include "xwalk/application/common/manifest_handlers/tizen_appwidget_handler.h"
+#include "xwalk/application/common/manifest_handlers/unittest_util.h"
+
+namespace xwalk {
+
+namespace keys = application_widget_keys;
+
+namespace application {
+
+namespace {
+
+// Extracts app-widget info object from application data object.
+const TizenAppWidgetInfo* GetInfo(scoped_refptr<ApplicationData> application) {
+ const TizenAppWidgetInfo* info = static_cast<TizenAppWidgetInfo*>(
+ application->GetManifestData(keys::kTizenAppWidgetFullKey));
+ return info;
+}
+
+// In specified dictionary sets a specified value under a specified key.
+// The value is set only if it is not empty.
+void SetNotEmptyString(const std::string& key, const std::string& value,
+ base::DictionaryValue* dictionary) {
+ CHECK(!key.empty());
+ CHECK(dictionary);
+ if (!value.empty())
+ dictionary->SetString(key, value);
+}
+
+// Creates a dictionary with namespace set to tizen.
+scoped_ptr<base::DictionaryValue> CreateTizenElement() {
+ scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
+ result->SetString(keys::kNamespaceKey, keys::kTizenNamespacePrefix);
+ return result.Pass();
+}
+
+// Creates a dictionary representing an app-widget element.
+scoped_ptr<base::DictionaryValue> CreateAppWidget(
+ const std::string& id, const std::string& primary,
+ const std::string& update_peroid = std::string(),
+ const std::string& auto_launch = std::string()) {
+ scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+ SetNotEmptyString(keys::kTizenAppWidgetIdKey, id, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetPrimaryKey, primary, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetUpdatePeriodKey,
+ update_peroid, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetAutoLaunchKey,
+ auto_launch, result.get());
+ return result.Pass();
+}
+
+// Creates a dictionary representing a box-label element.
+scoped_ptr<base::DictionaryValue> CreateBoxLabel(
+ const std::string& label, const std::string& lang = std::string()) {
+ scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+ SetNotEmptyString(keys::kTizenAppWidgetBoxLabelTextKey, label, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxLabelLangKey, lang, result.get());
+ return result.Pass();
+}
+
+// Creates a dictionary representing a box-icon element.
+scoped_ptr<base::DictionaryValue> CreateBoxIcon(const std::string& src) {
+ scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+ SetNotEmptyString(keys::kTizenAppWidgetBoxIconSrcKey, src, result.get());
+ return result.Pass();
+}
+
+// Creates a dictionary representing a box-content element.
+scoped_ptr<base::DictionaryValue> CreateBoxContent(
+ const std::string& src, const std::string& mouse_event = std::string(),
+ const std::string& touch_effect = std::string()) {
+ scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentSrcKey,
+ src, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentMouseEventKey,
+ mouse_event, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentTouchEffectKey,
+ touch_effect, result.get());
+ return result.Pass();
+}
+
+// Creates a dictionary representing a box-size element.
+scoped_ptr<base::DictionaryValue> CreateBoxSize(
+ const std::string& type, const std::string& preview = std::string(),
+ const std::string& use_decoration = std::string()) {
+ scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentSizeTextKey,
+ type, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentSizePreviewKey,
+ preview, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentSizeUseDecorationKey,
+ use_decoration, result.get());
+ return result.Pass();
+}
+
+// Creates a dictionary representing a pd element.
+scoped_ptr<base::DictionaryValue> CreateBoxDropView(
+ const std::string& src, const std::string& width,
+ const std::string& height) {
+ scoped_ptr<base::DictionaryValue> result = CreateTizenElement();
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentDropViewSrcKey,
+ src, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentDropViewWidthKey,
+ width, result.get());
+ SetNotEmptyString(keys::kTizenAppWidgetBoxContentDropViewHeightKey,
+ height, result.get());
+ return result.Pass();
+}
+
+// Creates an app-widget element id basing on values of default package id
+// and default application name.
+std::string CreateAppWidgetId(const std::string& name) {
+ std::vector<std::string> parts;
+ parts.push_back(kDefaultWidgetPackageId);
+ parts.push_back(kDefaultWidgetApplicationName);
+ parts.push_back(name);
+ return JoinString(parts, '.');
+}
+
+// Creates a dictionary representing an app-widget element with all required
+// fields and child elements set.
+scoped_ptr<base::DictionaryValue> CreateMinimalAppWidget(
+ const std::string& name, const std::string& primary) {
+ std::string id = CreateAppWidgetId(name);
+
+ scoped_ptr<base::DictionaryValue> result = CreateAppWidget(id, primary);
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey,
+ CreateBoxLabel("sample label"), result.get()));
+
+ scoped_ptr<base::DictionaryValue> box_content =
+ CreateBoxContent("index.html");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+ CreateBoxSize("1x1"), box_content.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentKey,
+ box_content.Pass(), result.get()));
+
+ return result.Pass();
+}
+
+// Creates a dictionary representing an app-widget element with all fields and
+// child elements set. Each optional field is set to something different than
+// its default value if specified.
+scoped_ptr<base::DictionaryValue> CreateFullAppWidget(
+ const std::string& name, const std::string& primary) {
+ std::string id = CreateAppWidgetId(name);
+
+ scoped_ptr<base::DictionaryValue> result =
+ CreateAppWidget(id, primary, "1800.0", "true");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey,
+ CreateBoxLabel("sample label"), result.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxLabelKey,
+ CreateBoxLabel("sample en label", "en"), result.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxIconKey,
+ CreateBoxIcon("icon.png"), result.get()));
+
+ scoped_ptr<base::DictionaryValue> box_content =
+ CreateBoxContent("index.html", "true", "false");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+ CreateBoxSize("1x1"), box_content.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+ CreateBoxSize("2x1", "image.png"), box_content.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+ CreateBoxSize("2x2", "", "false"), box_content.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentDropViewKey,
+ CreateBoxDropView("index.html", "720", "150"), box_content.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentKey,
+ box_content.Pass(), result.get()));
+
+ return result.Pass();
+}
+
+// Tests wheter specified value type is a dictionary or a list.
+bool IsComplexValueType(base::Value::Type type) {
+ return type == base::Value::TYPE_DICTIONARY || type == base::Value::TYPE_LIST;
+}
+
+// Searches for a child value specified by name in specified root value and
+// if the child is found, fills child and parent arguments with the found child
+// and its parent. Both parent and child arguments are optional.
+bool GetParentAndChild(const std::string& name, base::Value* root,
+ base::DictionaryValue** parent, base::Value** child) {
+ CHECK(!name.empty());
+ CHECK(root);
+
+ base::DictionaryValue* tmp_parent = nullptr;
+ if (!root->GetAsDictionary(&tmp_parent))
+ return false;
+
+ base::Value* tmp_child;
+ if (!tmp_parent->Get(name, &tmp_child))
+ return false;
+
+ if (parent)
+ *parent = tmp_parent;
+ if (child)
+ *child = tmp_child;
+
+ return true;
+}
+
+// Searches for a child value specified by name and index in specified root
+// value and if the child is found, fills child and parent arguments with
+// the found child and its parent. Both parent and child arguments are optional.
+bool GetParentAndChild(const std::string& name, size_t index,
+ base::Value* root, base::ListValue** parent, base::Value** child) {
+ CHECK(!name.empty());
+ CHECK(root);
+
+ base::Value* first_level_child;
+ if (!GetParentAndChild(name, root, nullptr, &first_level_child))
+ return false;
+
+ base::ListValue* tmp_parent = nullptr;
+ if (!first_level_child->GetAsList(&tmp_parent))
+ return false;
+
+ base::Value* tmp_child;
+ if (!tmp_parent->Get(index, &tmp_child))
+ return false;
+
+ if (parent)
+ *parent = tmp_parent;
+ if (child)
+ *child = tmp_child;
+
+ return true;
+}
+
+// If the value argument is nullptr, the function removes the value specified by
+// path, otherwise it changes the value specified by path to the value argument.
+bool ChangeOrRemove(const std::string& path, base::Value * root,
+ const std::string* value = nullptr) {
+ CHECK(!path.empty());
+ CHECK(root);
+
+ base::Value* current = root;
+
+ std::vector<std::string> parts;
+ base::SplitString(path, '.', &parts);
+ for (size_t i = 0, count = parts.size(); i < count; ++i) {
+ const std::string& part = parts[i];
+
+ std::vector<std::string> name_and_index;
+ base::SplitString(part, ':', &name_and_index);
+ if (name_and_index.size() == 1) { // current part refers to a dictionary
+ const std::string& name = name_and_index[0];
+
+ base::DictionaryValue* parent;
+ base::Value* child;
+ if (!GetParentAndChild(name, current, &parent, &child))
+ return false;
+
+ if (i == count - 1) {
+ if (value) {
+ if (IsComplexValueType(child->GetType()))
+ return false;
+ parent->SetString(name, *value);
+ return true;
+ }
+ return parent->Remove(name, nullptr);
+ }
+
+ current = child;
+ } else if (name_and_index.size() == 2) { // current part refers to a list
+ const std::string& name = name_and_index[0];
+ unsigned index;
+ if (!base::StringToUint(name_and_index[1], &index))
+ return false; // invalid path
+
+ base::ListValue* parent;
+ base::Value* child;
+ if (!GetParentAndChild(name, index, current, &parent, &child))
+ return false;
+
+ if (i == count - 1) {
+ if (value) {
+ if (IsComplexValueType(child->GetType()))
+ return false;
+ parent->Set(index, new base::StringValue(*value));
+ return true;
+ }
+ return parent->Remove(index, nullptr);
+ }
+
+ current = child;
+ } else { // current part is invalid
+ return false;
+ }
+ }
+
+ return current;
+}
+
+// Creates a key representing a list value item. For example "box-size:2".
+std::string MakeListItemKey(const std::string& name, size_t index) {
+ return name + ':' + base::UintToString(index);
+}
+
+// Makes a path to widget.app-widget.element.
+std::string MakeAppWidgetPath(const std::string& element) {
+ return MakeElementPath(keys::kTizenAppWidgetFullKey, element);
+}
+
+// Makes a path to widget.app-widget.box-label:index.element.
+std::string MakeBoxLabelPath(size_t index, const std::string& element) {
+ const std::string& label =
+ MakeListItemKey(keys::kTizenAppWidgetBoxLabelKey, index);
+ return MakeElementPath(MakeAppWidgetPath(label), element);
+}
+
+// Makes a path to widget.app-widget.box-icon.element.
+std::string MakeBoxIconPath(const std::string& element) {
+ return MakeElementPath(
+ MakeAppWidgetPath(keys::kTizenAppWidgetBoxIconKey), element);
+}
+
+// Makes a path to widget.app-widget.box-content.element.
+std::string MakeBoxContentPath(const std::string& element) {
+ return MakeElementPath(
+ MakeAppWidgetPath(keys::kTizenAppWidgetBoxContentKey), element);
+}
+
+// Makes a path to widget.app-widget.box-content.box-size:index.element.
+std::string MakeSizePath(size_t index, const std::string& element) {
+ const std::string& size =
+ MakeListItemKey(keys::kTizenAppWidgetBoxContentSizeKey, index);
+ return MakeElementPath(MakeBoxContentPath(size), element);
+}
+
+// Makes a path to widget.app-widget.box-content.pd.element.
+std::string MakeDropViewPath(const std::string& element) {
+ return MakeElementPath(
+ MakeBoxContentPath(keys::kTizenAppWidgetBoxContentDropViewKey), element);
+}
+
+} // namespace
+
+class TizenAppWidgetHandlerTest: public testing::Test {
+ public:
+ void ChangedOrRemovedFieldTest(const std::string& path,
+ const std::string* value = nullptr) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateFullAppWidget("first", "true");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ CHECK(ChangeOrRemove(path, manifest.get(), value));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_EQ(nullptr, application.get());
+ }
+
+ // Defines a test in which a field specified by path is removed from
+ // manifest created by CreateDefaultWidgetConfig and complemented by
+ // app-widget element created by CreateFullAppWidget.
+ // Can be used when path is precise (there is no dictionary list in the way).
+ void MissingFieldTest(const std::string& path) {
+ ChangedOrRemovedFieldTest(path);
+ }
+
+ // Defines a test in which a field specified by path is changed in
+ // manifest created by CreateDefaultWidgetConfig and complemented by
+ // app-widget element created by CreateFullAppWidget.
+ // Can be used when path is precise (there is no dictionary list in the way).
+ void InvalidFieldValueTest(const std::string& path,
+ const std::string& value) {
+ ChangedOrRemovedFieldTest(path, &value);
+ }
+};
+
+// Test case for no app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, NoAppWidget) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_NE(nullptr, application.get());
+ EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+ const TizenAppWidgetInfo* info = GetInfo(application);
+ EXPECT_EQ(nullptr, info);
+}
+
+// Test case for one app-widget element with only required attributes and child
+// elements set.
+TEST_F(TizenAppWidgetHandlerTest, OneMinimalAppWidget) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateMinimalAppWidget("first", "true");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_NE(nullptr, application.get());
+ EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+ const TizenAppWidgetInfo* info = GetInfo(application);
+ EXPECT_NE(nullptr, info);
+
+ const TizenAppWidgetVector& app_widgets = info->app_widgets();
+ EXPECT_EQ(1, app_widgets.size());
+
+ const TizenAppWidget& element = app_widgets[0];
+
+ std::vector<std::string> id_parts;
+ base::SplitString(element.id, '.', &id_parts);
+ EXPECT_EQ(3, id_parts.size());
+ EXPECT_EQ("first", id_parts[2]);
+ EXPECT_TRUE(element.primary);
+ EXPECT_EQ(0, element.update_period.size());
+ EXPECT_FALSE(element.auto_launch);
+ EXPECT_EQ("sample label", element.label.default_value);
+ EXPECT_EQ(0, element.label.lang_value_map.size());
+ EXPECT_TRUE(element.icon_src.empty());
+ EXPECT_EQ("index.html", element.content_src);
+ EXPECT_FALSE(element.content_mouse_event);
+ EXPECT_TRUE(element.content_touch_effect);
+ EXPECT_EQ(1, element.content_size.size());
+ EXPECT_EQ(TizenAppWidgetSizeType::k1x1, element.content_size[0].type);
+ EXPECT_TRUE(element.content_size[0].preview.empty());
+ EXPECT_TRUE(element.content_size[0].use_decoration);
+ EXPECT_EQ(0, element.content_drop_view.size());
+}
+
+// Test case for two app-widget elements with only required attributes and child
+// elements set.
+TEST_F(TizenAppWidgetHandlerTest, TwoMinimalAppWidgets) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateMinimalAppWidget("first", "true");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ app_widget = CreateMinimalAppWidget("second", "false");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_NE(nullptr, application.get());
+ EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+ const TizenAppWidgetInfo* info = GetInfo(application);
+ EXPECT_NE(nullptr, info);
+
+ const TizenAppWidgetVector& app_widgets = info->app_widgets();
+ EXPECT_EQ(2, app_widgets.size());
+
+ std::vector<std::string> id_parts;
+ base::SplitString(app_widgets[0].id, '.', &id_parts);
+ EXPECT_EQ(3, id_parts.size());
+ EXPECT_EQ("first", id_parts[2]);
+ EXPECT_TRUE(app_widgets[0].primary);
+
+ base::SplitString(app_widgets[1].id, '.', &id_parts);
+ EXPECT_EQ(3, id_parts.size());
+ EXPECT_EQ("second", id_parts[2]);
+ EXPECT_FALSE(app_widgets[1].primary);
+
+ for (const TizenAppWidget& element : app_widgets) {
+ EXPECT_EQ(0, element.update_period.size());
+ EXPECT_FALSE(element.auto_launch);
+ EXPECT_EQ("sample label", element.label.default_value);
+ EXPECT_EQ(0, element.label.lang_value_map.size());
+ EXPECT_TRUE(element.icon_src.empty());
+ EXPECT_EQ("index.html", element.content_src);
+ EXPECT_FALSE(element.content_mouse_event);
+ EXPECT_TRUE(element.content_touch_effect);
+ EXPECT_EQ(1, element.content_size.size());
+ EXPECT_EQ(TizenAppWidgetSizeType::k1x1, element.content_size[0].type);
+ EXPECT_TRUE(element.content_size[0].preview.empty());
+ EXPECT_TRUE(element.content_size[0].use_decoration);
+ EXPECT_EQ(0, element.content_drop_view.size());
+ }
+}
+
+// Test case for one app-widget element with all posible attributes and child
+// elements set.
+TEST_F(TizenAppWidgetHandlerTest, OneFullAppWidget) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateFullAppWidget("first", "true");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_NE(nullptr, application.get());
+ EXPECT_EQ(Manifest::TYPE_WIDGET, application->GetManifest()->type());
+
+ const TizenAppWidgetInfo* info = GetInfo(application);
+ EXPECT_NE(nullptr, info);
+
+ const TizenAppWidgetVector& app_widgets = info->app_widgets();
+ EXPECT_EQ(1, app_widgets.size());
+
+ const TizenAppWidget& element = app_widgets[0];
+
+ std::vector<std::string> id_parts;
+ base::SplitString(element.id, '.', &id_parts);
+ EXPECT_EQ(3, id_parts.size());
+ EXPECT_EQ("first", id_parts[2]);
+ EXPECT_TRUE(element.primary);
+ EXPECT_EQ(1, element.update_period.size());
+ EXPECT_EQ(1800, element.update_period[0]);
+ EXPECT_TRUE(element.auto_launch);
+ EXPECT_EQ("sample label", element.label.default_value);
+ EXPECT_EQ(1, element.label.lang_value_map.size());
+ EXPECT_EQ("sample en label", element.label.lang_value_map.at("en"));
+ EXPECT_EQ("icon.png", element.icon_src);
+ EXPECT_EQ("index.html", element.content_src);
+ EXPECT_TRUE(element.content_mouse_event);
+ EXPECT_FALSE(element.content_touch_effect);
+ EXPECT_EQ(3, element.content_size.size());
+ EXPECT_EQ(TizenAppWidgetSizeType::k1x1, element.content_size[0].type);
+ EXPECT_TRUE(element.content_size[0].preview.empty());
+ EXPECT_TRUE(element.content_size[0].use_decoration);
+ EXPECT_EQ(TizenAppWidgetSizeType::k2x1, element.content_size[1].type);
+ EXPECT_EQ("image.png", element.content_size[1].preview);
+ EXPECT_TRUE(element.content_size[1].use_decoration);
+ EXPECT_EQ(TizenAppWidgetSizeType::k2x2, element.content_size[2].type);
+ EXPECT_TRUE(element.content_size[2].preview.empty());
+ EXPECT_FALSE(element.content_size[2].use_decoration);
+ EXPECT_EQ(1, element.content_drop_view.size());
+ EXPECT_EQ("index.html", element.content_drop_view[0].src);
+ EXPECT_EQ(720, element.content_drop_view[0].width);
+ EXPECT_EQ(150, element.content_drop_view[0].height);
+}
+
+// Test case for missing namespace attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingAppWidgetNamespace) {
+ MissingFieldTest(MakeAppWidgetPath(keys::kNamespaceKey));
+}
+
+// Test case for missing id attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingId) {
+ MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetIdKey));
+}
+
+// Test case for missing primary attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingPrimary) {
+ MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetPrimaryKey));
+}
+
+// Test case for missing box-label element in app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingLabel) {
+ MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetBoxLabelKey));
+}
+
+// Test case for missing namespace attribute of box-label element.
+TEST_F(TizenAppWidgetHandlerTest, MissingLabelNamespace) {
+ MissingFieldTest(MakeBoxLabelPath(0, keys::kNamespaceKey));
+}
+
+// Test case for missing namespace attribute of box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, MissingIconNamespace) {
+ MissingFieldTest(MakeBoxIconPath(keys::kNamespaceKey));
+}
+
+// Test case for missing src attribute of box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, MissingIconSrc) {
+ MissingFieldTest(MakeBoxIconPath(keys::kTizenAppWidgetBoxIconSrcKey));
+}
+
+// Test case for missing box-content element in app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, MissingContent) {
+ MissingFieldTest(MakeAppWidgetPath(keys::kTizenAppWidgetBoxContentKey));
+}
+
+// Test case for missing namespace attribute of box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingContentNamespace) {
+ MissingFieldTest(MakeBoxContentPath(keys::kNamespaceKey));
+}
+
+// Test case for missing src attribute of box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingContentSrc) {
+ MissingFieldTest(MakeBoxContentPath(keys::kTizenAppWidgetBoxContentSrcKey));
+}
+
+// Test case for missing box-size element in box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingSize) {
+ MissingFieldTest(MakeBoxContentPath(keys::kTizenAppWidgetBoxContentSizeKey));
+}
+
+// Test case for missing namespace attribute of box-size element.
+TEST_F(TizenAppWidgetHandlerTest, MissingSizeNamespace) {
+ MissingFieldTest(MakeSizePath(0, keys::kNamespaceKey));
+}
+
+// Test case for missing box-size element with 1x1 value in box-content element.
+TEST_F(TizenAppWidgetHandlerTest, MissingSize1x1) {
+ MissingFieldTest(MakeBoxContentPath(MakeListItemKey(
+ keys::kTizenAppWidgetBoxContentSizeKey, 0)));
+}
+
+// Test case for missing namespace attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingDropViewNamespace) {
+ MissingFieldTest(MakeDropViewPath(keys::kNamespaceKey));
+}
+
+// Test case for missing src attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingDropViewSrc) {
+ MissingFieldTest(MakeDropViewPath(
+ keys::kTizenAppWidgetBoxContentDropViewSrcKey));
+}
+
+// Test case for missing width attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingWidth) {
+ MissingFieldTest(MakeDropViewPath(
+ keys::kTizenAppWidgetBoxContentDropViewWidthKey));
+}
+
+// Test case for missing height attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, MissingHeight) {
+ MissingFieldTest(MakeDropViewPath(
+ keys::kTizenAppWidgetBoxContentDropViewHeightKey));
+}
+
+// Test case for invalid namespace attribute of app-widget element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidAppWidgetNamespace) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kNamespaceKey),
+ "not_a_tizen_namespace");
+}
+
+// Test case for invalid id attribute of app-widget element.
+// The id must start with application id.
+TEST_F(TizenAppWidgetHandlerTest, InvalidIdNotStartedWithAppId) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kTizenAppWidgetIdKey),
+ "invalid_id");
+}
+
+// Test case for invalid id attribute of app-widget element.
+// The id must consist of 0-9a-zA-Z.
+TEST_F(TizenAppWidgetHandlerTest, InvalidIdInvalidCharInNamePart) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kTizenAppWidgetIdKey),
+ CreateAppWidgetId("the-first"));
+}
+
+// Test case for invalid primary attribute of app-widget element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidPrimary) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kTizenAppWidgetPrimaryKey),
+ "not_true_nor_false");
+}
+
+// Test case for invalid update-period attribute of app-widget element.
+// The value must be integer.
+TEST_F(TizenAppWidgetHandlerTest, InvalidUpdatePeriod) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kTizenAppWidgetUpdatePeriodKey),
+ "not_a_number");
+}
+
+// Test case for invalid update-period attribute of app-widget element.
+// The value must be not less than 1800.
+TEST_F(TizenAppWidgetHandlerTest, InvalidUpdatePeriodOutOfDomain) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kTizenAppWidgetUpdatePeriodKey),
+ "1799");
+}
+
+// Test case for invalid auto-launch attribute of app-widget element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidAutoLaunch) {
+ InvalidFieldValueTest(
+ MakeAppWidgetPath(keys::kTizenAppWidgetAutoLaunchKey),
+ "not_true_nor_false");
+}
+
+// Test case for invalid namespace attribute of box-label element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidLabelNamespace) {
+ InvalidFieldValueTest(
+ MakeBoxLabelPath(0, keys::kNamespaceKey),
+ "not_a_tizen_namespace");
+}
+
+// Test case for invalid namespace attribute of box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidIconNamespace) {
+ InvalidFieldValueTest(
+ MakeBoxIconPath(keys::kNamespaceKey),
+ "not_a_tizen_namespace");
+}
+
+// Test case for invalid namespace attribute of box-content element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidContentNamespace) {
+ InvalidFieldValueTest(
+ MakeBoxContentPath(keys::kNamespaceKey),
+ "not_a_tizen_namespace");
+}
+
+// Test case for invalid mouse-event attribute of box-content element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidMouseEvent) {
+ InvalidFieldValueTest(
+ MakeBoxContentPath(keys::kTizenAppWidgetBoxContentMouseEventKey),
+ "not_true_nor_false");
+}
+
+// Test case for invalid touch-effect attribute of box-content element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidTouchEffect) {
+ InvalidFieldValueTest(
+ MakeBoxContentPath(keys::kTizenAppWidgetBoxContentTouchEffectKey),
+ "not_true_nor_false");
+}
+
+// Test case for invalid namespace attribute of box-size element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidSizeNamespace) {
+ InvalidFieldValueTest(
+ MakeSizePath(0, keys::kNamespaceKey),
+ "not_a_tizen_namespace");
+}
+
+// Test case for invalid text value of box-size element.
+// The value must be one of these: 1x1, 2x1, 2x2.
+TEST_F(TizenAppWidgetHandlerTest, InvalidSize) {
+ InvalidFieldValueTest(
+ MakeSizePath(0, keys::kTizenAppWidgetBoxContentSizeTextKey),
+ "AxB");
+}
+
+// Test case for invalid use-decoration attribute of box-size element.
+// The value must be bool (true or false).
+TEST_F(TizenAppWidgetHandlerTest, InvalidUseDecoration) {
+ InvalidFieldValueTest(
+ MakeSizePath(2, keys::kTizenAppWidgetBoxContentSizeUseDecorationKey),
+ "not_true_nor_false");
+}
+
+// Test case for invalid namespace attribute of pd element.
+TEST_F(TizenAppWidgetHandlerTest, InvalidDropViewNamespace) {
+ InvalidFieldValueTest(
+ MakeDropViewPath(keys::kNamespaceKey),
+ "not_a_tizen_namespace");
+}
+
+// Test case for invalid width attribute of pd element.
+// The value must be integer.
+TEST_F(TizenAppWidgetHandlerTest, InvalidWidth) {
+ InvalidFieldValueTest(
+ MakeDropViewPath(keys::kTizenAppWidgetBoxContentDropViewWidthKey),
+ "not_a_number");
+}
+
+// Test case for invalid height attribute of pd element.
+// The value must be integer.
+TEST_F(TizenAppWidgetHandlerTest, InvalidHeight) {
+ InvalidFieldValueTest(
+ MakeDropViewPath(keys::kTizenAppWidgetBoxContentDropViewHeightKey),
+ "not_a_number");
+}
+
+// Test case for invalid height attribute of pd element.
+// The value must be in a range of [1, 380].
+TEST_F(TizenAppWidgetHandlerTest, InvalidHeightOutOfDomain) {
+ InvalidFieldValueTest(
+ MakeDropViewPath(keys::kTizenAppWidgetBoxContentDropViewHeightKey),
+ "381");
+}
+
+// Test case for more than one box-content element.
+TEST_F(TizenAppWidgetHandlerTest, TwoContents) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateFullAppWidget("first", "true");
+
+ scoped_ptr<base::DictionaryValue> box_content =
+ CreateBoxContent("index.html");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentSizeKey,
+ CreateBoxSize("1x1"), box_content.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxContentKey,
+ box_content.Pass(), app_widget.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_EQ(nullptr, application.get());
+}
+
+// Test case for more than one box-icon element.
+TEST_F(TizenAppWidgetHandlerTest, TwoIcons) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateFullAppWidget("first", "true");
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetBoxIconKey,
+ CreateBoxIcon("icon.png"), app_widget.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_EQ(nullptr, application.get());
+}
+
+// Test case for more than one pd element.
+TEST_F(TizenAppWidgetHandlerTest, TwoDropViews) {
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+
+ scoped_ptr<base::DictionaryValue> app_widget =
+ CreateFullAppWidget("first", "true");
+
+ CHECK(AddDictionary(
+ MakeElementPath(keys::kTizenAppWidgetBoxContentKey,
+ keys::kTizenAppWidgetBoxContentDropViewKey),
+ CreateBoxDropView("index.html", "720", "150"), app_widget.get()));
+
+ CHECK(AddDictionary(keys::kTizenAppWidgetFullKey,
+ app_widget.Pass(), manifest.get()));
+
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
+ EXPECT_EQ(nullptr, application.get());
+}
+
+} // namespace application
+} // namespace xwalk
#include "xwalk/application/common/manifest_handlers/unittest_util.h"
-#include <string>
+#include "base/strings/string_util.h"
#include "xwalk/application/common/application_manifest_constants.h"
namespace xwalk {
namespace {
-const char kDefaultVersion[] = "0";
-const char kDefaultName[] = "no name";
+// Makes a path to widget.element.
+std::string MakeWidgetPath(const std::string& element) {
+ return MakeElementPath(widget_keys::kWidgetKey, element);
+}
#if defined(OS_TIZEN)
-const char kDefaultPackageId[] = "abcdefghij";
-const char kDefaultApplicationName[] = "noname";
-const char kDefaultRequiredVersion[] = "0";
-
-#endif // defined(OS_TIZEN)
+// Makes a path to widget.application.element.
+std::string MakeApplicationPath(const std::string& element) {
+ return MakeElementPath(widget_keys::kTizenApplicationKey, element);
+}
-std::string DotConnect(const std::string& first, const std::string& second) {
- return first + '.' + second;
+// Creates an app-widget element id basing on values of default package id
+// and default application name.
+std::string GetDefaultApplicationId() {
+ std::vector<std::string> parts;
+ parts.push_back(kDefaultWidgetPackageId);
+ parts.push_back(kDefaultWidgetApplicationName);
+ return JoinString(parts, '.');
}
+#endif // defined(OS_TIZEN)
+
} // namespace
+const char kDefaultManifestName[] = "no name";
+const char kDefaultManifestVersion[] = "0";
+const char kDefaultWidgetName[] = "no name";
+const char kDefaultWidgetVersion[] = "0";
+
+#if defined(OS_TIZEN)
+
+const char kDefaultWidgetPackageId[] = "abcdefghij";
+const char kDefaultWidgetApplicationName[] = "noname";
+const char kDefaultWidgetRequiredVersion[] = "0";
+
+#endif // defined(OS_TIZEN)
+
scoped_ptr<base::DictionaryValue> CreateDefaultManifestConfig() {
scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue());
- manifest->SetString(manifest_keys::kXWalkVersionKey, kDefaultVersion);
- manifest->SetString(manifest_keys::kNameKey, kDefaultName);
+ manifest->SetString(manifest_keys::kXWalkVersionKey, kDefaultManifestVersion);
+ manifest->SetString(manifest_keys::kNameKey, kDefaultManifestName);
return manifest.Pass();
}
// 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
return application;
}
+std::string MakeElementPath(const std::string& parent,
+ const std::string& element) {
+ std::vector<std::string> parts;
+ parts.push_back(parent);
+ parts.push_back(element);
+ return JoinString(parts, '.');
+}
+
+bool AddDictionary(const std::string& key,
+ scoped_ptr<base::DictionaryValue> child, base::DictionaryValue* parent) {
+ if (key.empty() || !child || !parent)
+ return false;
+
+ scoped_ptr<base::Value> existing_child;
+ base::DictionaryValue* unused;
+ if (parent->GetDictionary(key, &unused)) {
+ if (!parent->Remove(key, &existing_child))
+ return false;
+ }
+
+ if (existing_child) {
+ scoped_ptr<base::ListValue> list(new base::ListValue);
+ list->Set(list->GetSize(), existing_child.release());
+ list->Set(list->GetSize(), child.release());
+ parent->Set(key, list.release());
+ } else {
+ base::ListValue* list;
+ if (parent->GetList(key, &list))
+ list->Set(list->GetSize(), child.release());
+ else
+ parent->Set(key, child.release());
+ }
+
+ return true;
+}
+
} // namespace application
} // namespace xwalk
#ifndef XWALK_APPLICATION_COMMON_MANIFEST_HANDLERS_UNITTEST_UTIL_H_
#define XWALK_APPLICATION_COMMON_MANIFEST_HANDLERS_UNITTEST_UTIL_H_
+#include <string>
+#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
namespace xwalk {
namespace application {
+extern const char kDefaultManifestName[];
+extern const char kDefaultManifestVersion[];
+extern const char kDefaultWidgetName[];
+extern const char kDefaultWidgetVersion[];
+
+#if defined(OS_TIZEN)
+
+extern const char kDefaultWidgetPackageId[];
+extern const char kDefaultWidgetApplicationName[];
+extern const char kDefaultWidgetRequiredVersion[];
+
+#endif // defined(OS_TIZEN)
+
+// Creates a minimal valid manifest configuration.
scoped_ptr<base::DictionaryValue> CreateDefaultManifestConfig();
+
+// Creates a minimal valid widget configuration.
scoped_ptr<base::DictionaryValue> CreateDefaultWidgetConfig();
+// Creates an ApplicationData for specified configuration data.
scoped_refptr<ApplicationData> CreateApplication(Manifest::Type type,
const base::DictionaryValue& manifest);
+// Creates a path to element under parent element.
+// For example, calling MakePath("a.b", "c") produces "a.b.c".
+std::string MakeElementPath(const std::string& parent,
+ const std::string& element);
+
+// In a parent dictionary adds a child dictionary under a specified key.
+// If it is a first dictionary under the key, it is added as dictionary
+// directly, otherwise it is added as another dictionary in a list of
+// dictionaries. If parent is null, it does nothing.
+bool AddDictionary(const std::string& key,
+ scoped_ptr<base::DictionaryValue> child, base::DictionaryValue* parent);
+
} // namespace application
} // namespace xwalk
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;
// 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 {
const char* preferencesName[] = {"pname0", "pname1", "pname2"};
const char* preferencesValue[] = {"pvalue0", "pvalue1", "pvalue2"};
const char* preferencesReadonly[] = {"true", "false", "false"};
-} // namespace
-class WidgetHandlerTest: public testing::Test {
- public:
- scoped_refptr<ApplicationData> CreateApplication(
- const base::DictionaryValue& manifest) {
- std::string error;
- scoped_refptr<ApplicationData> application = ApplicationData::Create(
- base::FilePath(), std::string(), ApplicationData::LOCAL_DIRECTORY,
- make_scoped_ptr(new Manifest(make_scoped_ptr(manifest.DeepCopy()),
- Manifest::TYPE_WIDGET)),
- &error);
- return application;
- }
+WidgetInfo* GetWidgetInfo(scoped_refptr<ApplicationData> application) {
+ WidgetInfo* info = static_cast<WidgetInfo*>(
+ application->GetManifestData(keys::kWidgetKey));
+ return info;
+}
- WidgetInfo* GetWidgetInfo(scoped_refptr<ApplicationData> application) {
- WidgetInfo* info = static_cast<WidgetInfo*>(
- application->GetManifestData(keys::kWidgetKey));
- return info;
- }
+template <Manifest::Type type>
+base::DictionaryValue* GetPreferencesItem(int id) {
+ NOTREACHED() << "Use one of already defined template specializations"
+ " or define a new one.";
+ return nullptr;
+}
- base::DictionaryValue* GetPreferencesItem(int id,
- bool is_parsed_manifest_key) {
- base::DictionaryValue* preferences = new base::DictionaryValue;
- if (is_parsed_manifest_key) {
- preferences->SetString(keys::kPreferencesNameKey,
- preferencesName[id]);
- preferences->SetString(keys::kPreferencesValueKey,
- preferencesValue[id]);
- // PreferencesReadonly is string on manifest and bool on widgetInfo
- preferences->SetString(keys::kPreferencesReadonlyKey,
- preferencesReadonly[id]);
- } else {
- preferences->SetString(kWidgetPreferencesName,
- preferencesName[id]);
- preferences->SetString(kWidgetPreferencesValue,
- preferencesValue[id]);
- preferences->SetBoolean(kWidgetPreferencesReadonly,
- strncmp(preferencesReadonly[id], "true", 4) == 0);
- }
- return preferences;
- }
+template <>
+base::DictionaryValue* GetPreferencesItem<Manifest::TYPE_MANIFEST>(int id) {
+ base::DictionaryValue* preferences = new base::DictionaryValue;
- // No Preferences and full other information
- void SetAllInfoToManifest(base::DictionaryValue* manifest) {
- // Insert some key-value pairs into manifest use full key
- manifest->SetString(keys::kWidgetNamespaceKey,
- keys::kWidgetNamespacePrefix);
- manifest->SetString(keys::kAuthorKey, author);
- manifest->SetString(keys::kDescriptionKey, decription);
- manifest->SetString(keys::kNameKey, name);
- manifest->SetString(keys::kShortNameKey, shortName);
- manifest->SetString(keys::kVersionKey, version);
- manifest->SetString(keys::kIDKey, ID);
- manifest->SetString(keys::kAuthorEmailKey, authorEmail);
- manifest->SetString(keys::kAuthorHrefKey, authorHref);
- manifest->SetString(keys::kHeightKey, height);
- manifest->SetString(keys::kWidthKey, width);
- }
+ preferences->SetString(keys::kPreferencesNameKey,
+ preferencesName[id]);
+ preferences->SetString(keys::kPreferencesValueKey,
+ preferencesValue[id]);
+ // PreferencesReadonly is string on manifest and bool on widgetInfo
+ preferences->SetString(keys::kPreferencesReadonlyKey,
+ preferencesReadonly[id]);
- // No Preferences and full other information
- void SetAllInfoToWidget(base::DictionaryValue* widget) {
- // Insert some key-value pairs into widget use widget key;
- widget->SetString(kWidgetAuthor, author);
- widget->SetString(kWidgetDecription, decription);
- widget->SetString(kWidgetName, name);
- widget->SetString(kWidgetShortName, shortName);
- widget->SetString(kWidgetVersion, version);
- widget->SetString(kWidgetID, ID);
- widget->SetString(kWidgetAuthorEmail, authorEmail);
- widget->SetString(kWidgetAuthorHref, authorHref);
- widget->SetString(kWidgetHeight, height);
- widget->SetString(kWidgetWidth, width);
- }
+ return preferences;
+}
+
+template <>
+base::DictionaryValue* GetPreferencesItem<Manifest::TYPE_WIDGET>(int id) {
+ base::DictionaryValue* preferences = new base::DictionaryValue;
+
+ preferences->SetString(kWidgetPreferencesName,
+ preferencesName[id]);
+ preferences->SetString(kWidgetPreferencesValue,
+ preferencesValue[id]);
+ preferences->SetBoolean(kWidgetPreferencesReadonly,
+ strncmp(preferencesReadonly[id], "true", 4) == 0);
+ return preferences;
+}
+
+// No Preferences and full other information
+void SetAllInfoToManifest(base::DictionaryValue* manifest) {
+ // Insert some key-value pairs into manifest use full key
+ manifest->SetString(keys::kWidgetNamespaceKey,
+ keys::kWidgetNamespacePrefix);
+ manifest->SetString(keys::kAuthorKey, author);
+ manifest->SetString(keys::kDescriptionKey, decription);
+ manifest->SetString(keys::kNameKey, name);
+ manifest->SetString(keys::kShortNameKey, shortName);
+ manifest->SetString(keys::kVersionKey, version);
+ manifest->SetString(keys::kIDKey, ID);
+ manifest->SetString(keys::kAuthorEmailKey, authorEmail);
+ manifest->SetString(keys::kAuthorHrefKey, authorHref);
+ manifest->SetString(keys::kHeightKey, height);
+ manifest->SetString(keys::kWidthKey, width);
+}
+
+// No Preferences and full other information
+void SetAllInfoToWidget(base::DictionaryValue* widget) {
+ // Insert some key-value pairs into widget use widget key;
+ widget->SetString(kWidgetAuthor, author);
+ widget->SetString(kWidgetDecription, decription);
+ widget->SetString(kWidgetName, name);
+ widget->SetString(kWidgetShortName, shortName);
+ widget->SetString(kWidgetVersion, version);
+ widget->SetString(kWidgetID, ID);
+ widget->SetString(kWidgetAuthorEmail, authorEmail);
+ widget->SetString(kWidgetAuthorHref, authorHref);
+ widget->SetString(kWidgetHeight, height);
+ widget->SetString(kWidgetWidth, width);
+}
+
+} // namespace
+
+class WidgetHandlerTest: public testing::Test {
};
TEST_F(WidgetHandlerTest, ParseManifestWithOnlyNameAndVersion) {
- base::DictionaryValue manifest;
- manifest.SetString(keys::kWidgetNamespaceKey, keys::kWidgetNamespacePrefix);
- manifest.SetString(keys::kNameKey, "no name");
- manifest.SetString(keys::kVersionKey, "0");
-
- scoped_refptr<ApplicationData> application = CreateApplication(manifest);
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
+ manifest->SetString(keys::kWidgetNamespaceKey, keys::kWidgetNamespacePrefix);
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
EXPECT_TRUE(application.get());
WidgetInfo* info = GetWidgetInfo(application);
TEST_F(WidgetHandlerTest,
ParseManifestWithAllOfOtherItemsAndOnePreferenceItem) {
// Create a manifest with one preference item.
- scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
SetAllInfoToManifest(manifest.get());
- manifest->Set(keys::kPreferencesKey, GetPreferencesItem(0, true));
+ manifest->Set(keys::kPreferencesKey,
+ GetPreferencesItem<Manifest::TYPE_MANIFEST>(0));
// Create an application use this manifest.
- scoped_refptr<ApplicationData> application;
- application = CreateApplication(*(manifest.get()));
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
EXPECT_TRUE(application.get());
EXPECT_EQ(application->manifest_type(), Manifest::TYPE_WIDGET);
// Get widget info from this application.
WidgetInfo* info = GetWidgetInfo(application);
EXPECT_TRUE(info);
- scoped_ptr<base::DictionaryValue> Copy(info->GetWidgetInfo()->DeepCopy());
+ scoped_ptr<base::DictionaryValue>
+ deep_copy(info->GetWidgetInfo()->DeepCopy());
base::DictionaryValue* widget_parsed_from_manifest;
- Copy->GetAsDictionary(&widget_parsed_from_manifest);
- EXPECT_TRUE(widget_parsed_from_manifest);
+ EXPECT_TRUE(deep_copy->GetAsDictionary(&widget_parsed_from_manifest));
// Create a widget with one preference item manually.
scoped_ptr<base::DictionaryValue> widget(new base::DictionaryValue);
SetAllInfoToWidget(widget.get());
- widget->Set(kWidgetPreferences, GetPreferencesItem(0, false));
+ widget->Set(kWidgetPreferences,
+ GetPreferencesItem<Manifest::TYPE_WIDGET>(0));
// Compare the widget parsed from manifest with
// the widget create manually.
TEST_F(WidgetHandlerTest,
ParseManifestWithAllOfOtherItemsAndThreePreferenceItemsList) {
// Create a manifest with three preference items.
- scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
SetAllInfoToManifest(manifest.get());
base::ListValue* manifestPreferences = new base::ListValue;
for (int i = 0; i < 3; i++) {
- manifestPreferences->Append(GetPreferencesItem(i, true));
+ manifestPreferences->Append(GetPreferencesItem<Manifest::TYPE_MANIFEST>(i));
}
+ // TODO(aszafranek): Set manifestPreferences to manifest and test it below
// Create an application use this manifest,
- scoped_refptr<ApplicationData> application;
- application = CreateApplication(*(manifest.get()));
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
EXPECT_TRUE(application.get());
EXPECT_EQ(application->manifest_type(), Manifest::TYPE_WIDGET);
// Get widget info from this application.
WidgetInfo* info = GetWidgetInfo(application);
EXPECT_TRUE(info);
- scoped_ptr<base::DictionaryValue> Copy(info->GetWidgetInfo()->DeepCopy());
+ scoped_ptr<base::DictionaryValue>
+ deep_copy(info->GetWidgetInfo()->DeepCopy());
base::DictionaryValue* widget_parsed_from_manifest;
- Copy->GetAsDictionary(&widget_parsed_from_manifest);
- EXPECT_TRUE(widget_parsed_from_manifest);
+ EXPECT_TRUE(deep_copy->GetAsDictionary(&widget_parsed_from_manifest));
// Create a widget with three preference items manually.
scoped_ptr<base::DictionaryValue> widget(new base::DictionaryValue);
SetAllInfoToWidget(widget.get());
- base::ListValue* widgetPreferences = new base::ListValue;
+ base::ListValue* widgetPreferences = new base::ListValue;
for (int i = 0; i < 3; i++) {
- widgetPreferences->Append(GetPreferencesItem(i, false));
+ widgetPreferences->Append(GetPreferencesItem<Manifest::TYPE_WIDGET>(i));
}
// Compare the widget parsed from manifest with
TEST_F(WidgetHandlerTest,
ParseManifestWithInvalidAuthorHrefValue) {
- scoped_ptr<base::DictionaryValue> manifest(new base::DictionaryValue);
+ scoped_ptr<base::DictionaryValue> manifest = CreateDefaultWidgetConfig();
SetAllInfoToManifest(manifest.get());
manifest->SetString(keys::kAuthorHrefKey, "INVALID_HREF");
// Create an application use this manifest,
- scoped_refptr<ApplicationData> application;
- application = CreateApplication(*(manifest.get()));
+ scoped_refptr<ApplicationData> application =
+ CreateApplication(Manifest::TYPE_WIDGET, *manifest);
EXPECT_TRUE(application.get());
EXPECT_EQ(application->manifest_type(), Manifest::TYPE_WIDGET);
// Get widget info from this application.
info->GetWidgetInfo()->GetString(keys::kAuthorHrefKey, &authorhref);
EXPECT_TRUE(authorhref.empty());
}
+
} // namespace application
} // namespace xwalk
XPKPackage::XPKPackage(const base::FilePath& path)
: Package(path, Manifest::TYPE_MANIFEST),
+ header_(),
zip_addr_(0) {
if (!base::PathExists(path))
return;
// 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 = "";
}
var WidgetStorage = function() {
- var _keyList = new Array();
- var _itemStorage = new Object();
-
var _SetItem = function(itemKey, itemValue) {
var result = extension.internal.sendSyncMessage({
cmd: 'SetPreferencesItem',
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(
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) {
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.');
}
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();
#include "xwalk/application/extension/application_widget_extension.h"
+#include <vector>
+
#include "base/bind.h"
#include "base/path_service.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
using content::BrowserThread;
namespace {
+
const char kCommandKey[] = "cmd";
const char kWidgetAttributeKey[] = "widgetKey";
const char kPreferencesItemKey[] = "preferencesItemKey";
const char kPreferencesItemValue[] = "preferencesItemValue";
+
+void DispatchStorageEvent(
+ base::DictionaryValue* msg,
+ content::WebContents* web_contents,
+ content::RenderFrameHost* frame) {
+ if (frame == web_contents->GetFocusedFrame())
+ return;
+
+ std::string key, oldValue, newValue;
+ msg->GetString("key", &key);
+ msg->GetString("oldValue", &oldValue);
+ msg->GetString("newValue", &newValue);
+
+ std::string code = base::StringPrintf(
+ "(function() {"
+ " var old_value = '%s' == '' ? null : '%s';"
+ " var new_value = '%s' == '' ? null : '%s';"
+ " var event = {"
+ " key: '%s',"
+ " oldValue: old_value,"
+ " newValue: new_value,"
+ " url: window.location.href,"
+ " storageArea: widget.preferences"
+ " };"
+ " for (var key in event) {"
+ " Object.defineProperty(event, key, {"
+ " value: event[key],"
+ " writable: false"
+ " });"
+ " }"
+ " for (var i = 0; i < window.eventListenerList.length; i++)"
+ " window.eventListenerList[i](event);"
+ "})();", oldValue.c_str(), oldValue.c_str(),
+ newValue.c_str(), newValue.c_str(), key.c_str());
+
+ frame->ExecuteJavaScript(base::UTF8ToUTF16(code));
}
+} // namespace
+
namespace xwalk {
namespace application {
AppWidgetExtensionInstance::AppWidgetExtensionInstance(
Application* application)
- : application_(application),
- handler_(this) {
+ : application_(application) {
DCHECK(application_);
base::ThreadRestrictions::SetIOAllowed(true);
AppWidgetExtensionInstance::~AppWidgetExtensionInstance() {}
void AppWidgetExtensionInstance::HandleMessage(scoped_ptr<base::Value> msg) {
- handler_.HandleMessage(msg.Pass());
}
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 {
return result.Pass();
}
- if (widget_storage_->AddEntry(key, value, false))
+ std::string old_value;
+ if (!widget_storage_->GetValueByKey(key, &old_value)) {
+ old_value = "";
+ }
+ if (old_value == value) {
+ LOG(WARNING) << "You are trying to set the same value."
+ << " Nothing will be done.";
+ result.reset(new base::FundamentalValue(true));
+ return result.Pass();
+ }
+ if (widget_storage_->AddEntry(key, value, false)) {
result.reset(new base::FundamentalValue(true));
+ scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue());
+ event->SetString("key", key);
+ event->SetString("oldValue", old_value);
+ event->SetString("newValue", value);
+ PostMessageToOtherFrames(event.Pass());
+ }
+
return result.Pass();
}
return result.Pass();
}
- if (widget_storage_->RemoveEntry(key))
+ std::string old_value;
+ if (!widget_storage_->GetValueByKey(key, &old_value)) {
+ LOG(WARNING) << "You are trying to remove an entry which doesn't exist."
+ << " Nothing will be done.";
result.reset(new base::FundamentalValue(true));
+ return result.Pass();
+ }
+
+ if (widget_storage_->RemoveEntry(key)) {
+ result.reset(new base::FundamentalValue(true));
+
+ scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue());
+ event->SetString("key", key);
+ event->SetString("oldValue", old_value);
+ event->SetString("newValue", "");
+ PostMessageToOtherFrames(event.Pass());
+ }
return result.Pass();
}
scoped_ptr<base::FundamentalValue> result(
new base::FundamentalValue(false));
- if (widget_storage_->Clear())
- result.reset(new base::FundamentalValue(true));
+ scoped_ptr<base::DictionaryValue> entries(new base::DictionaryValue());
+ widget_storage_->GetAllEntries(entries.get());
+ if (!widget_storage_->Clear())
+ return result.Pass();
+
+ for (base::DictionaryValue::Iterator it(*(entries.get()));
+ !it.IsAtEnd(); it.Advance()) {
+ std::string key = it.key();
+ if (!widget_storage_->EntryExists(key)) {
+ std::string old_value;
+ it.value().GetAsString(&old_value);
+ scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue());
+ event->SetString("key", key);
+ event->SetString("oldValue", old_value);
+ event->SetString("newValue", "");
+ PostMessageToOtherFrames(event.Pass());
+ }
+ }
+
+ result.reset(new base::FundamentalValue(true));
return result.Pass();
}
return result.Pass();
}
+scoped_ptr<base::StringValue> AppWidgetExtensionInstance::GetItemValueByKey(
+ scoped_ptr<base::Value> msg) {
+ base::DictionaryValue* dict;
+ msg->GetAsDictionary(&dict);
+
+ std::string key;
+ std::string value;
+ if (!dict->GetString(kPreferencesItemKey, &key) ||
+ !widget_storage_->GetValueByKey(key, &value))
+ value = "";
+ scoped_ptr<base::StringValue> result(new base::StringValue(value));
+ return result.Pass();
+}
+
scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::KeyExists(
scoped_ptr<base::Value> msg) const {
scoped_ptr<base::FundamentalValue> result(
return result.Pass();
}
+void AppWidgetExtensionInstance::PostMessageToOtherFrames(
+ scoped_ptr<base::DictionaryValue> msg) {
+ const std::vector<Runtime*>& runtime_set = application_->runtimes();
+ std::vector<Runtime*>::const_iterator it;
+ for (it = runtime_set.begin(); it != runtime_set.end(); ++it) {
+ content::WebContents* web_contents = (*it)->web_contents();
+ web_contents->ForEachFrame(base::Bind(&DispatchStorageEvent,
+ msg.get(),
+ web_contents));
+ }
+}
+
} // namespace application
} // namespace xwalk
#include <string>
-#include "xwalk/extensions/browser/xwalk_extension_function_handler.h"
#include "xwalk/extensions/common/xwalk_extension.h"
namespace xwalk {
class Application;
using extensions::XWalkExtension;
-using extensions::XWalkExtensionFunctionHandler;
-using extensions::XWalkExtensionFunctionInfo;
using extensions::XWalkExtensionInstance;
class ApplicationWidgetExtension : public XWalkExtension {
scoped_ptr<base::Value> mgs);
scoped_ptr<base::FundamentalValue> ClearAllItems(scoped_ptr<base::Value> mgs);
scoped_ptr<base::DictionaryValue> GetAllItems(scoped_ptr<base::Value> mgs);
+ scoped_ptr<base::StringValue> GetItemValueByKey(scoped_ptr<base::Value> mgs);
scoped_ptr<base::FundamentalValue> KeyExists(
scoped_ptr<base::Value> mgs) const;
+ void PostMessageToOtherFrames(scoped_ptr<base::DictionaryValue> msg);
Application* application_;
scoped_ptr<class AppWidgetStorage> widget_storage_;
- XWalkExtensionFunctionHandler handler_;
};
} // namespace application
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 = ?";
}
sql::Transaction transaction(sqlite_db_.get());
- transaction.Begin();
+ if (!transaction.Begin())
+ return false;
if (!sqlite_db_->Execute(kCreateStorageTableOp))
return false;
if (!transaction.Commit())
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;
}
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);
}
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;
}
return false;
sql::Transaction transaction(sqlite_db_.get());
- transaction.Begin();
+ if (!transaction.Begin())
+ return false;
sql::Statement stmt(sqlite_db_->GetUniqueStatement(
kClearStorageTableWithBindOp));
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();
+++ /dev/null
-// 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
-}
+++ /dev/null
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef XWALK_APPLICATION_TOOLS_LINUX_DBUS_CONNECTION_H_
-#define XWALK_APPLICATION_TOOLS_LINUX_DBUS_CONNECTION_H_
-
-#include <gio/gio.h>
-
-GDBusConnection* get_session_bus_connection(GError** error);
-
-#endif // XWALK_APPLICATION_TOOLS_LINUX_DBUS_CONNECTION_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/application/tools/linux/dbus_object_manager.h"
+
+#include "base/message_loop/message_loop.h"
+
+namespace {
+
+const char kServiceName[] = "org.crosswalkproject.Runtime1";
+const char kRunningManagerIface[] = "org.crosswalkproject.Running.Manager1";
+const char kRunningAppIface[] = "org.crosswalkproject.Running.Application1";
+const char kRunningManagerDBusPath[] = "/running1";
+const char kEPChannelCreatedSignalName[] = "EPChannelCreated";
+
+struct Properties : public dbus::PropertySet {
+ dbus::Property<std::string> app_id;
+
+ Properties(dbus::ObjectProxy* object_proxy,
+ const std::string& interface_name,
+ PropertyChangedCallback property_changed_callback)
+ : PropertySet(object_proxy, interface_name, property_changed_callback) {
+ RegisterProperty("AppID", &app_id);
+ }
+};
+
+} // namespace
+
+DBusObjectManager::DBusObjectManager(dbus::Bus* bus,
+ base::MessageLoop* main_loop)
+ : bus_(bus),
+ main_loop_(main_loop),
+ weak_ptr_factory_(this) {
+ ConnectToApplicationManager();
+}
+
+bool DBusObjectManager::Launch(const std::string& appid_or_url,
+ int launcher_pid, bool fullscreen, bool remote_debugging) {
+ if (!running_proxy_)
+ return false;
+ dbus::MethodCall method_call(
+ kRunningManagerIface, "Launch");
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendString(appid_or_url);
+ writer.AppendUint32(launcher_pid);
+ writer.AppendBool(fullscreen);
+ writer.AppendBool(remote_debugging);
+ scoped_ptr<dbus::Response> response(
+ running_proxy_->CallMethodAndBlock(&method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
+ if (!response.get())
+ return false;
+ if (!response->GetErrorName().empty()) {
+ LOG(ERROR) << "Error during call to 'Launch': "
+ << response->GetErrorName();
+ return false;
+ }
+
+ dbus::MessageReader reader(response.get());
+ dbus::ObjectPath running_application_path;
+ if (!reader.PopObjectPath(&running_application_path)) {
+ LOG(WARNING) << "Failed to create app proxy.";
+ } else {
+ app_proxy_ = bus_->GetObjectProxy(kServiceName, running_application_path);
+ if (app_proxy_)
+ ConnectToApplicationSignal(kEPChannelCreatedSignalName);
+ }
+ return true;
+}
+
+std::pair<std::string, int> DBusObjectManager::GetEPChannel() const {
+ std::pair<std::string, int> fd;
+ if (!app_proxy_) {
+ fd.second = -1;
+ return fd;
+ }
+ dbus::MethodCall method_call(kRunningAppIface, "GetEPChannel");
+ scoped_ptr<dbus::Response> response = app_proxy_->CallMethodAndBlock(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+ const std::string& error = response->GetErrorName();
+ if (!error.empty()) {
+ LOG(ERROR) << "Error during call to 'GetEPChannel': "
+ << error;
+ fd.second = -1;
+ return fd;
+ }
+ dbus::MessageReader reader(response.release());
+ dbus::FileDescriptor extension_process_fd_;
+ if (!reader.PopString(&fd.first) ||
+ !reader.PopFileDescriptor(&extension_process_fd_)) {
+ LOG(ERROR) << "Couldn't get EP Channel";
+ fd.second = -1;
+ return fd;
+ }
+ extension_process_fd_.CheckValidity();
+ fd.second = extension_process_fd_.TakeValue();
+ return fd;
+}
+
+bool DBusObjectManager::Suspend() {
+ if (!app_proxy_)
+ return false;
+ dbus::MethodCall method_call(kRunningAppIface, "Suspend");
+ scoped_ptr<dbus::Response> response = app_proxy_->CallMethodAndBlock(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+ if (!response->GetErrorName().empty()) {
+ LOG(ERROR) << "Error during call to 'Suspend': "
+ << response->GetErrorName();
+ return false;
+ }
+ return true;
+}
+
+bool DBusObjectManager::Resume() {
+ if (!app_proxy_)
+ return false;
+ dbus::MethodCall method_call(kRunningAppIface, "Resume");
+ scoped_ptr<dbus::Response> response = app_proxy_->CallMethodAndBlock(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
+ if (!response->GetErrorName().empty()) {
+ LOG(ERROR) << "Error during call to 'Resume': "
+ << response->GetErrorName();
+ return false;
+ }
+ return true;
+}
+
+void DBusObjectManager::OnOwnershipCallback(const std::string& service_name,
+ bool success) {
+ LOG(WARNING) << "Couldn't get ownership of D-Bus service name: "
+ << service_name << ".";
+}
+
+void DBusObjectManager::ConnectToApplicationManager() {
+ running_apps_manager_ = bus_->GetObjectManager(kServiceName,
+ dbus::ObjectPath(kRunningManagerDBusPath));
+ running_apps_manager_->RegisterInterface(kRunningAppIface, this);
+ running_proxy_ = bus_->GetObjectProxy(kServiceName,
+ dbus::ObjectPath(kRunningManagerDBusPath));
+}
+
+void DBusObjectManager::ObjectAdded(const dbus::ObjectPath& object_path,
+ const std::string& interface_name) {
+}
+
+void DBusObjectManager::ObjectRemoved(const dbus::ObjectPath& object_path,
+ const std::string& interface_name) {
+ if (object_path != app_proxy_->object_path())
+ return;
+ LOG(INFO) << "Application '" << object_path.value()
+ << "' disappeared, exiting.";
+ main_loop_->QuitNow();
+}
+
+dbus::PropertySet* DBusObjectManager::CreateProperties(
+ dbus::ObjectProxy *object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) {
+ Properties* properties = new Properties(
+ object_proxy, interface_name,
+ base::Bind(&DBusObjectManager::OnPropertyChanged,
+ base::Unretained(this), object_path));
+ return static_cast<dbus::PropertySet*>(properties);
+}
+
+void DBusObjectManager::OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& name) {
+ if (!running_apps_manager_)
+ ConnectToApplicationManager();
+}
+
+void DBusObjectManager::ConnectToApplicationSignal(
+ const std::string& signal_name) {
+ DCHECK(app_proxy_);
+ app_proxy_->ConnectToSignal(kRunningAppIface, signal_name,
+ base::Bind(&DBusObjectManager::OnAppSignal,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&DBusObjectManager::OnAppSignalConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+bool DBusObjectManager::IsApplicationRunning(const std::string& app_id) {
+ std::vector<dbus::ObjectPath> objects = running_apps_manager_->GetObjects();
+ bool is_running = false;
+ for (dbus::ObjectPath obj : objects) {
+ Properties* properties =
+ static_cast<Properties*>(
+ running_apps_manager_->GetProperties(
+ obj, kRunningAppIface));
+ if (!properties)
+ continue;
+ if (properties->app_id.value() == app_id) {
+ is_running = true;
+ break;
+ }
+ }
+ LOG(INFO) << "Application " << app_id << " is "
+ << (is_running ? "running." : "not running.");
+ return is_running;
+}
+
+void DBusObjectManager::OnAppSignal(dbus::Signal* signal) {
+ std::string signal_name = signal->GetMember();
+ if (signal_name == kEPChannelCreatedSignalName) {
+ if (observer_)
+ observer_->OnEPChannelCreated();
+ } else {
+ LOG(INFO) << "Unknown signal received: " << signal_name;
+ }
+}
+
+void DBusObjectManager::OnAppSignalConnected(
+ const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ if (!success)
+ LOG(WARNING) << "Failed to connect signal: " << signal_name;
+}
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_
+#define XWALK_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/threading/thread.h"
+#include "base/values.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/message.h"
+#include "dbus/object_manager.h"
+#include "dbus/object_path.h"
+#include "dbus/object_proxy.h"
+#include "dbus/property.h"
+
+class DBusObjectManager : public dbus::ObjectManager::Interface {
+ public:
+ class Observer {
+ public:
+ virtual void OnEPChannelCreated() = 0;
+
+ protected:
+ virtual ~Observer() {}
+ };
+
+ DBusObjectManager(dbus::Bus* bus, base::MessageLoop* main_loop);
+
+ bool Launch(const std::string& appid_or_url, int launcher_pid,
+ bool fullscreen, bool remote_debugging);
+ std::pair<std::string, int> GetEPChannel() const;
+ bool Suspend();
+ bool Resume();
+
+ bool IsApplicationRunning(const std::string& app_id);
+
+ void SetObserver(Observer* observer) { observer_ = observer; }
+
+ private:
+ void OnOwnershipCallback(const std::string& service_name, bool success);
+ void ObjectAdded(const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override;
+ void ObjectRemoved(const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override;
+ dbus::PropertySet* CreateProperties(
+ dbus::ObjectProxy* object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override;
+
+ void OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& name);
+
+ void ConnectToApplicationManager();
+ void ConnectToApplicationSignal(const std::string& signal_name);
+ void OnAppSignal(dbus::Signal* signal);
+ void OnAppSignalConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success);
+
+ scoped_refptr<dbus::Bus> bus_;
+ dbus::ObjectManager* running_apps_manager_;
+ dbus::ObjectProxy* running_proxy_;
+ dbus::ObjectProxy* app_proxy_;
+
+ // this is needed for exit events which come via dbus interface
+ base::MessageLoop* main_loop_;
+
+ base::WeakPtrFactory<DBusObjectManager> weak_ptr_factory_;
+
+ Observer* observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(DBusObjectManager);
+};
+
+#endif // XWALK_APPLICATION_TOOLS_LINUX_DBUS_OBJECT_MANAGER_H_
'../../../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',
'../../../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',
'../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',
],
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unistd.h>
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "dbus/object_proxy.h"
+
+#include "base/logging.h"
+
+#include "xwalk/application/tools/linux/xwalk_launcher.h"
+
+namespace {
+
+const char xwalk_service_name[] = "org.crosswalkproject.Runtime1";
+const char xwalk_running_path[] = "/running1";
+const char xwalk_running_manager_iface[] =
+ "org.crosswalkproject.Running.Manager1";
+const char xwalk_running_app_iface[] =
+ "org.crosswalkproject.Running.Application1";
+
+} // namespace
+
+XWalkLauncher::XWalkLauncher(bool query_running, base::MessageLoop* main_loop)
+ : ep_launcher_(nullptr),
+ query_running_(query_running),
+ main_loop_(main_loop) {
+ base::Thread::Options thread_options;
+ thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+ dbus_thread_.reset(new base::Thread("Crosswalk D-Bus thread"));
+ dbus_thread_->StartWithOptions(thread_options);
+
+ dbus::Bus::Options options;
+#if defined (OS_TIZEN_MOBILE)
+ options.bus_type = dbus::Bus::CUSTOM_ADDRESS;
+ options.address.assign("unix:path=/run/user/app/dbus/user_bus_socket");
+#endif
+ options.bus_type = dbus::Bus::SESSION;
+ options.connection_type = dbus::Bus::PRIVATE;
+ options.dbus_task_runner = dbus_thread_->message_loop_proxy();
+ dbus::Bus* bus = new dbus::Bus(options);
+ bus->Connect();
+ bus->GetManagedObjects();
+
+ dbus_object_manager_.reset(new DBusObjectManager(bus, main_loop));
+ dbus_object_manager_->SetObserver(this);
+}
+
+XWalkLauncher::~XWalkLauncher() {
+}
+
+int XWalkLauncher::Launch(const std::string& appid_or_url, bool fullscreen,
+ bool remote_debugging, int argc, char* argv[]) {
+ appid_or_url_ = appid_or_url;
+ fullscreen_ = fullscreen;
+ remote_debugging_ = remote_debugging;
+
+ // Query app.
+ if (query_running_) {
+ return dbus_object_manager_->IsApplicationRunning(appid_or_url_);
+ }
+
+ return !LaunchApplication();
+}
+
+int XWalkLauncher::LaunchApplication() {
+ ep_launcher_.reset(new XWalkExtensionProcessLauncher());
+
+ launcher_pid_ = getpid();
+ if (!dbus_object_manager_->Launch(appid_or_url_, launcher_pid_,
+ fullscreen_, remote_debugging_))
+ return 1;
+ return InitExtensionProcessChannel();
+}
+
+bool XWalkLauncher::InitExtensionProcessChannel() {
+ if (ep_launcher_->is_started())
+ return false;
+
+ // Need to call method via DBus to get EP channel
+ std::pair<std::string, int> fd = dbus_object_manager_->GetEPChannel();
+ if (fd.first.empty() || fd.second < 0)
+ return false;
+ ep_launcher_->Launch(fd.first, fd.second);
+ return true;
+}
+
+void XWalkLauncher::OnEPChannelCreated() {
+ InitExtensionProcessChannel();
+}
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_H_
+#define XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/threading/thread.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+
+#include "xwalk/application/tools/linux/dbus_object_manager.h"
+#include "xwalk/application/tools/linux/xwalk_extension_process_launcher.h"
+
+class XWalkLauncher : public DBusObjectManager::Observer {
+ public:
+ XWalkLauncher(bool query_running, base::MessageLoop* main_loop);
+ virtual ~XWalkLauncher();
+ virtual int Launch(const std::string& appid_or_url, bool fullscreen,
+ bool remote_debugging, int argc = 0,
+ char* argv[] = nullptr);
+
+ protected:
+ int LaunchApplication();
+
+ std::unique_ptr<XWalkExtensionProcessLauncher> ep_launcher_;
+
+ unsigned int launcher_pid_;
+ std::string appid_or_url_;
+ bool fullscreen_;
+ bool remote_debugging_;
+ bool query_running_;
+
+ base::MessageLoop* main_loop_;
+
+ std::unique_ptr<DBusObjectManager> dbus_object_manager_;
+
+ private:
+ bool InitExtensionProcessChannel();
+ virtual void OnEPChannelCreated() override;
+
+ std::unique_ptr<base::Thread> dbus_thread_;
+};
+
+#endif // XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_H_
// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <libgen.h>
-
#include <glib.h>
-#include <gio/gio.h>
-#include <gio/gunixfdlist.h>
-#include "xwalk/application/tools/linux/dbus_connection.h"
-#include "xwalk/application/tools/linux/xwalk_extension_process_launcher.h"
+#include <memory>
+
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump.h"
+#include "base/message_loop/message_pump_glib.h"
+#include "base/run_loop.h"
+
+#include "xwalk/application/tools/linux/xwalk_launcher.h"
#if defined(OS_TIZEN)
-#include "url/gurl.h"
#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
-#include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
#endif
-static const char* xwalk_service_name = "org.crosswalkproject.Runtime1";
-static const char* xwalk_running_path = "/running1";
-static const char* xwalk_running_manager_iface =
- "org.crosswalkproject.Running.Manager1";
-static const char* xwalk_running_app_iface =
- "org.crosswalkproject.Running.Application1";
+namespace {
-static char* application_object_path;
+int g_argc;
+char** g_argv;
+gboolean query_running = FALSE;
+gboolean fullscreen = FALSE;
+gboolean remote_debugging = FALSE;
+gchar** cmd_appid_or_url;
+char* application_object_path;
-static GMainLoop* mainloop;
-static GDBusConnection* g_connection;
-static GDBusObjectManager* g_running_apps_manager;
-static XWalkExtensionProcessLauncher* ep_launcher = NULL;
+} // namespace
-static int g_argc;
-static char** g_argv;
-static gboolean query_running = FALSE;
-static gboolean fullscreen = FALSE;
-static gboolean remote_debugging = FALSE;
-static gchar** cmd_appid_or_url;
-
-static GOptionEntry entries[] = {
+static const GOptionEntry entries[] {
{ "running", 'r', 0, G_OPTION_ARG_NONE, &query_running,
- "Check whether the application is running", NULL },
+ "Check whether the application is running", nullptr },
{ "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &fullscreen,
- "Run the application as fullscreen", NULL },
+ "Run the application as fullscreen", nullptr },
{ "debugging_port", 'd', 0, G_OPTION_ARG_NONE, &remote_debugging,
- "Enable remote debugging for the application", NULL },
- { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &cmd_appid_or_url,
- "ID of the application to be launched or URL to open", NULL },
- { NULL }
+ "Enable remote debugging for the application", nullptr },
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY,
+ &cmd_appid_or_url,
+ "ID of the application to be launched or URL to open", nullptr },
+ { nullptr }
};
-static void object_removed(GDBusObjectManager* manager, GDBusObject* object,
- gpointer user_data) {
- const char* path = g_dbus_object_get_object_path(object);
-
- if (g_strcmp0(path, application_object_path))
- return;
-
- fprintf(stderr, "Application '%s' disappeared, exiting.\n", path);
-
- delete ep_launcher;
- g_main_loop_quit(mainloop);
-}
-
-static void on_app_properties_changed(GDBusProxy* proxy,
- GVariant* changed_properties,
- GStrv invalidated_properties,
- gpointer user_data) {
- const char* interface = g_dbus_proxy_get_interface_name(proxy);
-
- fprintf(stderr, "properties changed %s\n", interface);
-
- if (g_variant_n_children(changed_properties) == 0)
- return;
-
- if (g_strcmp0(interface, xwalk_running_app_iface))
- return;
-
- GVariantIter* iter;
- const gchar* key;
- GVariant* value;
-
- g_variant_get(changed_properties, "a{sv}", &iter);
-
- while (g_variant_iter_loop(iter, "{&sv}", &key, &value)) {
- if (g_strcmp0(key, "State"))
- continue;
-
- const gchar* state = g_variant_get_string(value, NULL);
-
- fprintf(stderr, "Application state %s\n", state);
- }
-}
-
-static gboolean init_extension_process_channel(GDBusProxy* app_proxy) {
- if (ep_launcher->is_started())
- return FALSE;
-
- // Get the client socket file descriptor from fd_list. The reply will
- // contains an index to the list.
- GUnixFDList* fd_list;
- GVariant* res = g_dbus_proxy_call_with_unix_fd_list_sync(
- app_proxy, "GetEPChannel", NULL, G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &fd_list, NULL, NULL);
- if (!res || g_variant_n_children(res) != 2)
- return FALSE;
-
- const gchar* channel_id =
- g_variant_get_string(g_variant_get_child_value(res, 0), NULL);
- if (!channel_id || !strlen(channel_id))
- return FALSE;
-
- gint32 client_fd_idx =
- g_variant_get_handle(g_variant_get_child_value(res, 1));
- int client_fd = g_unix_fd_list_get(fd_list, client_fd_idx, NULL);
-
- ep_launcher->Launch(channel_id, client_fd);
- return TRUE;
-}
-
-static void on_app_signal(GDBusProxy* proxy,
- gchar* sender_name,
- gchar* signal_name,
- GVariant* parameters,
- gpointer user_data) {
- if (!strcmp(signal_name, "EPChannelCreated")) {
- init_extension_process_channel(proxy);
- } else {
- fprintf(stderr, "Unkown signal received: %s\n", signal_name);
- }
-}
-
-static int query_application_running(const char* app_id) {
- GList* objects = g_dbus_object_manager_get_objects(g_running_apps_manager);
- GList* it;
- bool is_running = FALSE;
-
- for (it = objects; it; it = it->next) {
- GDBusObject* object = reinterpret_cast<GDBusObject*>(it->data);
- GDBusInterface* iface = g_dbus_object_get_interface(
- object,
- xwalk_running_app_iface);
- if (!iface)
- continue;
-
- GDBusProxy* proxy = G_DBUS_PROXY(iface);
- GVariant* id_variant;
- id_variant = g_dbus_proxy_get_cached_property(proxy, "AppID");
- if (!id_variant) {
- g_object_unref(iface);
- continue;
- }
-
- const gchar* id;
- g_variant_get(id_variant, "s", &id);
- if (!strcmp(app_id, id)) {
- is_running = TRUE;
- break;
- }
-
- g_object_unref(iface);
- }
- const char* str = is_running ? "running" : "not running";
- g_print("Application %s is %s.\n", app_id, str);
-
- g_list_free_full(objects, g_object_unref);
- return is_running ? 0 : 1;
-}
-
-static void launch_application(const char* appid_or_url,
- gboolean fullscreen,
- gboolean remote_debugging) {
- ep_launcher = new XWalkExtensionProcessLauncher();
- GError* error = NULL;
- g_signal_connect(g_running_apps_manager, "object-removed",
- G_CALLBACK(object_removed), NULL);
-
- GDBusProxy* running_proxy = g_dbus_proxy_new_sync(
- g_connection,
- G_DBUS_PROXY_FLAGS_NONE, NULL, xwalk_service_name,
- xwalk_running_path, xwalk_running_manager_iface, NULL, &error);
- if (!running_proxy) {
- g_print("Couldn't create proxy for '%s': %s\n", xwalk_running_manager_iface,
- error->message);
- g_error_free(error);
- exit(1);
- }
-
- unsigned int launcher_pid = getpid();
-
- GVariant* result = g_dbus_proxy_call_sync(running_proxy, "Launch",
- g_variant_new("(subb)", appid_or_url, launcher_pid, fullscreen,
- remote_debugging),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
- if (!result) {
- fprintf(stderr, "Couldn't call 'Launch' method: %s\n", error->message);
- exit(1);
- }
-
- g_variant_get(result, "(o)", &application_object_path);
- fprintf(stderr, "Application launched with path '%s'\n",
- application_object_path);
-
- GDBusProxy* app_proxy = g_dbus_proxy_new_sync(
- g_connection,
- G_DBUS_PROXY_FLAGS_NONE, NULL, xwalk_service_name,
- application_object_path, xwalk_running_app_iface, NULL, &error);
- if (!app_proxy) {
- g_print("Couldn't create proxy for '%s': %s\n", xwalk_running_app_iface,
- error->message);
- g_error_free(error);
- exit(1);
- }
-
- g_signal_connect(app_proxy, "g-properties-changed",
- G_CALLBACK(on_app_properties_changed), NULL);
-
- mainloop = g_main_loop_new(NULL, FALSE);
- g_signal_connect(app_proxy, "g-signal", G_CALLBACK(on_app_signal), NULL);
-
-#if defined(OS_TIZEN)
- char name[128];
- snprintf(name, sizeof(name), "xwalk-%s", appid_or_url);
-
- if (xwalk_appcore_init(g_argc, g_argv, name, app_proxy)) {
- fprintf(stderr, "Failed to initialize appcore");
- exit(1);
- }
-#endif
-
- init_extension_process_channel(app_proxy);
- g_main_loop_run(mainloop);
-}
-
-void connect_to_application_manager() {
- GError* error = NULL;
- g_connection = get_session_bus_connection(&error);
- if (!g_connection) {
- fprintf(stderr, "Couldn't get the session bus connection: %s\n",
- error->message);
- exit(1);
- }
-
- g_running_apps_manager =
- g_dbus_object_manager_client_new_sync(
- g_connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
- xwalk_service_name, xwalk_running_path,
- NULL, NULL, NULL, NULL, &error);
- if (!g_running_apps_manager) {
- fprintf(stderr, "Service '%s' does could not be reached: %s\n",
- xwalk_service_name, error->message);
- exit(1);
- }
-}
-
int main(int argc, char** argv) {
- GError* error = NULL;
- char* appid_or_url;
-
- g_argc = argc;
- g_argv = argv;
-
#if !GLIB_CHECK_VERSION(2, 36, 0)
// g_type_init() is deprecated on GLib since 2.36.
g_type_init();
#if defined(OS_TIZEN)
if (xwalk_tizen_check_group_users())
- exit(1);
+ return 1;
#endif
+ base::MessageLoop msg_loop(
+ make_scoped_ptr<base::MessagePump>(new base::MessagePumpGlib()));
+
+ g_argc = argc;
+ g_argv = argv;
+ GError* error = nullptr;
GOptionContext* context =
g_option_context_new("- Crosswalk Application Launcher");
- g_option_context_add_main_entries(context, entries, NULL);
+ g_option_context_add_main_entries(context, entries, nullptr);
if (!g_option_context_parse(context, &argc, &argv, &error)) {
- fprintf(stderr, "Option parsing failed: %s\n", error->message);
+ LOG(ERROR) << "Option parsing failed: " << error->message;
exit(1);
}
- connect_to_application_manager();
-
- // Launch app.
- if (!strcmp(basename(argv[0]), "xwalk-launcher")) {
- if (cmd_appid_or_url == NULL) {
- fprintf(stderr, "No AppID informed, nothing to do.\n");
- return 0;
- }
- appid_or_url = strdup(cmd_appid_or_url[0]);
-#if defined(OS_TIZEN)
- if (GURL(appid_or_url).spec().empty()
- && xwalk_change_cmdline(argc, argv, appid_or_url))
+ std::string appid_or_url;
+ if (!strcmp(basename(g_argv[0]), "xwalk-launcher")) {
+ if (!cmd_appid_or_url) {
+ LOG(ERROR) << "No AppID informed, nothing to do.";
exit(1);
-#endif
+ }
+ appid_or_url = std::string(cmd_appid_or_url[0]);
} else {
- appid_or_url = strdup(basename(argv[0]));
+ appid_or_url = std::string(basename(g_argv[0]));
}
-
- // Query app.
- if (query_running) {
- return query_application_running(appid_or_url);
- }
-
- launch_application(appid_or_url, fullscreen, remote_debugging);
- free(appid_or_url);
- return 0;
+ std::unique_ptr<XWalkLauncher> launcher;
+#if defined(OS_TIZEN)
+ launcher.reset(new XWalkLauncherTizen(query_running, &msg_loop));
+#else
+ launcher.reset(new XWalkLauncher(query_running, &msg_loop));
+#endif
+ int result = launcher->Launch(appid_or_url, fullscreen, remote_debugging,
+ argc, argv);
+ if (!result)
+ msg_loop.Run();
+ return result;
}
// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <glib.h>
-#include <gio/gio.h>
+#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
+
+#include <unistd.h>
+#include <pkgmgr-info.h>
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
-#include <appcore/appcore-common.h>
-#include <pkgmgr-info.h>
+#include <string.h>
-#include "xwalk/application/common/id_util.h"
-#include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
+#include <string>
-enum app_event {
- AE_UNKNOWN,
- AE_CREATE,
- AE_TERMINATE,
- AE_PAUSE,
- AE_RESUME,
- AE_RESET,
- AE_LOWMEM_POST,
- AE_MEM_FLUSH,
- AE_MAX
-};
+#include "base/logging.h"
+#include "url/gurl.h"
// Private struct from appcore-internal, necessary to get events from
// the system.
struct ui_ops {
void* data;
- void (*cb_app)(enum app_event evnt, void* data, bundle* b);
+ void (*cb_app)(app_event evnt, void* data, bundle* b);
};
-static struct ui_ops appcore_ops;
+namespace {
-static const char* event2str(enum app_event event) {
+const char* Event2Str(app_event event) {
switch (event) {
case AE_UNKNOWN:
return "AE_UNKNOWN";
return "INVALID EVENT";
}
-static void application_event_cb(enum app_event event, void* data, bundle* b) {
- fprintf(stderr, "event '%s'\n", event2str(event));
- GDBusProxy* app_proxy = reinterpret_cast<GDBusProxy*>(data);
+ui_ops app_ops;
+
+} // namespace
- if (!app_proxy) {
- fprintf(stderr, "Invalid DBus proxy.");
- return;
+XWalkLauncherTizen::XWalkLauncherTizen(bool query_running,
+ base::MessageLoop* main_loop)
+ : XWalkLauncher(query_running, main_loop) {
+}
+
+int XWalkLauncherTizen::Launch(const std::string& appid_or_url, bool fullscreen,
+ bool remote_debugging, int argc, char* argv[]) {
+ appid_or_url_ = appid_or_url;
+ fullscreen_ = fullscreen;
+ remote_debugging_ = remote_debugging;
+ // Query app.
+ if (query_running_) {
+ return dbus_object_manager_->IsApplicationRunning(appid_or_url_);
}
+ std::string name = "xwalk-" + appid_or_url_;
+
+ if (XwalkAppcoreInit(name, argc, argv)) {
+ LOG(ERROR) << "Failed to initialize appcore.";
+ return 1;
+ }
+ if (GURL(appid_or_url_).spec().empty()
+ && XwalkChangeCmdline(appid_or_url_, argc, argv))
+ return 1;
+ return 0;
+}
+
+bool XWalkLauncherTizen::Suspend() {
+ return dbus_object_manager_->Suspend();
+}
+
+bool XWalkLauncherTizen::Resume() {
+ return dbus_object_manager_->Resume();
+}
+
+void XWalkLauncherTizen::application_event_cb(app_event event,
+ void* data, bundle* b) {
+ XWalkLauncherTizen* xwalk_launcher = static_cast<XWalkLauncherTizen*>(data);
+ LOG(INFO) << "event '" << Event2Str(event) << "'";
switch (event) {
case AE_UNKNOWN:
case AE_CREATE:
break;
case AE_TERMINATE:
- exit(0);
+ xwalk_launcher->main_loop_->QuitNow();
break;
case AE_PAUSE:
- g_dbus_proxy_call(
- app_proxy, "Suspend", NULL,
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+ if (!xwalk_launcher->Suspend())
+ LOG(ERROR) << "Suspending application failed";
break;
case AE_RESUME:
- g_dbus_proxy_call(
- app_proxy, "Resume", NULL,
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+ if (!xwalk_launcher->Resume())
+ LOG(ERROR) << "Resuming application failed";
break;
case AE_RESET:
+ if (!xwalk_launcher->LaunchApplication())
+ xwalk_launcher->main_loop_->QuitNow();
+ break;
case AE_LOWMEM_POST:
case AE_MEM_FLUSH:
case AE_MAX:
}
}
-int xwalk_appcore_init(
- int argc, char** argv, const char* name, GDBusProxy* app_proxy) {
- appcore_ops.cb_app = application_event_cb;
- appcore_ops.data = app_proxy;
-
- return appcore_init(name, &appcore_ops, argc, argv);
+int XWalkLauncherTizen::XwalkAppcoreInit(const std::string& name,
+ int argc, char* argv[]) {
+ app_ops.cb_app = application_event_cb;
+ app_ops.data = this;
+ return appcore_init(name.c_str(), &app_ops, argc, argv);
}
-int xwalk_change_cmdline(int argc, char** argv, const char* app_id) {
+int XWalkLauncherTizen::XwalkChangeCmdline(const std::string& app_id,
+ int argc, char* argv[]) {
// Change /proc/<pid>/cmdline to app exec path. See XWALK-1722 for details.
pkgmgrinfo_appinfo_h handle;
- char* exec_path = NULL;
+ char* exec_path = nullptr;
// todo : add is_admin
- if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id,
+ if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(),
getuid(), &handle) != PMINFO_R_OK ||
pkgmgrinfo_appinfo_get_exec(handle, &exec_path) != PMINFO_R_OK ||
!exec_path) {
- if (pkgmgrinfo_appinfo_get_appinfo(app_id, &handle) != PMINFO_R_OK ||
+ if (pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle) !=
+ PMINFO_R_OK ||
pkgmgrinfo_appinfo_get_exec(handle, &exec_path) != PMINFO_R_OK ||
!exec_path) {
- fprintf(stderr, "Couldn't find exec path for application: %s\n", app_id);
+ LOG(ERROR) << "Couldn't find exec path for application: " << app_id;
return -1;
}
}
+ // zeros g_argv_
for (int i = 0; i < argc; ++i)
memset(argv[i], 0, strlen(argv[i]));
- strncpy(argv[0], exec_path, strlen(exec_path)+1);
+
+ strncpy(argv[0], exec_path, strlen(exec_path) + 1);
pkgmgrinfo_appinfo_destroy_appinfo(handle);
return 0;
}
// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_TIZEN_H_
#define XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_TIZEN_H_
-int xwalk_appcore_init(int argc, char** argv,
- const char* name, GDBusProxy* app_proxy);
+#include <appcore-common.h>
+#include <glib.h>
-int xwalk_change_cmdline(int argc, char** argv, const char* app_id);
+#include <memory>
+#include <string>
+
+#include "base/message_loop/message_loop.h"
+
+#include "xwalk/application/common/id_util.h"
+#include "xwalk/application/tools/linux/xwalk_launcher.h"
+#include "xwalk/application/tools/tizen/xwalk_tizen_user.h"
+
+// Private enum from appcore-internal
+extern "C" enum app_event {
+ AE_UNKNOWN,
+ AE_CREATE,
+ AE_TERMINATE,
+ AE_PAUSE,
+ AE_RESUME,
+ AE_RESET,
+ AE_LOWMEM_POST,
+ AE_MEM_FLUSH,
+ AE_MAX
+};
+
+class XWalkLauncherTizen : public XWalkLauncher {
+ public:
+ XWalkLauncherTizen(bool query_running, base::MessageLoop* main_loop);
+ int Launch(const std::string& appid_or_url, bool fullscreen,
+ bool remote_debugging, int argc, char* argv[]);
+ bool Suspend();
+ bool Resume();
+
+ private:
+ static void application_event_cb(app_event event, void* data, bundle* b);
+ int XwalkAppcoreInit(const std::string& name, int argc, char* argv[]);
+ int XwalkChangeCmdline(const std::string& app_id, int argc, char* argv[]);
+
+ base::MessageLoop* main_loop_;
+};
#endif // XWALK_APPLICATION_TOOLS_LINUX_XWALK_LAUNCHER_TIZEN_H_
#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"
# 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',
],
# 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',
],
'variables': {
'tizen%': 0,
'tizen_mobile%': 0,
- 'shared_process_mode%': 0,
'enable_murphy%': 0,
},
'target_defaults': {
['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'],
}],
ObjectPath ManagedObject::path() const {
return path_;
-};
+}
void ManagedObject::AppendAllPropertiesToWriter(MessageWriter* writer) const {
MessageWriter interfaces_writer(NULL);
// be called from any thread.
void PostResult(scoped_ptr<base::ListValue> result) const {
post_result_cb_.Run(result.Pass());
- };
+ }
std::string name() const {
return name_;
#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;
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());
#else
NOTIMPLEMENTED();
#endif // #if defined(OS_LINUX)
-#else
+ } else {
process_.reset(content::BrowserChildProcessHost::Create(
content::PROCESS_TYPE_CONTENT_END, this));
process_->Launch(
new ExtensionSandboxedProcessLauncherDelegate(process_->GetHost()),
cmd_line.release());
-#endif // #if defined(SHARED_PROCESS_MODE)
+ }
base::ListValue runtime_variables_lv;
ToListValue(&const_cast<base::ValueMap&>(*runtime_variables_),
}
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());
}
}
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());
}
%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+)
-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
// 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;";
private:
friend class base::RefCountedThreadSafe<RuntimeFileSelectHelper>;
FRIEND_TEST_ALL_PREFIXES(RuntimeFileSelectHelperTest, IsAcceptTypeValid);
- explicit RuntimeFileSelectHelper();
+ RuntimeFileSelectHelper();
virtual ~RuntimeFileSelectHelper();
// Utility class which can listen for directory lister events and relay
class RuntimeJavaScriptDialogManager : public content::JavaScriptDialogManager {
public:
- explicit RuntimeJavaScriptDialogManager();
+ RuntimeJavaScriptDialogManager();
virtual ~RuntimeJavaScriptDialogManager();
virtual void RunJavaScriptDialog(
#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"
storage_->set_channel_id_service(new net::ChannelIDService(
new net::DefaultChannelIDStore(NULL),
base::WorkerPool::GetTaskRunner(true)));
- storage_->set_http_user_agent_settings(
- new net::StaticHttpUserAgentSettings("en-us,en", base::EmptyString()));
+ storage_->set_http_user_agent_settings(new net::StaticHttpUserAgentSettings(
+ "en-us,en", xwalk::GetUserAgent()));
scoped_ptr<net::HostResolver> host_resolver(
net::HostResolver::CreateDefaultResolver(NULL));
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) {
} // namespace
-XWalkRunner::XWalkRunner() {
+XWalkRunner::XWalkRunner()
+ : shared_process_mode_enabled_(false) {
VLOG(1) << "Creating XWalkRunner object.";
DCHECK(!g_xwalk_runner);
g_xwalk_runner = this;
void EnableRemoteDebugging(int port);
void DisableRemoteDebugging();
+ bool shared_process_mode_enabled() const
+ { return shared_process_mode_enabled_; }
+
protected:
XWalkRunner();
virtual scoped_ptr<SysAppsComponent> CreateSysAppsComponent();
virtual scoped_ptr<StorageComponent> CreateStorageComponent();
+ bool shared_process_mode_enabled_;
+
private:
friend class XWalkMainDelegate;
friend class ::XWalkTestSuiteInitializer;
#include "xwalk/runtime/browser/xwalk_runner_tizen.h"
+#include "base/command_line.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/nss_util.h"
#include "xwalk/application/browser/application_service.h"
#include "xwalk/runtime/browser/sysapps_component.h"
#include "xwalk/runtime/browser/xwalk_component.h"
#include "xwalk/runtime/common/xwalk_runtime_features.h"
+#include "xwalk/runtime/common/xwalk_switches.h"
namespace xwalk {
-XWalkRunnerTizen::XWalkRunnerTizen() {}
+XWalkRunnerTizen::XWalkRunnerTizen() {
+ CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ shared_process_mode_enabled_ =
+ !(cmd_line->HasSwitch(switches::kXWalkDisableSharedProcessMode));
+}
XWalkRunnerTizen::~XWalkRunnerTizen() {}
// 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
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");
// 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";
extern const char kListFeaturesFlags[];
extern const char kXWalkAllowExternalExtensionsForRemoteSources[];
extern const char kXWalkDataPath[];
+extern const char kXWalkDisableSharedProcessMode[];
#if defined(OS_ANDROID)
extern const char kXWalkProfileName[];
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) {
#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 {
// RenderView::Observer:
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) OVERRIDE;
void OnHWKeyPressed(int keycode);
class DeviceCapabilitiesExtension : public XWalkExtension {
public:
- explicit DeviceCapabilitiesExtension();
+ DeviceCapabilitiesExtension();
virtual ~DeviceCapabilitiesExtension();
// XWalkExtension implementation.
class RawSocketExtension : public XWalkExtension {
public:
- explicit RawSocketExtension();
+ RawSocketExtension();
virtual ~RawSocketExtension();
// XWalkExtension implementation.
}],
['tizen==1', {
'sources': [
+ 'application/common/manifest_handlers/tizen_appwidget_handler_unittest.cc',
'application/common/manifest_handlers/tizen_navigation_handler_unittest.cc',
],
}],